간단한 웹 서비스를 작성하기 위해 Jersey 라이브러리와 구글 앱엔진을 사용하곤 하는데요,
구글 앱엔진 SDK가 업데이트되면서 Jersey라이브러리와 충돌을 일으켜 다음과 같은 오류메시지가 표시됩니다.
Uncaught exception from servlet java.lang.IncompatibleClassChangeError: Implementing class at com.google.appengine.runtime.Request.process-228b7cd57b1558f8(Request.java) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:794) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at java.lang.ClassLoader.loadClass(ClassLoader.java:359) at com.sun.jersey.api.core.ScanningResourceConfig.init(ScanningResourceConfig.java:79) at com.sun.jersey.api.core.PackagesResourceConfig.init(PackagesResourceConfig.java:104) at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:78) at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:89) at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:696) at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:674) at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:203) at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:374) at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:557) at javax.servlet.GenericServlet.init(GenericServlet.java:212) at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:440) at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:263) 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:480) at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:487) at com.google.tracing.TraceContext.runInContext(TraceContext.java:774) at com.google.tracing.TraceContext$DoInTraceContext.runInContext(TraceContext.java:751) at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:342) at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:334) at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:484)
at java.lang.Thread.run(Thread.java:722)
무엇이 문제를 일으키는 걸까?
Jersey와 앱엔진 모두 asm 라이브러리를 사용하고 있는데, 앱엔진 SDK가 업데이트되면서 asm 4.0(asm-4.0.jar) 버전을 사용하게 되었습니다. 반면 Jersey는 3.0 버전(asm-3.0.jar)을 사용하기에 충돌이 발생하여 이 문제가 발생하게 됩니다.
해결 방법
이 해결 방법은 2012/08/13 - Google App Engine + Jersey를 사용하여 REST 서비스 구축하기 포스트의 방법대로 개발환경이 구축되어 있는 것을 전제로 합니다.
1. [프로젝트 경로]/war/WEB-INF/lib 내에 asm-3.0.jar 파일과 asm-4.0.jar 파일이 보일 것입니다. 이 중 asm-4.0.jar 파일을 삭제합니다.
2. 프로젝트 속성 > Google > App Engine > Datastore > Datanucleus JDO/JPA version에서 v2를 v1으로 바꿔줍니다.
위 과정을 수행한 후, 앱엔진에 Deploy해서 테스트하면 문제없이 잘 수행되는 것을 확인할 수 있습니다.
(Datanucleus enhancement는 Encountered a problem: Unexpected exception이라는 메시지가 나오기는 하는데, 실행시 별 문제는 없더군요)
'프로그래밍 이야기' 카테고리의 다른 글
이클립스에서 기본 문자열 인코딩 설정하기(eclipse.ini) (0) | 2012.09.07 |
---|---|
Jersey에서 원소가 한개인 JSONArray를 반환할 때 Array로 반환되지 않는 문제 해결 (0) | 2012.09.04 |
Google App Engine + Jersey를 사용하여 REST 서비스 구축하기 (3) | 2012.08.13 |
소켓 통신에서 InputStream / OutputStream을 열 때 무한대기(멈추는 현상)은 왜 일어날까요? (0) | 2012.07.21 |
이클립스 CDT로 편리하게 GeekOS 프로젝트 진행하기 (0) | 2012.03.20 |