Does Jersey Extension for Bean Validation supports Bean Validation 2.0 (JSR 380) - jersey

I am working with WebSphere Liberty 19.0.0.2 with webProfile-8.0 feature which supports jaxrs-2.1 and beanValidation-2.0. For better support for MutiPart streaming I am using Jersey as JAX-RS implementation instead of liberty's default Apache CXF.
Some more contextual information about versioning of relevant components
Bean Validation 1.1 (JSR 349), Bean Validation 2.0 (JSR 380)
I want to use bean validation 2.0 feature to validate request/response/params in my REST Resource class and for that I need use Jersey's extension for bean validation. https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/bean-validation.html
As you can see on this link (if you scroll down) the latest version of the extension (2.30.1) also refer to JSR-349 which is bean validation 1.1.
MENIFEST of the jar from following gradle dependency also mention JSR-349
compile group: 'org.glassfish.jersey.ext', name: 'jersey-bean-validation', version: '2.30'
Its surprising that there is no Jersey extension for Bean Validation 2.0 (JSR 380).
When I use above dependency in liberty, bean validation works but I get following error on server startup because of bean validation annotation usage in my resource class.
[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)
These error are concerning and not feeling confident to use it. Any advice or help is much appreciated.
Update 03/06/2020
Following is feature manager section from server.xml
<featureManager>
<!--NOTE: Following are standard features and should not be removed-->
<feature>servlet-4.0</feature>
<feature>jndi-1.0</feature>
<feature>requestTiming-1.0</feature>
<feature>monitor-1.0</feature>
<feature>localConnector-1.0</feature>
<feature>restConnector-2.0</feature>
<feature>ssl-1.0</feature>
<!-- Do not add enabled webProfile-8.0 because we want to disable default
REST implementation (Apache-CXF) provided by Liberty. We want to use Jersey
as our REST implementation because it better support multi-part streaming, -->
<!-- <feature>webProfile-8.0</feature> -->
<feature>jsp-2.3</feature>
<feature>cdi-2.0</feature>
<feature>managedBeans-1.0</feature>
<feature>jdbc-4.2</feature>
<feature>beanValidation-2.0</feature>
<!-- We need javaMail feature for logback email appender to work -->
<feature>javaMail-1.6</feature>
</featureManager>
Here is my rest application configuration extending jersey's ResourceConfig class
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);
}
}
I mentioned use of jersey-bean-validation version 2.30 but I learned that 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. So I would really want to use version 2.27 and make bean validation 2.0 working with it because liberty version I am using has not up to jakarta ee yet.

Cause of all the issues was incorrect META-INF information packaged within jersey-bean-validation jar and also incorrect gradle dependency.
If go to https://mvnrepository.com/artifact/org.glassfish.jersey.ext/jersey-bean-validation/2.27 url and scroll down if you see it includes validation-api 1.1.0.Final and hibernate-validator 5.1.3.Final which for Bean Validation 1.1 (JSR 349).
You have to exclude above incorrect transitive dependencies and include correct version for Bean Validation 2.0 (JSR 380) which is Hibernate Validator 6.0 (6.0.18.Final)
If your container already provides implementation of bean validation, you don't need to include hibernate validator jar. In my case enabling beanValidation beanValidation-2.0 in liberty it provides bean validation implementation.
// 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'
}
excluded 2 jars at compile configuration level because they were coming as transitive dependencies from multiple places.
This fixed all issues and bean validation works like charm.

Related

Integration Test Started failing post Spring boot 2.2.0 upgrade with Swagger latest version 2.9.2 & HATEOS

Integration Test Started failing post Spring boot 2.2.0 upgrade with Swagger latest version 2.9.2 & HATEOS
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'linkDiscoverers'
defined in class path resource [org/springframework/hateoas/config/HateoasConfiguration.class]:
Unsatisfied dependency expressed through method 'linkDiscoverers' parameter 0;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'org.springframework.plugin.core.PluginRegistry<org.springframework.hateoas.client.LinkDiscoverer,
org.springframework.http.MediaType>' available: expected single matching bean but
found 3: relProviderPluginRegistry,linkDiscovererRegistry,entityLinksPluginRegistry
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'org.springframework.plugin.core.PluginRegistry<org.springframework.hateoas.client.LinkDiscoverer,
org.springframework.http.MediaType>' available: expected single matching bean but found 3:
relProviderPluginRegistry,linkDiscovererRegistry,entityLinksPluginRegistry
The issue with springfox may take while to resolve issue but there is alternative available with latest swagger v3 have similar capabilities of springfox
https://github.com/springdoc/springdoc-openapi.git
Only disabled the SpringFox dependencies, added SpringDoc, and replaced the SpringFox bean, with a SpringDoc bean. Everything is working as expected. All I need to do is to convert a couple of annotations on each rest service so SpringDoc displays everything correctly. SpringDoc does work
I used this and it works for me
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency

Spring Boot application breaks after upgrade to Apache Derby 10.15 -- why?

During a round of SOUP upgrades in a Spring Boot application, I bumped Apache Derby from 10.14.1.0 to 10.15.1.3. Now the tests fail with this beauty (snipped, full stacktrace here):
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration':
Unsatisfied dependency expressed through constructor parameter 0
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dataSource':
Invocation of init method failed
Caused by: java.lang.IllegalStateException:
Failed to replace DataSource with an embedded database for tests.
If you want an embedded database please put a supported one on the
classpath or tune the replace attribute of #AutoConfigureTestDatabase.
What is going here? Do I need to change any configuration?
Apache Derby requires Java 9 from 10.15.x on which Spring Boot does currently not support.
See also spring-boot#16433.
I just want to answer with what it took me to get Derby 15.2.0 to work with Spring Boot 2.4.4 with derby in embedded mode, on top of Java 11. Spring Boot 2.4.4 works out of the box with Derby 14, although you will get some warning as spring boot starts. Upgrading apache derby to 15.2.0 fixed that for me.
In pom, both derby and derbytools dependencies defined:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.15.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbytools</artifactId>
<version>10.15.2.0</version>
</dependency>
Then in your apps properties file:
spring.datasource.driver-class-name=org.apache.derby.iapi.jdbc.AutoloadedDriver
Instead of:
spring.datasource.driver-class-name=org.apache.derby.jdbc.EmbeddedDriver
After that, I now get a good startup of Spring Boot with no warnings or anything that raises concerns.

Hibernate (4.3.11-Final) logging not bridging to log4j2?

We are migrating from log4j to log4j2. We use the following libraries and there logging mechanisms:
Tomcat (which uses JULI), Spring 4.2.0 (which uses commons-logging) and Hibernate 4.3.11-Final (which uses jboss-logging).
I have successfully got Spring bridging to log4j2, but Hibernate logging is not working.
According to the Hibernate docs:
To use JBoss Logging with Log4j2, the log4j2 jar would also need to be available on the classpath.
I have the following logging-related jars on my classpath:
commons-logging-1.2.jar
jboss-logging-3.1.3.GA.jar
jboss-logging-annotations-1.2.0.Beta1.jar
log4j-api-2.6.1.jar
log4j-core-2.6.1.jar
log4j-jcl-2.6.1.jar
log4j-slf4j-impl-2.6.1.jar
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
Any ideas why I'm not seeing the results I expect?
The version of jboss-logging included with hibernate-4 is not compatible with log4j2.
I had to import version 3.3.0.Final (should work starting with 3.1.4, according to JBLOGGING-94) for hibernate to work with log4j2.
Here is a shortcut if you use maven :
<dependency> <!-- version working with log4j2 -->
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.3.0.Final</version>
<scope>runtime</scope>
</dependency>

How to setup swagger-springmvc 0.6.5 with a Spring 3.1.2 application

I am trying to use swagger-springmvc 0.6.6 in a Spring 3.1.2 project. But when I deploy the application to Tomcat it's failing with an exception.
There seems to be a problem with versions I am using. swagger-springmvc also brings in Spring 3.2.4 jars which are conflicting with Spring 3.1.2 jars.
Error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'org.springframework.security.filterChains': Cannot resolve reference to bean
'org.springframework.security.web.DefaultSecurityFilterChain#2'
while setting bean property 'sourceList' with key [2]; nested exception is
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'org.springframework.security.web.DefaultSecurityFilterChain#2
.......
....nested exception is java.lang.ClassNotFoundException:
org.springframework.cache.ehcache.EhCacheFactoryBean
The org.springframework.cache.ehcache.EhCacheFactoryBean class is found in both Spring 3.1.2 and Spring 3.2.4.
When I try to run the app in my Local smachine its running without issues.
Could someone help me to resolve the issue?
Please refer to this sample configuration. It is a very plain vanilla setup which shows the bare minimum configuration required.
JDK 6
Tomcat 7
Spring 3.2.4
https://github.com/varoonverma/Swagger.git
Cheers,

Configuring Spring Batch with Maven

Configuring Spring Batch with Maven. JDK used: 1.6, Spring Batch version 2.1.8.RELEASE; Spring version 3.0.5.RELEASE. Getting run time exception as below:
D:\SpringProject\SpringTry\target>java -jar SpringTry-1.0-SNAPSHOT.jar jobs/helloWorld.xml helloWorldJob
2012-09-02 00:23:51,650 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - <Refreshing org.springframework.context.
support.ClassPathXmlApplicationContext#b29c9d: startup date [Sun Sep 02 00:23:51 IST 2012]; root of context hierarchy>
2012-09-02 00:23:51,769 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path
resource [jobs/helloWorld.xml]>
2012-09-02 00:23:53,854 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path
resource [launch-context.xml]>
2012-09-02 00:23:53,929 ERROR [org.springframework.batch.core.launch.support.CommandLineJobRunner] - <Job Terminated in error: Configuration
problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/batch]
Offending resource: class path resource [jobs/helloWorld.xml]
>
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler fo
r XML schema namespace [http://www.springframework.org/schema/batch]
Offending resource: class path resource [jobs/helloWorld.xml]
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
Any suggestion on how to resolve this. Also noticed that Spring 2.5.6 is getting downloaded everytime, along with version mentioned 3.0.5
My manifest looks like:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Build-Jdk: 1.6.0
Main-Class: org.springframework.batch.core.launch.support.CommandLineJobRunner
Class-Path: lib/spring-batch-core-2.1.9.RELEASE.jar lib/xstream-1.3.jar lib/xpp3_min-1.1.4c.jar lib/jettison-1.1.jar lib/spring-aop-2.5.6.jar lib/aopalliance-1.0.jar lib/spring-tx-2.5.6.jar lib/spring-batch-infrastructure-2.1.9.RELEASE.jar lib/spring-beans-3.0.5.RELEASE.jar lib/spring-context-3.0.5.RELEASE.jar lib/spring-expression-3.0.5.RELEASE.jar lib/spring-asm-3.0.5.RELEASE.jar lib/spring-core-3.0.5.RELEASE.jar lib/commons-logging-1.1.1.jar lib/spring-jdbc-3.0.5.RELEASE.jar lib/log4j-1.2.16.jar lib/maven-resources-plugin-2.4.3.jar lib/maven-plugin-api-2.0.6.jar lib/maven-project-2.0.6.jar lib/maven-profile-2.0.6.jar lib/maven-artifact-manager-2.0.6.jar lib/maven-plugin-registry-2.0.6.jar lib/maven-core-2.0.6.jar lib/wagon-file-1.0-beta-2.jar lib/maven-plugin-parameter-documenter-2.0.6.jar lib/wagon-http-lightweight-1.0-beta-2.jar lib/wagon-http-shared-1.0-beta-2.jar lib/jtidy-4aug2000r7-dev.jar lib/xml-apis-1.0.b2.jar lib/maven-reporting-api-2.0.6.jar lib/doxia-sink-api-1.0-alpha-7.jar lib/wagon-provider-api-1.0-beta-2.jar lib/maven-repository-metadata-2.0.6.jar lib/maven-error-diagnostics-2.0.6.jar lib/commons-cli-1.0.jar lib/wagon-ssh-external-1.0-beta-2.jar lib/wagon-ssh-common-1.0-beta-2.jar lib/maven-plugin-descriptor-2.0.6.jar lib/plexus-interactivity-api-1.0-alpha-4.jar lib/wagon-ssh-1.0-beta-2.jar lib/jsch-0.1.27.jar lib/classworlds-1.1.jar lib/maven-artifact-2.0.6.jar lib/maven-settings-2.0.6.jar lib/maven-model-2.0.6.jar lib/maven-monitor-2.0.6.jar lib/plexus-container-default-1.0-alpha-9-stable-1.jar lib/junit-3.8.1.jar lib/plexus-utils-2.0.5.jar lib/maven-filtering-1.0-beta-4.jar lib/plexus-build-api-0.0.4.jar lib/plexus-interpolation-1.13.jar
Most probably you are either:
simply using a version of spring-batch-core jar (Maven dependency) which has version below 2.0. Schema naming works for version 2.0 and above. If it's the case, update your dependency
or
You have the correct (higher than 2.0) version of spring-batch-core in your project's pom.xml, but you also have a transitive dependency which brings into your project an earlier version of spring-batch-core. If that's the case, try the following:
mvn dependency:tree -Dverbose -Dincludes=org.springframework.batch
this will list all the dependencies that bring in their own version of spring-batch dependencies. Add an exclude entry on spring-batch-core for those dependencies, something like this:
<dependency>
<groupId>whatever.group</groupId>
<artifactId>whateverArtifact</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
</exclusion>
</exclusions>
</dependency>
My issue was resolved by adding maven-shade-plugin as detailed in the:
https://stackoverflow.com/a/8574629/1419116

Resources