Spring MVC Jackson Exception on Payara 5 startup - spring

My application is using the following:
JDK version: Open JDK jdk-11.0.11+9 Payara : 5.2021.5 Spring version: 5.2.7.RELEASE jackson version: 2.9.4.
Payara 5.2021.5 uses Jackson version 2.10.2, whereas the application uses Jackson version: 2.9.4. It looks like the method signature for some Jackson methods used by SpringMVC has changed in Jackson 2.10.2.
On Server startup, the following Exception is thrown:
Details: Location: org/springframework/http/converter/json/Jackson2ObjectMapperBuilder$XmlObjectMapperInitializer.create
(Lcom/fasterxml/jackson/core/JsonFactory;)Lcom/fasterxml/jackson/databind/ObjectMapper; #15: areturn Reason: Type 'com/fasterxml/jackson/dataformat/xml/XmlMapper' (current frame, stack[0]) is not assignable to 'com/fasterxml/jackson/databind/ObjectMapper' (from method signature)
I tried disabling class loading hierarchy locally by setting element in the glassfish-web.xml as well as globally, by setting system property fish.payara.classloading.delegate to false in domain.xml
I also tried adding the following to web.xml as suggested in documentation, as well as the init parameter to DispatcherServlet, but does not seem to help-
<context-param>
<param-name>jersey.config.jsonFeature</param-name>
<param-value>JacksonFeature</param-value>
</context-param>

tried disabling class loading hierarchy locally by setting element in the glassfish-web.xml. It looks like Payara ignores this flag and continues to load the libraries in \payara-5.2021.5\payara5\glassfish\modules, instead of loading from the application. I even tried by replacing glassfish-web.xml with payara-web.xml
The issue resolved by setting system property fish.payara.classloading.delegate to false in domain.xml.

Related

Upgrading to Springboot 3: 'org.springframework.hateoas.server.LinkRelationProvider' that could not be found

I am upgrading my springboot app from 2.7.x to 3.0.0, I have made required changes for jakartaEE. When starting my app I am getting the below error
{"#timestamp":"2023-01-03T15:28:01.149Z","#version":"1","message":"\r\n\r\n***************************\r\nAPPLICATION
FAILED TO
START\r\n***************************\r\n\r\nDescription:\r\n\r\nParameter
1 of method collectionModelContentConverter in
org.springdoc.core.configuration.SpringDocHateoasConfiguration
required a bean of type
'org.springframework.hateoas.server.LinkRelationProvider' that could
not be found.\r\n\r\n\r\nAction:\r\n\r\nConsider defining a bean of
type 'org.springframework.hateoas.server.LinkRelationProvider' in your
configuration.\r\n","logger_name":"org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter","thread_name":"main","level":"ERROR","level_value":40000}
I am using hateos lib for representation in my app, Also I am using springdoc-openapi-starter-webmvc-ui for swagger UI.
When I disable configuration for api-docs springdoc.api-docs.enabled=false the above error go away but my swagger page is also gone, which definitely means this is not the solution.
Could someone please guide me why this bean is not getting found with springboot 3 while it was all working before with springboot2.7.x and java-11.
here is my pom.xml https://gist.github.com/bruce2019/c93a16dc20f7edb7d922b1e284f39d15
Thanks in advance
You can use springdoc-openapi-starter-webmvc-ui with 2.0.2 version
Add "/v3/api-docs/**" to mvcMatchers in WebSecurityCustomizer

How to launch spring boot application with cloud-bus via custom auto-configuration?

Some time ago I found out that my spring-boot application had been launching slowly via #EnableAutoConfiguration. Then I decided to create custom configuration to speed up a process. I tried to #Import all needed configurations and I faced with issue of unknown beans:
Description:
Parameter 0 of method streamBusBridge in org.springframework.cloud.bus.BusStreamAutoConfiguration required a bean of type 'org.springframework.cloud.stream.function.StreamBridge' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.cloud.stream.function.StreamBridge' in your configuration.
It seems that I've already used all cloud-bus configurations:
PathServiceMatcherAutoConfiguration.class,
BindingsEndpointAutoConfiguration.class,
BusAutoConfiguration.class,
BindingServiceConfiguration.class,
BindersHealthIndicatorAutoConfiguration.class,
ChannelsEndpointAutoConfiguration.class,
BusRefreshAutoConfiguration.class,
FunctionConfiguration.class,
BusStreamAutoConfiguration.class,
BusJacksonAutoConfiguration.class
What should I add to launch my application via custom auto-configuration?
Spring-boot: v2.6.6
Spring-cloud-bus: v3.1.2
Java: 17

About map properties to java class in spring boot 2

I want to convert properties to map, see below
field2ZhNameMap.platform=平台
==>
private Map<String,String> field2ZhNameMap;
In Spring boot 1.5.6 start the app in tomcat it's OK, but use sprint boot 2.0.0.M7 start the app in tomcat I got below error
Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under '' to com.foo.bar.util.Field2ZhNameProperties
at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:227)
Caused by: java.lang.IllegalArgumentException: PropertyName must not be empty
at org.springframework.util.Assert.hasLength(Assert.java:233)
at org.springframework.boot.origin.PropertySourceOrigin.<init>(PropertySourceOrigin.java:41)
After debuging source code I found start the app in tomcat it has a JndiPropertySource which caused above problem. So I have to explicitly disable JndiPropertySource by specify spring.jndi.ignore=true in a spring.properties to solve this problem.
In addition I found these classes like Binder do not exist in 1.5.6, it seems it has a big change from 1.5.6 to 2.0.0. So I want to know if has some documents record these change and guide how to correctly map properties to java class in spring boot 2?
For me, upgrade to Spring Boot 2.0.1.RELEASE on Tomcat 8.5.30 resolved PropertyName must not be empty

Websphere 8.5 with Spring-5

Is Websphere 8.5.5 compatible with Spring 5? The Validation API referenced in spring5 (validation-api 5) is resulting in MethodNotFound exception.. Any pointers/patch available to get this solved - short of upgrading to Websphere 9?
Caused by: java.lang.NoSuchMethodError:
javax/validation/Configuration.getDefaultParameterNameProvider()Ljavax/validation/ParameterNameProvider;
(loaded from
file:/opt/IBM/WebSphere/AppServer/plugins/javax.j2ee.validation.jar by
org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader#25d460de)
called from class
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
(loaded from file:../spring-context-5.0.2.RELEASE.jar by
com.ibm.ws.classloader.CompoundClassLoader#1c7dbdd9
The method javax/validation/Configuration.getDefaultParameterNameProvider was added in Bean Validation 1.1, so that indicates the Spring Validator you are using is attempting to use the Bean Validation 1.1 API. According to https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.html:
As of Spring 5.0, this class requires Bean Validation 1.1+
WebSphere 8.5.5 provides Bean Validation 1.0 and did not add support for Bean Validation 1.1 until version 9.0. So, you'll either need to use Spring 4.x or WebSphere 9.x.
The above answer is not correct. You can run Spring 5 in WebSphere 8.5. This may not be the perfect solution for your situation, but this will get you on the correct path.
1.) Provide your Bean Validation 1.1 JAR
Here is a sample of the Maven dependency.
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
2.) Add the following a deployment.xml file to the following location in your EAR file.
/myAppEAR/META-INF/ibmconfig/cells/defaultCell/applications/defaultApp/deployments/defaultApp/deployment.xml
3.) In the contents of your deployment.xml file, you must set the classloaderMode to PARENT_LAST. You must also modify this code to use the correct WAR file name.
Here is a sample...
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1422578178899">
<deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1422578178899" startingWeight="10" warClassLoaderPolicy="SINGLE">
<modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1422578178899" startingWeight="10000" **uri="myApp.war"** **classloaderMode="PARENT_LAST"**/>
<classloader xmi:id="Classloader_1422578178899" **mode="PARENT_LAST"**/>
</classloader>
</deployedObject>
</appdeployment:Deployment>
#rob-breidecker is correct, this is possible even though WebSphere 8.5.5 provides Bean Validation 1.0. To do this, you need to change the classloader of your application.
To do that via the UI, go to Applications -> WebSphere enterprise applications -> Your Application -> Class loading and update detection and change the Class loader order to be Classes loaded with local class loader first (parent last). This "causes the class loader to attempt to load classes from its local class path before delegating the class loading to its parent.".
If you are deploying an EAR and want this change to propagate to inner applications, you can either change WAR class loader policy to Single class loader for application or change the class loader of the individual war (in the EAR click Manage Modules -> Your Module then change Class loader order).
As long as you provide a version of validation-api (I used 2.0.1.Final), you should get passed the above issue.
The following wasadmin.sh script will apply the above settings (replace app_name with the name of your application): (credit)
dep = AdminConfig.getid('/Deployment:app_name/');
depObject = AdminConfig.showAttribute(dep, 'deployedObject');
AdminConfig.modify(depObject, [['warClassLoaderPolicy', 'SINGLE']]);
classldr = AdminConfig.showAttribute(depObject, 'classloader');
AdminConfig.modify(classldr, [['mode', 'PARENT_LAST']]);
I though at some point it was impossible to do this, but finally, I found a solution, you can use spring 5.X and Boot 2.X with WebShpre 8.5 using the below Steps, just make sure that you project is compatible with:
1- Bean Validation
2- Servelt 3.1
Steps:
1- Create a custom folder on you server for example /opt/custom/lib/spring5 and upload below jars to this folder
a. jakarta.el-3.0.4.jar
b. jakarta.validation-api-2.0.2.jar
2- Create a new shared library in WebSphere as below
a. Go to environment -> shared library
b. Chose the scope to node and server
c. Click on New and fill the value with below
i. Name: spring5
ii. Class path: /opt/custom/lib/spring5
iii. Enable checkbox “use an isolated class loader for this shared library”
3- Restart the server
4- Go to Enterprise Application Click on the application (WAR/EAR)
5- Go To shared library reference add assign it to you application (WAR/EAR)
6- Go to Enterprise Application Click on the application (WAR/EAR)
7- Choose Classes loaded with local class loader first (parent last)
8- Restart the server
In case someone still needs a solution, the only way it worked for me was to change the file https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.html
from 5.x to use the logic from 4.x

filter-name element is missing in generated web.xml

One of our old applications uses Struts-1.2 and EJB-2, generated with xdoclet 1.2.3. Maven 1 is used to build the application using java 1.4. The application has been running in weblogic 8.1 without any issues.
Now we are upgrading to Weblogic 10.3.6 which runs on java 6. When the application is deployed to Weblogic 10.3.6 we encounter the following error.
The error is weblogic.descriptor.DescriptorException: VALIDATION PROBLEMS WERE FOUND problem:
cvc-minLength-valid.1.1: string length (0) is less than minLength facet (1) for filter-nameType
in namespace http://java.sun.com/xml/ns/javaee:<null>
I understand this error is because the web.xml file is missing the filter-name element for a Filter class.
The problem is web.xml is generated by the application as part of the build process and I have no idea where or how to add the filter-name element value. What should I do to get the filter-name element to be added to the generated web.xml?
(Note: There is no problem when deployed to Weblogic8.1. This happens only when trying to deploy on weblogic10.3.6.)
Any help will be much appreciated.
Thanks.
Got it going.
I had to add the following annotation to the filter class...
#web.filter name="FilterClassName"
web.xml generated the filter-name element after I added the above annotation.

Resources