Spring的”@Validated”在Liberty和注入中无法正常工作。

huangapple 未分类评论50阅读模式
英文:

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>

huangapple
  • 本文由 发表于 2020年5月29日 23:23:42
  • 转载请务必保留本文链接:https://java.coder-hub.com/62089368.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定