我在我的应用程序中看到了在独立码头上运行的奇怪行为。
启动应用程序会抛出错误:
2011-12-14 16:46:20.634:WARN ::启动处理程序时出错 java.lang.IllegalAccessError:class sun.reflect.GeneratedConstructorAccessor2无法访问其超类 sun.reflect.ConstructorAccessorImpl at sun.misc.Unsafe.defineClass(原生方法)
由行
触发if(f.getAnnotation(Persist.class)!= null)// f是一个Field实例(一个公共实例,不能少), Persist是一个注释
关于这个的一些有趣的事实
代码在tomcat中正常运行
代码在蚂蚁码头任务中运行良好
代码在独立码头上抛出此错误(尝试过v6& v8),即使我使用运行jetty ant任务的相同jetty jar运行它。
使用最小的jetty.xml运行(基本上只是指向一个目录)。
答案 0 :(得分:6)
因为我刚刚遇到过这个问题,并且因为它看起来有点......模糊不清,所以认为值得发布,因为其他任何一个可怜的灵魂都会遇到这个看似随意的行为。
遇到消息here,其相关引用是
问题是AOP代理类是在单独生成的 classloader,这是可见性问题的原因,因为包私有类型是 从其他类加载器中看不到。 Guice试图检测到这一点以避免引入 单独的类加载器,但这似乎不会在你的例子中发生。
因此,如果我将所有app jars直接转储到JETTY_HOME / lib中,我的应用程序将会起作用,这显然会导致aop以guice批准的方式生成类。
更正 - 事实证明,这与guice没有任何关系,但Jetty加载类的方式。对此的实际修复是改变jetty加载类的方式,将其添加到jetty.xml webappcontext定义中:
<Set name="handler">
<New class="org.mortbay.jetty.webapp.WebAppContext">
<Set name="parentLoaderPriority">true</Set>
答案 1 :(得分:2)
我在嵌入式Jetty和@Async注释方面遇到了类似的问题。我通过强制Jetty的classLoader与我的应用程序的类加载器相同来解决它:
context.setClassLoader(Thread.currentThread().getContextClassLoader());
以下是完整代码:
public class Jetty {
public static Server createServer(int port) {
Server server = new Server(port);
WebAppContext context = new WebAppContext();
context.setResourceBase("src/main/webapp");
context.setClassLoader(Thread.currentThread().getContextClassLoader());
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{context});
server.setHandler(handlers);
return server;
}
}