Google app engine 失败的REST服务:java.lang.CompatibleClassChangeError:实现类

Google app engine 失败的REST服务:java.lang.CompatibleClassChangeError:实现类,google-app-engine,jersey,Google App Engine,Jersey,我希望Jersey能够很容易地部署到Google App Engine,因为它被认为是受支持的(),有几个人提到他们让它工作了() 但它不起作用 我使用用于eclipse的gae插件创建了一个新项目(使用gae sdk 1.7.3) 我在我的web.xml中添加了: <servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>com.sun.jersey.sp

我希望Jersey能够很容易地部署到Google App Engine,因为它被认为是受支持的(),有几个人提到他们让它工作了() 但它不起作用

  • 我使用用于eclipse的gae插件创建了一个新项目(使用gae sdk 1.7.3)
  • 我在我的web.xml中添加了:

    <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>sample.hello.resources</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    <servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer
    </servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>sample.hello.bean.MyApplication</param-value>
    </init-param>
    </servlet>
    
    
    泽西岛休息服务
    com.sun.jersey.spi.container.servlet.ServletContainer
    com.sun.jersey.config.property.packages
    sample.hello.resources
    com.sun.jersey.config.feature.DisableWADL
    真的
    1.
    
  • 我在类路径中添加了:jersey-bundle-1.14.jar(我甚至只尝试了核心、servlet和服务器,甚至只尝试了1.5)

但我还是被这件事缠住了:

      WARNING: failed Jersey REST Service: java.lang.IncompatibleClassChangeError: Implementing class
  Oct 27, 2012 6:17:06 PM com.google.apphosting.utils.jetty.JettyLogger warn
  WARNING: failed com.google.appengine.tools.development.DevAppEngineWebAppContext@68c12474{/,/Users/anthony/workspaces/gae/restfulapp/war}: java.lang.IncompatibleClassChangeError: Implementing class
  Oct 27, 2012 6:17:06 PM com.google.apphosting.utils.jetty.JettyLogger warn
  WARNING: failed JettyContainerService$ApiProxyHandler@365878d2: java.lang.IncompatibleClassChangeError: Implementing class
  Oct 27, 2012 6:17:06 PM com.google.apphosting.utils.jetty.JettyLogger warn
  WARNING: Error starting handlers
  java.lang.IncompatibleClassChangeError: Implementing class
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:207)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    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:206)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556)
    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 org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:224)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:205)
    at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:249)
    at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:157)
    at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:333)
    at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
    at com.google.appengine.tools.development.DevAppServerMain.<init>(DevAppServerMain.java:269)
    at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:245)
警告:REST服务失败:java.lang.CompatibleClassChangeError:实现类
2012年10月27日下午6:17:06 com.google.apphosting.utils.jetty.JettyLogger警告
警告:com.google.appengine.tools.development失败。DevAppEngineWebAppContext@68c12474{/,/Users/anthony/workspace/gae/restfulapp/war}:java.lang.CompatibleClassChangeError:实现类
2012年10月27日下午6:17:06 com.google.apphosting.utils.jetty.JettyLogger警告
警告:JettyContainerService失败$ApiProxyHandler@365878d2:java.lang.CompatibleClassChangeError:实现类
2012年10月27日下午6:17:06 com.google.apphosting.utils.jetty.JettyLogger警告
警告:启动处理程序时出错
java.lang.CompatibleClassChangeError:实现类
位于java.lang.ClassLoader.defineClass1(本机方法)
位于java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
位于java.lang.ClassLoader.defineClass(ClassLoader.java:615)
位于java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
位于java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
在java.net.URLClassLoader.access$000(URLClassLoader.java:58)
在java.net.URLClassLoader$1.run(URLClassLoader.java:197)
位于java.security.AccessController.doPrivileged(本机方法)
位于java.net.URLClassLoader.findClass(URLClassLoader.java:190)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:306)
位于com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:207)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:247)
位于com.sun.jersey.api.core.ScanningResourceConfig.init(ScanningResourceConfig.java:79)
位于com.sun.jersey.api.core.PackagesResourceConfig.init(PackagesResourceConfig.java:104)
位于com.sun.jersey.api.core.PackagesResourceConfig.(PackagesResourceConfig.java:78)
位于com.sun.jersey.api.core.PackagesResourceConfig.(PackagesResourceConfig.java:89)
位于com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:696)
位于com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:674)
位于com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:206)
位于com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373)
位于com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556)
位于javax.servlet.GenericServlet.init(GenericServlet.java:212)
位于org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:440)
位于org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:263)
位于org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
位于org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
位于org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
位于org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
位于org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
位于org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
位于org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
位于org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
位于org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
位于org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
位于org.mortbay.jetty.Server.doStart(Server.java:224)
位于org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
位于com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:205)
位于com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:249)
位于com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:157)
在com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:333)
位于com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
在com.google.appengine.tools.development.DevAppServerMain.(DevAppServerMain.java:269)
位于com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:245)
我错过了什么?我应该为gae使用另一个jax-rs实现吗?
谢谢你的回答

好的,我发现:显然(查看我在问题中发布的堆栈跟踪),GAE不允许Jersey使用其类加载器扫描可用的rest资源。 因此,我详细阅读了Jersey文档,发现可以手动将Rest资源指定给Jersey

以下是web.xml文件:

<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
  <param-name>com.sun.jersey.config.property.packages</param-name>
  <param-value>sample.hello.resources</param-value>
</init-param>
<init-param>
  <param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
  <param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
  <param-name>javax.ws.rs.Application</param-name>
  <param-value>sample.hello.bean.MyApplication</param-value>
</init-param>
</servlet>

Jersey Web应用程序
/休息/*
Jersey Web应用程序
com.sun.jersey.spi.container.servlet.ServletContainer
javax.ws.rs.Application
sample.hello.bean.MyApplication
您可以注意到我现在有一个应用程序类:

    package sample.hello.bean;

    import java.util.HashSet;
    import java.util.Set;

    import javax.ws.rs.core.Application;

    import sample.hello.resources.HelloResource;

    public class MyApplication extends Application {
         public Set<Class<?>> getClasses() {
             Set<Class<?>> s = new HashSet<Class<?>>();
             s.add(HelloResource.class);
             return s;
         }
    }
package sample.hello.bean;
导入java.util.HashSet;
导入java.util.Set;
导入javax.ws.rs.core.Application;
导入sample.hello.resources.HelloResource;
公共类MyApplication扩展了Applic