使用Jetty的构造函数注入抛出InstantiationException

时间:2017-01-27 14:33:11

标签: java java-ee jetty cdi

我觉得我错过了一些明显的东西......

我有许多需要在运行时注入各种依赖项的JEE过滤器和Servlet。

目前,我们将依赖项声明为字段,如下所示:

import javax.inject.Inject;

public class ThingFilter implements Filter {
    @Inject
    ThingDependency thing;

    ....

}

这适用于所有情况。但是,如果我将其更改为使用构造函数注入,如下所示:

import javax.inject.Inject;

public class ThingFilter implements Filter {
    private final ThingDependency thing;

    @Inject
    public ThingFilter(ThingDependency thing) {
        this.thing = thing;
    }

    ....

}

...然后它在WebSphere Liberty下运行时工作正常,但在使用我们为集成测试启动的嵌入式Jetty服务器运行时却没有。 (理想情况下,我们当然会使用相同的东西,但这是另一个故事。)我们得到的例外是:

org.eclipse.jetty.servlet.ServletHolder$1: java.lang.InstantiationException: com.thing.ThingFilter
        at org.eclipse.jetty.servlet.ServletHolder.makeUnavailable(ServletHolder.java:593)
        at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:652)
        at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:495)
        at org.eclipse.jetty.servlet.ServletHolder.ensureInstance(ServletHolder.java:782)
        at org.eclipse.jetty.servlet.ServletHolder.prepare(ServletHolder.java:767)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:538)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1584)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1228)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1130)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
        at org.eclipse.jetty.server.Server.handle(Server.java:564)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:318)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112)
        at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
        at java.lang.Thread.run(Thread.java:745)
Caused by:
java.lang.InstantiationException: com.thing.ThingFilter
        at java.lang.Class.newInstance(Class.java:427)
        at org.eclipse.jetty.server.handler.ContextHandler$Context.createInstance(ContextHandler.java:2510)
        at org.eclipse.jetty.servlet.ServletContextHandler$Context.createServlet(ServletContextHandler.java:1326)
        at org.eclipse.jetty.servlet.ServletHolder.newInstance(ServletHolder.java:1208)
        at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:611)
        at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:495)
        at org.eclipse.jetty.servlet.ServletHolder.ensureInstance(ServletHolder.java:782)
        at org.eclipse.jetty.servlet.ServletHolder.prepare(ServletHolder.java:767)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:538)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1584)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1228)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1130)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
        at org.eclipse.jetty.server.Server.handle(Server.java:564)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:318)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112)
        at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
        at java.lang.Thread.run(Thread.java:745)
Caused by:
java.lang.NoSuchMethodException: com.thing.ThingFilter.<init>()
        at java.lang.Class.getConstructor0(Class.java:3082)
        at java.lang.Class.newInstance(Class.java:412)
        at org.eclipse.jetty.server.handler.ContextHandler$Context.createInstance(ContextHandler.java:2510)
        at org.eclipse.jetty.servlet.ServletContextHandler$Context.createServlet(ServletContextHandler.java:1326)
        at org.eclipse.jetty.servlet.ServletHolder.newInstance(ServletHolder.java:1208)
        at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:611)
        at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:495)
        at org.eclipse.jetty.servlet.ServletHolder.ensureInstance(ServletHolder.java:782)
        at org.eclipse.jetty.servlet.ServletHolder.prepare(ServletHolder.java:767)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:538)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1584)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1228)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1130)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
        at org.eclipse.jetty.server.Server.handle(Server.java:564)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:318)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112)
        at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
        at java.lang.Thread.run(Thread.java:745)

看起来它只是试图创建对象而不指定任何构造函数参数,这当然不起作用。

我们创建这样的嵌入式Jetty服务器:

String webAppPath = "...path to WAR";

WebAppContext webAppContext = new WebAppContext(webAppPath, "/");
JettyWeldInitializer.initWebApp(webAppContext);
webAppContext.addEventListener(new Listener());

server.setHandler(webAppContext);
server.start();

我做错了什么?

3 个答案:

答案 0 :(得分:1)

Weld的Jetty集成仍然需要默认的构造函数。 servlet规范非常清楚,过滤器,servlet,监听器不是托管组件,而是支持注入点。因此,Weld集成基于满足注入点的非托管实例,并且不将它们视为托管类,它的实例化bean的Jetty。特别是Jetty不允许您管理这些类的生命周期。看看JettyWeldInjectorAbstractInjector,它们表明它只是处理注入点。

答案 1 :(得分:0)

这个类中有默认构造函数吗? 如果你不这样做,你怎么期望创建一个类的实例传递给构造函数?

答案 2 :(得分:-1)

您无法挑选和选择Java EE组件规范的各种实现(例如servlet和jsp apis的实现,以及CDI实现,将它们放在一起并期望它们知道如何一起工作。

需要整合各种部件。

这就是WebSphere,GlassFish,WildFly等存在的原因。

您可以考虑使用Arquillian和WebSphere Liberty

来推动集成测试