「展開された」WAR スタイルのコンテキストをブートストラップしようとしている Jetty 6.1.9 環境がありますが、NoClassDefFoundError エラーが発生します。
Jetty 環境は次のようにブートストラップされます。
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 のレイアウトは次のようになります
- 病棟
- マイアプリ
- WEB-INF
- lib\jdom.jar
- web.xml
- WEB-INF
- マイアプリ
エラーが発生しているクラスは foo.jar にあります。
また、Jetty が WEB-INF/lib ディレクトリで JAR を見つけているように感じます。これは、サーバーの起動後に foo.jar がロックされ (削除しようとしました)、サーバーを強制終了するとロックが解除されるためです。
MyServer のメイン メソッドを実行する Java コマンド ラインのクラスパスに JAR を手動で配置すると、すべて正常に動作しますが、これらの 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();