【问题标题】:Constructor injection with Jetty throws InstantiationException使用 Jetty 的构造函数注入抛出 InstantiationException
【发布时间】:2017-01-27 14:33:10
【问题描述】:

我觉得我在这里遗漏了一些明显的东西......

我有许多需要在运行时注入各种依赖项的 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();

我做错了什么?

【问题讨论】:

    标签: java jakarta-ee jetty cdi


    【解决方案1】:

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

    【讨论】:

    • 对,我的错,我以为一切都已管理,但显然事实并非如此。感谢您的帮助!
    【解决方案2】:

    你有这个类的默认构造函数吗? 如果不这样做,您希望如何创建该类的实例以传递给构造函数?

    【讨论】:

    • 是的,ThingDependency 有一个默认构造函数。问题是我们与 Jetty (Weld) 一起使用的 CDI 实现期望 ThingFilter 有一个默认构造函数 - WebSphere 的实现对此没有任何问题,并且可以正确执行注入。
    【解决方案3】:

    你不能选择 Java EE 组件规范的各种实现(例如 servlet 和 jsp api 的实现,以及 CDI 实现,将它们放在一起并期望它们知道如何协同工作。

    需要整合各个部分。

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

    您可以考虑使用 Arquillian 和 WebSphere Liberty 来驱动您的集成测试

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 2012-06-19
      相关资源
      最近更新 更多