在Android上使用Jetty上的Jersey出现ContainerException异常:“没有WebApplication提供程序”。

4

我正在尝试在Android上运行Jetty上的Jersey。

我创建了一个Android,实例化了一个带有Jersey Servlet的Jetty Server。但是当我启动Jetty并访问REST资源(在我的情况下:http://192.168.1.12:8080/api/hello)时,我会收到一个ContainerException错误消息:未提供WebApplication提供程序(请参见下面的异常堆栈跟踪)。

有任何想法吗?

由于Jetty或Jersey要求,我已将javax包JNDI添加到项目中。Android不喜欢导入javax库,因此我暂时使用--core-library命令行参数来编译dex文件。

异常跟踪:

com.sun.jersey.api.container.ContainerException: No WebApplication provider is present
at com.sun.jersey.spi.container.WebApplicationFactory.createWebApplication(WebApplicationFactory.java:69)
at com.sun.jersey.spi.container.servlet.ServletContainer.create(ServletContainer.java:391)
at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.create(ServletContainer.java:306)
at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:605)
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:208)
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:241)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:444)
at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:335)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:523)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:479)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:483)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:227)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1031)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:965)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)
at org.eclipse.jetty.server.Server.handle(Server.java:349)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:449)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:910)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:647)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:233)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:76)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:615)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:45)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534)
at java.lang.Thread.run(Thread.java:1019)

活动代码:

public class StartServerActivity extends Activity {

private Server webServer;
private final static String LOG_TAG = "Jetty";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    System.setProperty("java.net.preferIPv4Stack", "true");
    System.setProperty("java.net.preferIPv6Addresses", "false");

    webServer = new Server(8080);

    ServletHolder servletHolder = new ServletHolder(ServletContainer.class);
    servletHolder.setInitParameter("com.sun.jersey.config.property.packages", "com.famenu.server.resources");
    servletHolder.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");
    ServletContextHandler servletContextHandler = new ServletContextHandler(webServer, "/api");
    servletContextHandler.addServlet(servletHolder, "/");


    webServer.setHandler(servletContextHandler);

    try {
        webServer.start();
        webServer.join();
        Log.d(LOG_TAG, "started Web server");

    }
    catch (Exception e) {
        Log.d(LOG_TAG, "unexpected exception starting Web server: " + e);
    }
}

我正在使用Jetty 7.3.0.v20110203、Jersey 1.12和Android 1.6。


深入研究com.sun.jersey.spi.container.WebApplicationFactory的源代码,我发现异常是由ServiceFinder.find(WebApplicationProvider.class)抛出的,它无法找到任何WebApplicationProvider类... 但是谁应该实例化这个WebApplicationProviderImpl呢?:( - Giorgio
2个回答

5

我曾经遇到过Jetty 8和Jersey 1.13的相同问题。为了解决这个问题,我添加了以下依赖项。

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-servlet</artifactId>
    <version>1.13</version>
</dependency>

1
跟进:我遇到了同样的问题,解决方案并不是缺少这个依赖项,而是我使用了一个不兼容的版本。(在我的情况下是1.17.1,而另一个依赖项需要1.18.1。)感谢您指出正确的方向! - jwismar
@jwismar 感谢您的回复。您的解决方案对我来说可用于使用1.18.1版jersey客户端。 - Rakesh Gourineni

2

WebApplicationProviderImpl是通过jersey-server.jar中的META-INF/services条目进行注册的。您是否将Jersey重新打包到自己的jar中,却忘记了META-INF/services条目?

因此,要解决此异常,需要将jersey-core、jersey-server和jersey-servlet中的META-INF/services文件夹添加到apk的META-INF文件夹中。

然后,您将无法使用Eclipse进行部署,但以下命令行将起作用:

cd 项目目录

ant debug

adb install -r "bin/您的项目-debug.apk"


1
我已经成功在Android上运行了Jersey!你可以在这里找到我所做的工作:https://github.com/giorgio-zamparelli/jersey-android - Giorgio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接