Invalid web-app-versionType after Spring Upgrade - spring-boot

To support JUnit 5, I recently upgraded a Spring Boot application to version 2.4.7.
Local development uses an embedded Tomcat server, while all other environments run on a Weblogic server 12.1.3.
Everything runs locally, but using the Weblogic Server results in the following exception:
Caused By: weblogic.descriptor.DescriptorException: VALIDATION PROBLEMS WERE FOUND
/weblogic.utils.classloaders.GenericClassLoader#700d06bb finder: weblogic.utils.classloaders.CodeGenClassFinder#40ce7cdd annotation: APP#/WEB-INF/lib/tomcat-embed-websocket-9.0.46.jar!/META-INF/web-fragment.xml:18:3:18:3: problem: cvc-enumeration-valid: string value '4.0' is not a valid enumeration value for web-app-versionType in namespace http://xmlns.jcp.org/xml/ns/javaee
at weblogic.descriptor.internal.MarshallerFactory$1.evaluateResults(MarshallerFactory.java:249)
Other questions on the topic led me to check web.xml, but it contains version="3.0".
I don't know how to proceed because I don't understand where this comes from.

Do you have this in your pom.xml to exclude packaging of the tomcat jar files when creating the war file?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
The spring-boot-starter-tomcat dependencies must have provided scope.

Related

Upgrading To Spring Boot 2.4.0 Breaks Legacy Applications

I'm upgrading a set of legacy applications to Spring Boot 2.4.0, running on OpenJDK 8, deployed to Pivotal Cloud Foundry.
The app and all its unit tests ran perfectly under Spring 2.3.4-RELEASE before I started this upgrade.
There was work to be done right off the bat: Spring Boot 2.4.0 brings in JUnit 5.x, so I had to fix all the JUnit 4.x tests to use the new annotations and classes.
After fixing all the tests I tried to run in IntelliJ 2020.2. All the tests failed, for the same reason: java.lang.IllegalStateException: Failed to load ApplicationContext. The root of the stack trace gives this cause:
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata
They removed a fundamental class from Spring Boot for the sake of Kubernetes, from the sound of it. I'm not sure I see why.
I did a Google search and found this explanation and fix.
I added spring.config.use-legacy-processing to my application.yml and a test application.properties file:
spring:
config:
use-legacy-processing: true
Still no joy - all the tests fail.
I'm confused by other links I've seen. Is this an issue with spring-cloud-dependencies? I'm reading that there might an issue with the Hoxton version. Do I need to add it to my app? It never needed this dependency before the upgrade:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
The problem is bigger than the tests. If I ignore them and try to run the app I still fail:
ERROR [main]: Application run failed |ApplicationName=Risk_Advisor | sourcedfrom=ERROR
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configurationPropertiesBeans' defined in class path resource [org/springframework/cloud/autoconfigure/ConfigurationPropertiesRebinderAutoConfiguration.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.context.properties.ConfigurationPropertiesBeans] from ClassLoader [sun.misc.Launcher$AppClassLoader#18b4aac2]
The root cause is the same:
java.lang.NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
when ever you do upgrades on spring, pls always look at the spring / cloud compatibility matrix and then upgrades the versions for both spring and cloud accordingly:
Also, pls note that you may not have added spring cloud as direct dependency but it may be coming into your final jar as a transitive dependency so its always better to add below spring cloud dependency as direct dependency management in your pom to stay away from any conflicts:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I got the same error when migrating to Spring Boot 2.4.4 which forced me to migrate to Spring Cloud 2020.0.1 as well. In my case, the error was due to Bootstrap, provided by spring-cloud-commons, not being any longer enabled by default. I had to re-enabled it by adding the following new starter in my build.gradle file as stated here:
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
You say your app doesn't use Spring Cloud, so I'm not sure why you ended up facing which seems to be the same issue. Hopefully this workaround might work for you and help out others using Spring Cloud.
To fix the failing JUnit 4 tests, I have just added it as a dependency:
testImplementation 'junit:junit:4.13'
I had the same error for JUnit 4 tests after migration my project to Spring Boot 2.5.6. Adding JUnit 4 dependencies did not fix this error as well as migration JUnit 4 tests to JUnit 5. My project does not define Spring Cloud dependencies in build.gradle so in order to find where those dependencies come from I simply ran gradle command:
gradle dependencyInsight --dependency org.springframework.cloud
and saw that spring cloud dependencies were pulled within one of the custom libraries. Upgrade spring cloud dependencies to a compatible version there and reimport custom library fixed the error.

Spring Boot app starts on Windows 10 but not on OS X (HS)

I have a Spring Boot application that connects to a postgresql-database. I am working on it on windows 10 (work) and macos (home). The code is shared via github. On win10 the app starts without any problems but when I update the code on macos and restart the app I often get the error Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class
The one way I can remedy the issue is to include the H2 in-memory-db in pom.xml, start the app, remove it again and restart the Spring Boot app. But it doesn't always work.
My application.properties file:
spring.datasource.url=jdbc:postgresql://localhost:5432/john
spring.datasource.username=doe
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
I am using Java JDK 10 in both environments with the Spring Tools suite in eclipse.
I have cleaned the project, updated maven right-clicking on the project -> Maven -> Update Project but without luck.

Weblogic 12.2.1 + Java 8 + Spring Data JPA + Hibernate 5.x Deployment conflict

I am trying to deploy an EAR file using WebLogic 12.2.1 with Hibernate 5.x and Spring-data-jpa 1.9.4. The same configuration deployed fine on Weblogic 12.1.3. JPA 2.1 is used on both of them.
Weblogic is throwing a ClassNotFoundException and looking for the QueryDsl library which is optional with spring-data:
weblogic.management.DeploymentException: java.lang.ClassNotFoundException: com.mysema.query.types.path.PathBuilder
The manifest for Spring-data even references this jar as optional. Since Oracle publishes none of their source I can't exactly debug the problem .. it seems to throw an error long before my ApplicationContext actually initializes any of the Spring wiring.
The same configuration deploys fine on Websphere 8.5.5. There seems to be some kind of deployment conflict with using Weblogic 12.2.1 but I can't spot any other meaningful differences. Is anyone experiencing something similar?
I managed to overcome this error by explicitly adding querydsl-core and querydsl-jpa to my poms.
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
</dependency>

How is a war file created for spring boot with maven?

I'm trying to follow the guide for converting a spring project to a war.
http://spring.io/guides/gs/convert-jar-to-war/
It starts out using maven and gradle and then right after the jar portion it completely forgets about maven and only has gradle updates.
There are two main changes that you need to make in the pom. The first is to change the project's packaging type to war:
<groupId>org.springframework</groupId>
<artifactId>gs-convert-jar-to-war</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
The second is to add a dependency on spring-boot-starter-tomcat and mark it as provided:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
mvn package will now produce a war file that can be run using java -jar or deployed to a separate servlet container.
There is an official guide at spring:
http://spring.io/guides/gs/convert-jar-to-war-maven/
Pay attention to "Initialize the servlet" section.
It explains an important point of adding a class that substitutes web.xml. Without it (or without proper web.xml) you will get a war file but when deployed nothing will be accessible in browser as nothing will be registered as your request dispatcher.
Also note that it is best to run this example on Tomcat 8 as it supports latest servlet specs. I have spent number of hours trying to figure out why it does not work on my Tomcat 7.

Setting javax.xml.ws.Service from JDK, instead of javaee-api with maven

I'm facing with this problem:
The method getPort(QName, Class<T>) in the type Service is not applicable for the arguments (QName, Class<AcessoDadosGeolocalizacao>, WebServiceFeature[])
I used wsimport to generate my clients, but now my maven application is using the class javax.xml.ws.Service from
<dependency>
<groupId>javaee</groupId>
<artifactId>javaee-api</artifactId>
<version>5</version>
<scope>provided</scope>
</dependency>
How can I use the javax.xml.ws.Service from the JDK 6?
I've added the webservices-api to my pom.xml and the problem is gone.
<dependency>
<groupId>javax.xml</groupId>
<artifactId>webservices-api</artifactId>
<version>2.1-b14</version>
</dependency>
If I am adding this entry(webservices-api) ;it is giving run time error while accessing JAXB-API.I found that the JDK6 should be the first in the order of classpath and then maven library.I moved up the JDK6 above the Maven library.Then it worked.
I ran into a similar issue with Eclipse and a Dynamic Web Application. Its not Maven related however googling for that error gets you all of about 7 results in Google as of today's date with about three or more of them being relisting at other websites of the same stack exchange question - so I thought in case others had a similar issue I'd add what helped me. The WAR was set to use JBoss AS5, the VM was set to use Java 6. Because its eclipse and I had already consumed the web service - the error was not occurring on import as the stubs had already been created. I ensured the Java facet was set to use 1.6 (it had been 1.5), I cleaned and built but the error persisted. I then noticed I had a reference on my build path to Java EE 1.5. I removed this, cleaned and built and the error went away.
Hope this helps anyone else faced with the same issue!

Resources