英文:
Spring's "@Validated" doesn't work with Liberty and injection
问题
在Spring Boot项目的控制器类中使用@Validated
注解,并在Liberty服务器上运行时,依赖注入似乎出现了问题(在调用注入变量的那一行会返回NullPointerException)。如果在Tomcat上运行项目,它可以正常工作。如果将类上的@Validated
注解注释掉并在Liberty上运行项目,也能正常工作。问题似乎仅出现在使用@Validated
和Liberty上。有任何想法吗?
这是一个最小化的可复现示例:
TestController.java:
// 在这里是 TestController.java 的代码
TestComponent.java:
// 在这里是 TestComponent.java 的代码
TestApplication.java:
// 在这里是 TestApplication.java 的代码
pom.xml:
// 在这里是 pom.xml 的代码
这是使用Spring Boot v2.2.7和WebSphere Application Server版本20.0.0.5 Liberty的情况。
编辑:
这是空指针异常的堆栈跟踪信息:
// 在这里是堆栈跟踪的内容
英文:
When I use the "@Validated" annotation in a Controller class in a Spring Boot project and run it on a Liberty server, dependency injection appears broken (it returns a NullPointerException on the line calling the injected variable). If I run the project on Tomcat, it works fine. If I comment out "@Validated" on the class and run the project on Liberty, that works too. It's only with "@Validated" and Liberty. Any ideas?
Here is my minimal reproducible example:
TestController.java:
package sr.libertyspringtest;
import java.io.UnsupportedEncodingException;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Validated
public class TestController {
private TestComponent testComponent;
public TestController(TestComponent testComponent) {
this.testComponent = testComponent;
}
@GetMapping("/hello")
ResponseEntity<?> hello() throws UnsupportedEncodingException{
String testString = testComponent.getTestString();
return ResponseEntity.ok().body(testString);
}
}
TestComponent.java:
package sr.libertyspringtest;
import org.springframework.stereotype.Component;
@Component
public class TestComponent {
public String getTestString() {
return "test";
}
}
TestApplication.java:
package sr.libertyspringtest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class TestApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TestApplication.class);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>sr</groupId>
<artifactId>libertyspringtest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>libertyspringtest Maven Webapp</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
This is with Spring Boot v2.2.7 and WebSphere Application Server Version 20.0.0.5 Liberty.
EDIT:
Here is the stacktrace for the NPE:
java.lang.NullPointerException: null
at sr.libertyspringtest.TestController.hello(TestController.java:23) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_251]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_251]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_251]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_251]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:686) ~[com.ibm.websphere.javaee.servlet.4.0_1.0.40.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:791) ~[com.ibm.websphere.javaee.servlet.4.0_1.0.40.jar:na]
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1230) ~[na:na]
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:729) ~[na:na]
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:426) ~[na:na]
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:182) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:93) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:201) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:90) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:201) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:90) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:128) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:66) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:103) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:121) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:201) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:90) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:201) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:90) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:1001) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1139) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:5021) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.handleRequest(DynamicVirtualHost.java:314) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1007) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:279) [com.ibm.ws.webcontainer_1.1.40.jar:na]
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:1134) [com.ibm.ws.transport.http_1.0.40.jar:na]
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:415) [com.ibm.ws.transport.http_1.0.40.jar:na]
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:374) [com.ibm.ws.transport.http_1.0.40.jar:na]
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:551) [com.ibm.ws.transport.http_1.0.40.jar:na]
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:484) [com.ibm.ws.transport.http_1.0.40.jar:na]
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:346) [com.ibm.ws.transport.http_1.0.40.jar:na]
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.ready(HttpInboundLink.java:317) [com.ibm.ws.transport.http_1.0.40.jar:na]
at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:167) [com.ibm.ws.channelfw_1.0.40.jar:na]
at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:75) [com.ibm.ws.channelfw_1.0.40.jar:na]
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:504) [com.ibm.ws.channelfw_1.0.40.jar:na]
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:574) [com.ibm.ws.channelfw_1.0.40.jar:na]
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:958) [com.ibm.ws.channelfw_1.0.40.jar:na]
at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1047) [com.ibm.ws.channelfw_1.0.40.jar:na]
at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:239) [com.ibm.ws.threading_1.1.40.jar:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_251]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_251]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_251]
答案1
得分: 0
可能是因为您的server.xml文件缺少一些功能,因为它在Tomcat上运行正常。这可能会有所帮助:
<featureManager>
<feature>beanValidation-2.0</feature>
<feature>cdi-2.0</feature>
</featureManager>
英文:
It might be that you are missing some features in your server.xml since it works on Tomcat. This might help:
<featureManager>
<feature>beanValidation-2.0</feature>
<feature>cdi-2.0</feature>
</featureManager>
专注分享java语言的经验与见解,让所有开发者获益!
评论