【问题标题】:Cross-context request forwarding in tomcat results in java.lang.ClassCastException: org.glassfish.jersey.message.internal.TracingLoggertomcat 中的跨上下文请求转发导致 java.lang.ClassCastException: org.glassfish.jersey.message.internal.TracingLogger
【发布时间】:2026-02-02 11:20:09
【问题描述】:

我正在尝试使用 RequestDispatcher.forward(request, response) 将请求从一个 webapp(使用 Jersey 2.10)转发到另一个(“myWebapp”)。两个 webapp 都驻留在 /tomcat/webapps 中。在 context.xml 我设置了<Context crossContext="true">

@GET
@Path("")
public Response getTest(
        @Context ServletContext context,
        @Context HttpServletRequest request,
        @Context HttpServletResponse response)
        throws Exception {

        ServletContext fCtx = context.getContext("/myWebapp");
        System.out.println("ctx: "+context);
        System.out.println("forward-ctx: "+fCtx);

        RequestDispatcher dispatcher=fCtx.getRequestDispatcher("/test");
        System.out.println("rd: "+dispatcher);      

        System.out.println("request: "+request);
        System.out.println("response: "+response);

        dispatcher.forward(request, response); <- throwing ClassCastException

}

这显示了以下输出:

ctx: org.apache.catalina.core.ApplicationContextFacade@48a7c880
forward-ctx: org.apache.catalina.core.ApplicationContextFacade@72d0abcb
rd: org.apache.catalina.core.ApplicationDispatcher@7f5c70c3
request: org.apache.catalina.connector.RequestFacade@3829f752
response: org.apache.catalina.connector.ResponseFacade@4b2c454c

所以一切都应该设置好。但是当我执行它时,我得到以下转发异常:

java.lang.ClassCastException: org.glassfish.jersey.message.internal.TracingLogger$1 cannot be cast to org.glassfish.jersey.message.internal.TracingLogger
    at org.glassfish.jersey.message.internal.TracingLogger.getInstance(TracingLogger.java:144)
    at org.glassfish.jersey.server.internal.routing.UriRoutingContext.<init>(UriRoutingContext.java:115)
    at org.glassfish.jersey.server.ContainerRequest.<init>(ContainerRequest.java:179)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:345)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:690)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:477)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)

我不确定,如果这与泽西岛不兼容?我尝试了最新版本的 Jersey 2.17。这可能是与实际转发无关的泽西岛事情吗?我该如何解决它......?

更新: 有趣的是,无论请求方法是 GET 还是 POST,都会抛出相同的错误。在另一个应用程序中,使用完全相同的设置,转发工作。所以我认为,这本身不是泽西岛问题,而是取决于我的设置。仍然无法弄清楚它可能是什么。

【问题讨论】:

  • 您好,这两个应用程序使用的是同一个球衣版本,对吧?
  • @kucing_terbang 好吧,通过测试,我现在把它弄混了。所以目前我在执行前锋的 webapp 中使用 jersey 2.13。在另一个 webapp 中,我使用 2.10(不起作用)和 2.5.1 在另一个 webapp 中,它可以工作。
  • @kucing_terbang 将我的球衣版本更改为 2.5.1。那成功了。其实很简单。可惜我没认出来。以前使用不同的球衣版本有问题。
  • 酷,对你有好处;)

标签: java tomcat jersey-2.0 forward


【解决方案1】:

在转发以及最终请求的 webapp 中将我的 Jersey 版本更改为 2.5.1,以保持一致。这样就成功了,实际上很简单。太糟糕了,我没有意识到这一点,因为我之前在使用不同的球衣版本时遇到过问题。

编辑: 事实证明,这个约束实际上是相当累人的,并且在必要的 Jersey 版本更改上变得乏味,以保持所有应用程序的一致性。在更新到 2.22.2 时,即使使用相同的版本,也确实发生了错误。现在更好的解决方案是将调度程序 webapp 更改为一个简单的 servlet,因此它不包含任何 Jersey 依赖项,因此不会与转发应用程序的 Jersey 版本冲突。

【讨论】: