0

我有一个 Jetty 6.1.9 环境,我试图引导一个“爆炸”的 WAR 样式上下文,但是,我收到了 NoClassDefFoundError 错误。

Jetty env 是这样引导的:

public class MyServer {

  public static void main(String[] argv) {

         jetty_default = jetty_default + "/web-content/jetty-6.1.9";
         String jetty_home = System.getProperty("jetty.home", jetty_default);

         Server server = new Server();
         Connector connector = new SelectChannelConnector();
         connector.setPort(7895);

         server.setConnectors(new Connector[]{connector});

         WebAppContext myAppCxt= new WebAppContext();
         myAppCxt.setContextPath("/foo");
         myAppCxt.setWar(jetty_home + "/wardirs/myApp");

         myAppCxt.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml");

         myAppCxt.setInitParams(initParamsMaps);
         myAppCxt.setTempDirectory(aTmpDir);

         server.setHandler(processingNodeAppCxt);
         server.start();

  }

wardirs/myApp 的布局是这样的

  • 看守
    • 我的应用程序
      • 网络信息
        • 库\ jdom.jar
        • web.xml

我得到错误的类在 foo.jar 中。

感觉就像 Jetty 在 WEB-INF/lib 目录中找到了 JAR,因为在启动服务器后 foo.jar 被锁定(我尝试删除它)并且当我杀死服务器时它被解锁。

如果我手动将 JAR 放在运行 MyServer 的 main 方法的 java cmd 行的类路径上,那么一切正常,但是,我希望这些 JAR 存在于 WEB-INF\lib 目录中并按应有的方式自动拾取。

实际的例外是:

Mar 06, 2013 9:07:25 PM sun.reflect.NativeMethodAccessorImpl invoke0
SEVERE: /foo/api/process
java.lang.NoClassDefFoundError: org/jdom/Content
    at com.foo.MyManager$Status.createICProcessor(MyManager.java:231)
    at com.foo.myApp.Api.process(API.java:xxx)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:149)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:67)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:259)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:133)
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:133)
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:71)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:990)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:941)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:932)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:384)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:451)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:632)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:324)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:842)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:648)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
    at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:450)
Caused by: java.lang.ClassNotFoundException: org.jdom.Content
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    ... 35 more

由于这感觉像是一个类加载器上下文问题,我唯一能想到的另一件事是堆栈跟踪顶行中引用的 MyManager 正在其自己的线程中运行,该线程由 webapp 的 ServletContextListener 启动,如下所示:

        myMgrThread = new Thread(myManager);
        long myMgrThreadId = myMgrThread.getId();
        myMgrThread .setName("MyApp_MyMgr-" + myMgrThreadId);
        myMgrThread .setPriority(Thread.NORM_PRIORITY);
        myMgrThread .setDaemon(true);
        myMgrThread .start();
4

2 回答 2

0

根据您的项目布局,以及那个stacktrace,它找到com.foo.myApp.Api并且com.foo.MyManager在您的WEB-INF/lib/foo.jar就好了,但是它没有找到org.jdom.Content

org.jdom.Content存在于您wEB-INF/lib/foo.jar的? 或者在你没有提到的类似文件中WEB-INF/lib/jdom.jar?或者您是否希望org.jdom.Content从父类加载器中找到(换句话说,无论MyServer类是从哪个类加载器开始的)?

于 2013-03-07T14:17:49.380 回答
0

我想我回答了我自己的问题。正在其中运行的 IDE 项目不会将 'webapp' .class 文件移动到“$jetty_home/wardirs/myApp/WEB-INF/classes”中,正如 servlet 规范所期望的那样。相反,它将它们包含在调用 MyServer.main 的类路径中。

当我将应用程序类复制到“$jetty_home/wardirs/myApp/WEB-INF/classes”时,NOCLASSDEFERRORs 消失了。所以现在这些类是 WEB-INF/classes 并且在类路径上调用 main。

正如您可能在这里所说的那样,这个项目在 webapp 和容器之间没有分离关注点。应用程序和码头的所有类和 JARS 都被一起转储了,它“工作”。我一直在尝试将事情分开,以便 webapp 类和依赖的 JAR 被清楚地分开,例如。引入 ServletContextListener 以将之前从“main”引导的 webapp 代码移动到其中,将 JAR 移动到 WEB-INF/lib 等。这就像试图从头发上取下口香糖一样。

于 2013-03-07T21:40:13.320 回答