한참을 삽질했습니다. 구글링을 해보니 mac의 jdk와 호환이 되지 않아서 발생하는 문제라고 합니다.

http://stackoverflow.com/questions/17822795/google-app-engine-javax-servlet-unavailableexception-initialization-failed#comment27168122_17822795


역시나 윈도우 가상머신에 GAE 개발환경 갖추고 실행하니 같은 소스가 잘 동작합니다.



다음은 앱엔진 로그에 나타나는 메시지입니다.

  1. 2013-10-15 16:22:29.386 / 500 5066ms 0kb Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1
    210.98.50.4 - - [15/Oct/2013:16:22:29 -0700] "GET / HTTP/1.1" 500 0 - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1" "1.okgawi.appspot.com" ms=5067 cpu_ms=2567 loading_request=1 app_engine_release=1.8.6 instance=00c61b117cc605edbcad33f6d430edbd601896
  2. W2013-10-15 16:22:29.299
    EXCEPTION 
    java.lang.IllegalArgumentException
    	at com.google.appengine.runtime.Request.process-3c18ce8f0ef50d07(Request.java)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:360)
    	at org.mortbay.util.Loader.loadClass(Loader.java:91)
    	at org.mortbay.util.Loader.loadClass(Loader.java:71)
    	at org.mortbay.jetty.servlet.Holder.doStart(Holder.java:73)
    	at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:242)
    	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    	at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
    	at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
    	at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
    	at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    	at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
    	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    	at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:435)
    	at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:442)
    	at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:186)
    	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:306)
    	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:298)
    	at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:439)
    	at java.lang.Thread.run(Thread.java:724)
    
  3. E2013-10-15 16:22:29.376
    javax.servlet.ServletContext log: unavailable
    javax.servlet.UnavailableException
    	at org.mortbay.jetty.servlet.Holder.doStart(Holder.java:79)
    	at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:242)
    	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    	at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
    	at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
    	at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
    	at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    	at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
    	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:219)
    	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:194)
    	at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:134)
    	at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446)
    	at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:435)
    	at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:442)
    	at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:186)
    	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:306)
    	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:298)
    	at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:439)
    	at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
    	at java.lang.Thread.run(Thread.java:724)
    
  4. W2013-10-15 16:22:29.380
    Failed startup of context com.google.apphosting.utils.jetty.RuntimeAppEngineWebAppContext@1d9525e{/,/base/data/home/apps/s~okgawi/1.370945407503011368}
    java.lang.NullPointerException
    	at java.lang.Class.isAssignableFrom(Native Method)
    	at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:256)
    	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    	at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
    	at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
    	at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
    	at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    	at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
    	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:219)
    	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:194)
    	at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:134)
    	at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446)
    	at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:435)
    	at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:442)
    	at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:186)
    	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:306)
    	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:298)
    	at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:439)
    	at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
    	at java.lang.Thread.run(Thread.java:724)



쉬운 게 없군요.


Ceylon (http://ceylon-lang.org) 언어는 Java와 JavaScript 두 가지 플랫폼을 지원합니다. JVM 또는 node.js 플랫폼에서 동작하는 진정한 일타쌍피 언어이죠.

이 실험적인 언어의 기능(Feature)이 정해졌다고 합니다.

http://www.theserverside.com/news/thread.tss?thread_id=77418 (Gavin King이 직접 쓴 뉴스)

http://www.infoq.com/news/2013/09/ceylon-beta


Ceylon은 C, Java언어를 아시는 분들은 아주 잘 읽힙니다. html도 구조대로 프로그래밍을 하고 동적으로 생성해줍니다.

Table table = Table {

    title = "Squares";

    rows = 5;

    Border {

        padding = 2;

        weight = 1;

    };

    Column {

        heading = "x";

        width = 10;

        String content(Integer row) {

            return row.string;

        }

    },

    Column {

        heading = "x^2";

        width=10;

        String content(Integer row) {

            return (row^2).string;

        }

    }

};


하이버네이트로 자바 표준인 JPA도 이끌어낸 Gavin이라 이 분이 만든 Ceylon이 어떤 반향을 일으킬 것 같습니다. 특히나 메이저 언어가 된 자바스크립트와 전혀 다른 언어 자바를 통합시켰으니까요.


15분이면 Ceylon 언어를 탐험하실 수 있습니다. 

http://ceylon-lang.org/documentation/current/introduction/

영어가 안되서 당황하시면 안 됩니다. ^^;

맥에 jdk를 설치하면, jdk7부터는 /Library/Java/JavaVirtualMachines/ 아래 설치됩니다. 시스템 환경변수에서 중요한 것이 JAVA_HOME인데, 이 경로를 참고해서 설정을 해야할 것입니다.


이를 편하게 변경하는 기능을 만든 것이 있습니다.

http://www.guigarage.com/downloads/jvc.jar

다운로드를 받으면 적당한 위치로 옮기고, 터미널에서 다음과 같이 명령을 내리면 됩니다.

java -jar jvc.jar



원하는 버전을 선택하고 아래 set Version 버튼을 클릭하면 됩니다. 시스템 비번을 입력하면 설정이 완료됩니다.

터미널을 새로 띄우고, 아래 명령으로 확인합니다.


java -version


참고: http://www.guigarage.com/2013/02/change-java-version-on-mac-os



JAVA_HOME 환경변수는 자바 개발의 시작입니다. 윈도우7에서 환경변수를 설정하는 방법을 알아봅니다.


탐색기에서 컴퓨터를 선택하고 컨텍스트 메뉴의 속성을 엽니다. 좌측에서 고급 시스템 설정을 클릭합니다.



고급 탭에서 하단의 환경 변수(N)... 버튼을 클릭합니다.



하단의 시스템 변수(S) 항목에서 JAVA_HOME을 선택하고 편집 버튼을 클릭합니다. 만약 처음이라면 새로 만들기(W)... 버튼을 클릭합니다.


변수 이름에 JAVA_HOME 을 입력하고, 변수 값에 설치된 경로를 붙여넣습니다. 

그리고 확인 버튼으로 열린 창들을 닫습니다.


cmd 창을 닫았다가 다시 엽니다. echo %JAVA_HOME% 라고 입력하면 설정된 환경변수 값을 확인할 수 있습니다.


한 가지 환경변수가 더 설정이 되어야 합니다. 바로 %Path% 입니다.

%JAVA_HOME%\bin; 

위 경로를 시스템 환경 변수 Path에 추가합니다. 

참고: http://okjsp.tistory.com/1165643255


jdk1.7이 현재 배포되는 버전입니다. 이전 버전인 jdk1.6을 다운로드 받으려면 http://java.sun.com 에서 Java SE로 이동합니다. 


Previous Releases 를 선택합니다.



Java SE 6를 선택합니다. 이전의 자바도 다운로드 받을 수 있게 링크가 제공됩니다. 하지만, 오라클의 정책에 따라서 이전 버전들은 로그인 해야 다운로드 받을 수 있습니다.




Java SE Development Kit 6u45 링크를 선택합니다. 1.6의 45번째 업데이트 버전입니다.



동의 항목을 체크하고 하단에서 OS에 맞는 jdk를 다운로드 하면 됩니다.



로그인을 해야 다운로드 받을 수 있습니다.



다운로드를 다 받으면 폴더를 열어서 파일을 실행합니다.



설치를 마치면 C:\Program Files\Java\jdk1.6.0_45 폴더에 설치됩니다. 이 경로는 JAVA_HOME 환경변수 값이 됩니다.



환경변수 JAVA_HOME을 아래 링크를 참고해서 적용하세요.

http://okjsp.tistory.com/tag/java_home


메이븐, 빌드 도구

허광남 kenu.heo@gmail.com

메이븐은 아파치의 오픈 소스 빌드 도구입니다. http://maven.apache.org 사이트에서 정보를 구할 수 있습니다. 빌드란 프로그램 소스의 컴파일을 포함해서 애플리케이션을 사용할 수 있도록 패키징까지 해주는 과정입니다. 개발환경 도구에는 메이븐의 이클립스 플러그인이 함께 설치되어 있습니다. m2eclipse라는 플러그인이며, 이클립스에서 메이븐을 쉽게 사용하도록 도와주는 기능을 제공합니다.

메이븐 프로젝트 소스 구조

메이븐은 설정보다 관례(CoC;Convention over Configuration)라는 컨셉으로, 먼저 나왔던 ANT(http://ant.apache.org) 빌드 도구와 달리 빌드의 설정을 자유롭게 하는 대신 지정된 규칙에 따라 코드를 위치시키면 컴파일, 패키징, 문서화 등의 나머지 작업들을 자동으로 수행해 줍니다.

자바 라이브러리 일괄 관리

메이븐은 여러 프로젝트에 중복 산재해 있는 자바 라이브러리(JAR)를 한 곳에서 관리합니다. 일반적으로 프로젝트에서 소스코드가 차지하는 용량이 3~5메가라고 하면 jar파일의 크기는 30~50메가가 넘는 경우가 많습니다. 이런 경우 버전관리 시스템에서 제외시켜서 관리할 수 있다면 매우 가볍게 작업이 가능합니다.
메이븐은 사용자 홈 디렉토리를 기준으로 .m2 라는 폴더를 만들어서 repository 폴더 하위에 인터넷에서 다운로드 받은 jar 파일을 관리합니다. pom.xml 에서 지정된 라이브러리들을 필요에 따라 복사하거나 참조해서 사용합니다.

메이븐 설치

전자정부 표준프레임워크의 개발환경 서버를 설치하면 메이븐이 함게 설치됩니다. JAVA_HOME 환경변수 같이 MAVEN_HOME을 지정하고, PATH에 추가해도 되지만 메이븐/bin, 폴더만 PATH 환경변수에 추가하겠습니다. 컴퓨터 아이콘을 클릭하고, 컨텍스트 메뉴에서 속성을 선택합니다.
<그림> 환경변수 설정 시작



제어판의 좌측에서 고급 시스템 설정을 클릭합니다.
<그림> 고급 시스템 설정



하단의 시스템 변수에서 Path 항목을 선택합니다. 여기에 들어갈 값은 빌게이츠 친구 탐색기에서 복사할 수 있습니다.
<그림> 시스템 변수 Path



탐색기를 열어서 C:폴더에 들어갑니다. 주소줄을 클릭해서 복사합니다.
<그림> 메이븐 경로 복사



시스템 환경 변수 Path의 제일 앞에 복사한 C:경로를 추가하고 ;을 붙여서 구분해 줍니다.
<그림> 메이븐 경로 Path에 추가



cmd 창을 띄워서 mvn --version 을 입력합니다. 버전이 표시되면 정상적으로 설치가 된 것입니다.
<그림> 메이븐 버전 확인


메이븐 간단 테스트

간단히 템플릿 코드를 생성해 보겠습니다. 다음의 코드를 cmd창에 입력합니다.
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

필요한 jar파일을 알아서 다운로드합니다. 그 파일들을 이용해서 archetype 플러그인의 generate 골을 실행합니다.
<그림> 메이븐 아키타입 실행



tree /f 도스 명령어를 이용해서 생성된 파일들과 폴더를 보면 다음과 같습니다. src/main, src/test 폴더에 각각 지정한 groupId 패키지에 따른 하위 폴더와 각각의 java 샘플이 있고, 가장 상위에는 pom.xml 파일이 있습니다.
<그림> 메이븐 아키타입 퀵스타트 구조



빌드는 mvn package 페이즈(phase)를 통해서 할 수 있습니다.
<그림> 메이븐 pacakge 페이즈 실행



결과는 target 폴더가 만들어지면서 담기게 됩니다. quickstart 샘플의 경우 jar파일이 만들어 집니다.
<그림> 메이븐 산출물 target



target 폴더로 이동해서 java -cp my-app-1.0.SNAPSHOT.jar com.mycompany.app.App 명령을 입력하면 실행할 수 있습니다.
<그림> 메이븐 결과 실행



간단히 메이븐을 설치하고 이용하는 방법을 알아보았습니다.


http://okjsp.tistory.com
http://okjsp.net
http://github.com/kenu
























http://java.sun.com/ 에서 jdk7을 http://netbeans.org/ 에서 netbeans7을 구할 수 있습니다.


JDK 경로는 Program Files 에서 java로 변경합니다. 폴더명에 공백이 들어가지 않게 하기 위해서입니다.  


JRE는 그냥 기본 위치에 설치합니다.


이제 NetBeans를 설치합니다. http://netbeans.org/ 로 접속하면 됩니다.


NetBeans도 java 디렉토리로 설치합니다.


제임스 고슬링 아저씨도 놀란 뉴스입니다. 애플이 OSX의 JDK를 위해서 OpenJDK for Mac OS X 를 시작한다고 합니다. 
http://openjdk.java.net 의 블로그 섹션에 보면 오라클에 인수된 썬을 떠난 제임스 고슬링 아저씨의 글도 볼 수 있습니다. 


Java 7을 위한 노력은 계속 될 것이라는 메시지가 담겨있는 뉴스인데, 예전 애플의 Java 왕따 소식에 비해서 상당히 좋은 뉴스가 아닌가 생각됩니다. 

http://openjdk.java.net/ 사이트는 오픈소스 자바가 만들어 지는 곳입니다. 여기에 애플이 가세했다는 것은 맥 사용자로 굉장히 환영하는 바입니다.

좋은 애플리케이션 개발하는데 영양가 있는 계속 좋은 소식이 들려오길 기대합니다.



http://www.oracle.com/java 접속
http://java.sun.com/ 접속해도 됩니다만 격세지감만 느껴집니다. 세상 참 빠르게 변합니다.



Java 성능 모니터링에 대해 모르고 있던 5가지 사항, Part 2
JDK의 내장 프로파일러를 이용한 Java 프로세스 모니터링
http://www.ibm.com/developerworks/kr/library/j-5things8.html 
위 developerWorks 기사에 있는 내용을 조금 따라해봤습니다. jdk에 있는 샘플을 이용해서 $JAVA_HOME/bin에 있는 다섯 가지 커맨드를 소개하고 있습니다.
$JAVA_HOME/demo/jfc/SwingSet2 폴더에 있는 SwingSet2.jar를 실행합니다.

java -jar SwingSet2.jar 라고 입력하면 실행됩니다.

자바 스윙으로 만들어진 창이 뜨게 됩니다.

고유한 프로세스를 jps 명령으로 확인할 수 있습니다.

이 외에도 jstat 명령과 jmap, jhat 등의 자바 성능관련 정보를 확인할 수 있는 명령들이 소개됩니다.

+ Recent posts