无法将 HttpServletRequest 注入 ContainerRequestFilter with Javal 11、Jetty 和 Jersey



我正在更新Java 8 web服务以在Java 11上运行。我对Java不太熟悉,我对c#。net环境比较熟悉。我已经阅读了几十篇关于这个问题的文章和问题,我非常确信我的代码应该可以工作,但是我的项目设置是错误的。

我的原始项目只有一个Eclipse项目文件,我添加了Maven,并重新组织了我的项目,以便我可以构建一个爆炸的WAR并从那里进行调试。目前,有问题的代码如下:

@Provider
@Priority(Priorities.AUTHENTICATION)
public class SecurityFilter implements ContainerRequestFilter {
@Inject
private jakarta.inject.Provider<HttpServletRequest> requestProvider;

@Override
public void filter(ContainerRequestContext filterContext) throws IOException {
var servletRequest = requestProvider.get();
}
}
这给了我一个错误,如:
jakarta.servlet.ServletException: jakarta.servlet.ServletException: A MultiException has 2 exceptions.  They are:
1. java.lang.IllegalArgumentException: org.glassfish.hk2.api.ProxyCtl referenced from a method is not visible from class loader
2. java.lang.IllegalArgumentException: While attempting to create a Proxy for jakarta.servlet.http.HttpServletRequest in scope org.glassfish.jersey.process.internal.RequestScoped an error occured while creating the proxy
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:157)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
at org.eclipse.jetty.server.Server.handle(Server.java:562)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:406)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:663)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:398)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:319)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
at org.eclipse.jetty.io.SocketChannelEndPoint$1.run(SocketChannelEndPoint.java:101)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:412)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:381)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:268)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce(AdaptiveExecutionStrategy.java:190)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:894)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1038)
at java.base/java.lang.Thread.run(Thread.java:831)
Caused by: jakarta.servlet.ServletException: A MultiException has 2 exceptions.  They are:
1. java.lang.IllegalArgumentException: org.glassfish.hk2.api.ProxyCtl referenced from a method is not visible from class loader
2. java.lang.IllegalArgumentException: While attempting to create a Proxy for jakarta.servlet.http.HttpServletRequest in scope org.glassfish.jersey.process.internal.RequestScoped an error occured while creating the proxy
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:410)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1410)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:508)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:580)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1571)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1370)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:463)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1544)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1292)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:192)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:141)
... 16 more

我的原始代码是这样的:

@Provider
@Priority(Priorities.AUTHENTICATION)
public class SecurityFilter implements ContainerRequestFilter {
@Context
private HttpServletRequest servletRequest;

@Override
public void filter(ContainerRequestContext filterContext) throws IOException {
}
}

给出了同样的两个异常加上另外一个4。@Inject方法在动作被调用时导致异常,@Context方法在服务器启动时导致异常,但无论哪种情况,httpServletRequest都不能由DI容器/作用域提供。

我不是100%确定所有的位是如何一起工作的,但如果我有正确的,应用程序使用Jetty 11.0.6自托管web服务器,与Jersey 3.0.2容器,运行雅加达平台9.1.0 - Servlet API V5.0,和雅加达JAXB web服务。我想我遗漏了一个依赖项,但我还不能确定它是什么。以下是我的POM和Web.xml文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Demo-Server</groupId>
<artifactId>Demo-Server</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>Demo Server</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>16</release>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.17</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.9.2</version>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>9.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-plus</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.2.1.jre11</version>
</dependency>
<dependency>
<groupId>com.sap.cloud.db.jdbc</groupId>
<artifactId>ngdbc</artifactId>
<version>2.9.12</version>
<type>pom</type>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven2</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0">
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.demo.bridge.app.Application</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/demo/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/webts/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.demo.rest.service</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
</web-app>
我真的希望有人知道我错过了什么。仅供参考-我已经在我的POM中留下了所有当前依赖项,而不仅仅是那些我认为相关的依赖项,因为可能是我有多个依赖项导致了这个问题。

服务器启动代码更难清理,但如果有必要,我可以发布它-主要部分是WebAppContext,它似乎可以读取servlet -如果我不使用@Context, servlet也会响应,它们只是因为空引用或坏的DI设置而崩溃。

感谢您的帮助。

——更新

我一直在切换一些Maven依赖项。我很确定我有Jetty, Jakarta, JAXB和Jersey的基本依赖关系,但我仍然得到@Context/@Inject的问题。我很需要这件org.glassfish.球衣。inject:jersey-hk2包,因为如果我把它去掉,我会得到一个错误:java.lang。。如果我再加上雅加达。

所以基本上我有两个注入包,@Context/@Inject对其中一个或两个都不起作用。我想知道雅加达9是否需要一些设置代码,但我没有在任何示例中看到任何设置代码。

我的pom依赖现在看起来像这样-仍然不高兴(我还忽略了应用程序深度):

<!-- Jakarta -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>9.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>2.0.0</version>
</dependency>

<!-- JAXB -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.1</version>
</dependency>

<!-- Jetty -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>11.0.6</version>
</dependency>

<!-- Jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.0.2</version>
</dependency>

最新更新:

所以我切换回OpenJDK 8,期待项目运行,事实证明它不起作用。在将jar与原始项目进行比较时,我注意到我的新程序具有不同的jar。进一步看,现有的项目没有HK2文件,但这些文件在jersey-common包中发货。

有没有人知道如何在项目中有泽西没有航运HK2罐,因为HttpServletRequest的注入工作没有他们?

标记

所以这个问题很难解决,因为元素在Jetty, Jakarta和Jersey之间的交互方式在运行时都在幕后,也就是说,程序成功编译了任何数量的不工作的排列。

无论如何,经过大约7天的实验,允许注入HttpServletRequest工作的包的集合如下:

<!-- Jakarta -->
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-jakarta-servlet-api</artifactId>
<version>5.0.1</version>
<!-- <scope>provided</scope> -->
</dependency>
<dependency>
<groupId>org.glassfish.hk2.external</groupId>
<artifactId>jakarta.inject</artifactId>
<version>2.6.1</version>
</dependency>
<!-- JAXB -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.1</version>
</dependency>

<!-- Jetty -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>11.0.6</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-xml</artifactId>
<version>11.0.6</version>
</dependency>

<!-- Jersey -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>

我在Java 8中编译我的原始项目时发现了这个问题(就像我添加Maven之前一样),我发现我的非Maven项目没有输出3个hk2相关的库,hk2-api-2.2.0-b21.jar, hk2-locator-2.2.0-b21.jar, hk2-utils-2.2.0-b21.jar。删除这些文件可以使程序正常运行。

然后我尝试使用依赖排除,但即使我最终使用相同的库,程序也无法工作。现在我不太确定这是如何工作的,但我记得读到依赖关系可以作用域为"提供",这就是说(如果我理解正确的话)-所需的类实现已经存在于您已经拥有的一些库中(如JRE或其他依赖),因此您不必再次包含库。

再次-我不明白为什么这工作,但它绝对必须这样设置。我真的希望这能让某人少活几天!

最新更新