用于Bean验证的Jersey扩展是否支持Bean验证2.0(JSR 380)

用于Bean验证的Jersey扩展是否支持Bean验证2.0(JSR 380),jersey,jersey-2.0,bean-validation,websphere-liberty,jsr380,Jersey,Jersey 2.0,Bean Validation,Websphere Liberty,Jsr380,我正在使用WebSphere Liberty 19.0.0.2和webProfile-8.0功能,该功能支持jaxrs-2.1和beanValidation-2.0。为了更好地支持多部分流媒体,我使用Jersey作为JAX-RS实现,而不是Liberty默认的Apache CXF 有关相关组件版本控制的更多上下文信息 Bean验证1.1(JSR349),Bean验证2.0(JSR380) 我想使用BeanValidation2.0特性来验证REST资源类中的请求/响应/参数,为此,我需要使用Je

我正在使用WebSphere Liberty 19.0.0.2webProfile-8.0功能,该功能支持jaxrs-2.1beanValidation-2.0。为了更好地支持多部分流媒体,我使用Jersey作为JAX-RS实现,而不是Liberty默认的Apache CXF

有关相关组件版本控制的更多上下文信息

Bean验证1.1(JSR349),Bean验证2.0(JSR380)

我想使用BeanValidation2.0特性来验证REST资源类中的请求/响应/参数,为此,我需要使用Jersey的扩展进行bean验证

正如您在这个链接上看到的(如果向下滚动),扩展的最新版本(2.30.1)也参考了JSR-349,它是bean validation 1.1

下面的gradle依赖项中的jar的MENIFEST也提到了JSR-349

compile group: 'org.glassfish.jersey.ext', name: 'jersey-bean-validation', version: '2.30'

令人惊讶的是,BeanValidation2.0(JSR380)没有Jersey扩展

当我在liberty中使用上述依赖项时,bean验证可以工作,但在服务器启动时,由于我的资源类中使用了bean验证注释,所以出现以下错误

[3/5/20 18:11:28:597 EST] 00000020 id=00000000 org.glassfish.jersey.model.Parameter                         2 Unable to get the com.sun.proxy.$Proxy70 annotation value property
java.lang.NoSuchMethodException: javax.validation.constraints.NotNull.value()
    at java.lang.Class.getMethod(Class.java:1786)
    at org.glassfish.jersey.model.Parameter.getValue(Parameter.java:453)
    at org.glassfish.jersey.model.Parameter.create(Parameter.java:270)
    at org.glassfish.jersey.model.Parameter.createList(Parameter.java:400)
    at org.glassfish.jersey.model.Parameter.createList(Parameter.java:383)
    at org.glassfish.jersey.server.model.Parameter.create(Parameter.java:137)
    at org.glassfish.jersey.server.model.Invocable.<init>(Invocable.java:215)
    at org.glassfish.jersey.server.model.Invocable.create(Invocable.java:161)
    at org.glassfish.jersey.server.model.ResourceMethod$Builder.createInvocable(ResourceMethod.java:541)
    at org.glassfish.jersey.server.model.ResourceMethod$Builder.build(ResourceMethod.java:522)
    at org.glassfish.jersey.server.model.Resource$Builder.processMethodBuilders(Resource.java:647)
    at org.glassfish.jersey.server.model.Resource$Builder.buildResourceData(Resource.java:583)
    at org.glassfish.jersey.server.model.Resource$Builder.build(Resource.java:639)
    at org.glassfish.jersey.server.model.Resource.from(Resource.java:782)
    at org.glassfish.jersey.server.ResourceBagConfigurator.init(ResourceBagConfigurator.java:55)
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:331)
    at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$1(ApplicationHandler.java:293)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
    at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:232)
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:292)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:259)
    at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:311)
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154)
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:347)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:291)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1373)
    at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:1157)
    at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:1125)
    at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1023)
    at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6619)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:467)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApplication(DynamicVirtualHost.java:462)
    at com.ibm.ws.webcontainer.osgi.WebContainer.startWebApplication(WebContainer.java:1152)
    at com.ibm.ws.webcontainer.osgi.WebContainer.access$000(WebContainer.java:111)
    at com.ibm.ws.webcontainer.osgi.WebContainer$3.run(WebContainer.java:957)
    at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:239)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

[3/5/20 18:11:28:598 EST] 00000020 id=00000000 org.glassfish.jersey.model.Parameter                         2 Unable to get the com.sun.proxy.$Proxy29 annotation value property
java.lang.NoSuchMethodException: javax.validation.Valid.value()
    at java.lang.Class.getMethod(Class.java:1786)
    at org.glassfish.jersey.model.Parameter.getValue(Parameter.java:453)
    at org.glassfish.jersey.model.Parameter.create(Parameter.java:270)
    at org.glassfish.jersey.model.Parameter.createList(Parameter.java:400)
    at org.glassfish.jersey.model.Parameter.createList(Parameter.java:383)
    at org.glassfish.jersey.server.model.Parameter.create(Parameter.java:137)
    at org.glassfish.jersey.server.model.Invocable.<init>(Invocable.java:215)
    at org.glassfish.jersey.server.model.Invocable.create(Invocable.java:161)
    at org.glassfish.jersey.server.model.ResourceMethod$Builder.createInvocable(ResourceMethod.java:541)
    at org.glassfish.jersey.server.model.ResourceMethod$Builder.build(ResourceMethod.java:522)
    at org.glassfish.jersey.server.model.Resource$Builder.processMethodBuilders(Resource.java:647)

我提到了jersey bean验证版本2.30的使用,但我了解到,jersey 2.27是JAX-RS2.1API的JavaEE实现的最新版本。开始2.28版JAX-RS 2.1的雅加达EE实现。所以我真的想使用2.27版,让bean validation 2.0与之配合使用,因为我使用的liberty版本尚未达到jakarta ee。

所有问题的原因是jersey bean validation jar中打包的META-INF信息不正确,而且gradle依赖项也不正确

如果您看到它包括验证api 1.1.0.Final和hibernate validator 5.1.3.Final(用于Bean验证1.1)(JSR 349),请转到url并向下滚动。

您必须排除上述不正确的可传递依赖项,并包括BeanValidation2.0(JSR380)的正确版本,即HibernateValidator6.0(6.0.18.Final)

如果您的容器已经提供了bean验证的实现,则不需要包括hibernate验证器jar。在我的例子中,在liberty中启用beanValidation beanValidation-2.0提供了bean验证实现

// Jersey 2.27 is latest version which is JAVA EE implementation of JAX-RS 2.1 API. Starting 2.28 its Jakarta EE implementation of JAX-RS 2.1
compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.27'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.27'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-multipart', version: '2.27'
compile (group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.27') {
    exclude group: 'javax.inject', module: 'javax.inject'
}
compile (group: 'org.glassfish.jersey.ext', name: 'jersey-bean-validation', version: '2.27') {
    exclude group: 'javax.el', module: 'javax.el-api'
    exclude group: 'org.hibernate'
}

configurations.compile {
    exclude group: 'javax.validation', module: 'validation-api'
    exclude group: 'javax.annotation', module: 'javax.annotation-api'
}
在编译配置级别排除了2个JAR,因为它们是来自多个位置的可传递依赖项


这解决了所有问题,bean验证可以像charm一样工作。

你能发布你的server.xml吗?特别是您正在使用的功能和应用程序设置?你申请的内容是什么?如果您使用的是Jersey而不是内置的CXF,那么您可能希望禁用jaxrs-2.1特性,或者您使用的是parent last classloading委派。后者可能是问题的一部分。至于清单头,这很可能是打包代码中的错误。我可以从Jersey bean验证项目中的pom.xml依赖项看出,它依赖于Jakarta bean validation 2.0。HTH@AndyMcCright谢谢你的回复。更新了问题,提供了您需要的更多信息。正如我在更新liberty版本中提到的,我正在使用的版本尚未达到jakarta ee,因此我想真正使用jersey core和扩展版本2.27来使bean验证2.0正常工作。您可以在看到bean验证api版本的地方共享pom文件的url吗?这是我正在查看的pom.xml(master-可能更接近于2.30.1):应该可以将Jakarta EE 8 api与Java EE 8互换使用,因此您应该能够使用更高版本的Jersey(由于包名更改,EE 9不兼容)-尽管这可能仍然无助于解决此问题。这是否包括支持提供时钟等新功能?
import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;

@ApplicationPath("/rest")
public class RestApplicationConfig extends ResourceConfig {

    public RestApplicationConfig() {
        super();
        configureResourcesAndFeatures();
    }

    private void configureResourcesAndFeatures() {
        packages(RestApplicationConfig.class.getPackage().getName());
        register(MultiPartFeature.class);

        property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
    }
}
// Jersey 2.27 is latest version which is JAVA EE implementation of JAX-RS 2.1 API. Starting 2.28 its Jakarta EE implementation of JAX-RS 2.1
compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.27'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.27'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-multipart', version: '2.27'
compile (group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.27') {
    exclude group: 'javax.inject', module: 'javax.inject'
}
compile (group: 'org.glassfish.jersey.ext', name: 'jersey-bean-validation', version: '2.27') {
    exclude group: 'javax.el', module: 'javax.el-api'
    exclude group: 'org.hibernate'
}

configurations.compile {
    exclude group: 'javax.validation', module: 'validation-api'
    exclude group: 'javax.annotation', module: 'javax.annotation-api'
}