当前位置: 首页 > 知识库问答 >
问题:

在不同端口启动执行器时的NPE[重复]

麹学文
2023-03-14

在将执行器配置为在不同端口上启动时,应用程序会出现以下StackTrace失败:

java.lang.NullPointerException: null
at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:241) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
  at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:270) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
  at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:106) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
  at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4528) [tomcat-embed-core-9.0.37.jar:9.0.37]

aop发出以下信息警告:

2020-08-16 10:01:11.240  INFO 83848 --- [           main] o.s.aop.framework.CglibAopProxy          : Unable to proxy interface-implementing method [public final void org.springframework.web.filter.GenericFilterBean.init(javax.servlet.FilterConfig) throws javax.servlet.ServletException] because it is marked as final: Consider using interface-based JDK proxies instead!
plugins {
  id 'org.springframework.boot' version '2.3.3.RELEASE'
...
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.1.5.RELEASE'
implementation 'org.springframework.security:spring-security-jwt:1.0.10.RELEASE'
...
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.stereotype.Component;
...
@Aspect
@Component
@Slf4j
public class MyFilter {

    @Around("execution(public void org.springframework.security.web.FilterChainProxy.doFilter(..))")
    public void handleRequestRejectedException (ProceedingJoinPoint pjp) throws Throwable {
        try {
            pjp.proceed();
        } catch (RequestRejectedException exception) {
           ...
        }
    }
}

感谢任何/所有的帮助。

  • 詹姆斯

共有1个答案

陆文康
2023-03-14

在OP用一些示例代码更新了这个问题之后,我发现问题并不是像我在评论中链接到的另一个问题那样的过于通用的切入点,捕获了太多的类,而是其他问题:

James,您的目标是方法FilterChainProxy.doFilter(..),即直接是一个Spring框架类。问题是,正如您在日志中得到的错误消息中所看到的那样:

o.s.aop.framework.CglibAopProxy:
  Unable to proxy interface-implementing method [
    public final void org.springframework.web.filter.GenericFilterBean.init(javax.servlet.FilterConfig)
    throws javax.servlet.ServletException
  ]
  because it is marked as final:
  Consider using interface-based JDK proxies instead!

问题是目标类派生自GenericFilterBean,其中init(..)方法标记为final。CGLIB通过子类化和重写非私有方法来工作,但是不能重写final方法。因此,Spring AOP抱怨道。

错误消息还提示您如何解决该问题:您可以使用通过实现接口工作的JDK代理,而不是为目标使用CGLIB代理。幸运的是,doFilter是一个接口方法,更准确地说是JavaEE方法filter.doFilter(..)的实现。

现在的下一个问题是,您使用的不是普通的Spring,而是Spring Boot,它以预置的组合而闻名,这些预置似乎使您无法切换到JDK代理,尽管在普通的Spring中,这甚至是默认的。但是Boot想让用户太友好和聪明,让你陷入这个陷阱。我不记得Spring Boot ticket处理这个问题,但上次我检查它没有解决。

避免这种情况的一种方法是对方面使用完整的AspectJ,而不是只使用Spring AOP,从而使您摆脱基于代理的“AOP精简”方法,并使您能够直接修改目标类,或者通过call()pointcut(Spring AOP不支持)将方面编织到所有调用类中而不是目标类中。

另一个解决方案是将您的方面与另一个问题较少的目标类/方法挂钩,而不是直接与带有final方法的Spring framework类挂钩。

附注:我不是Spring用户,我只是从这里回答与AOP相关的问题中碰巧知道了一些细节。实际上,我很惊讶Spring实现的CGLIB代理对final方法并不宽容,只是忽略它们并记录一个警告,而不是试图重写它们并产生错误。也许有一些配置选项,但我把它留给Spring的人来回答这个问题,我在这里没有线索。

我不能更准确地回答,因为我需要在GitHub上看到一个完整的MCVE,最好是一个Maven或Gradle项目,以便进一步分析您的情况。我只是想在这里解释一些基础知识。

 类似资料:
  • 问题内容: Jenkins无法运行android模拟器。 然后,我尝试与jenkins一样运行模拟器。问题是android模拟器没有开始监听端口。首先,我以“用户”用户成功创建并启动了模拟器,如下所示: 因此,“用户”用户一切正常,但对于“詹金斯”用户,我有问题 就是这样!不管我等待了​​多少时间,“仿真器:在端口5554上监听控制台连接”这一行都不到了! 顺便说一句,kvm对两个用户都运行良好

  • 问题内容: 我一直在研究Spring / Spring MVC应用程序,并且希望添加性能指标。我遇到过Spring Boot Actuator,它看起来是一个不错的解决方案。但是我的应用程序不是Spring Boot应用程序。我的应用程序在传统容器Tomcat 8中运行。 我添加了以下依赖 我创建了以下配置类。 我什至可以按照StackOverflow另一篇文章的建议在每个配置类上添加 问题答案:

  • 在我的Spring Boot应用程序(2.0.0.M7)中。我设置的属性 然而,当我击中 我得到404。 解决办法是什么?

  • 我有一个python脚本,它计算给定文件的字数,并在执行后将输出保存到“result.txt”文件中。我希望docker容器在容器启动时执行此操作,并在控制台上显示输出。下面是我的docker文件和python文件 我正在映射一个本地目录,它有两个文本文件IF. txt和Limerick1.txt从主机到容器内的目录/home/data,容器内的python代码读取文件并将输出保存到result.

  • 问题内容: 我有一个构建作业和一个测试作业参数。 我想从事构建工作,在并行执行中同时运行一个参数的测试作业和具有不同参数的同一测试作业。 如何做到这一点,以及是否有可能无需编写自己的插件即可执行? 谢谢! 问题答案: 创建测试作业时,将其创建为“构建多配置项目”。在配置作业时,选择“配置矩阵”,然后选择“用户定义的轴” 您可以在作业中将此轴的名称用作参数。给定的参数将在不同的作业中同时启动。(如果

  • 在我的休闲Spring启动应用程序中,我注册了这样的servlet。 该servlet与应用程序注册在同一端口上。问题是,我的基础架构(k8s等)期望应用程序和度量endpoint在不同的端口上工作(就像执行器一样)。 如何在不同的端口上注册第三方servlet?