Spring tool application failed to start - java

Anyone know how to solve below issue?
The following method did not exist:
'void
org.apache.catalina.Context.addServletContainerInitializer(javax.servlet.ServletContainerInitializer,
java.util.Set)'
The calling method's class,
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory,
was loaded from the following location:
jar:file:/C:/Users/Janice/.m2/repository/org/springframework/boot/spring-boot/2.7.6/spring-boot-2.7.6.jar!/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.class
The called method's class, org.apache.catalina.Context, is available
from the following locations:
jar:file:/C:/Users/Janice/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/10.1.4/tomcat-embed-core-10.1.4.jar!/org/apache/catalina/Context.class
The called method's class hierarchy was loaded from the following
locations:
org.apache.catalina.Context: file:/C:/Users/Janice/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/10.1.4/tomcat-embed-core-10.1.4.jar
Action:
Correct the classpath of your application so that it contains
compatible versions of the classes
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
and org.apache.catalina.Context
I expected to upgrade version for tomcat-embed-core to version 10.1.4
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>10.1.4</version>
</dependency>

You cannot deploy Spring Boot 2.7.x or lower to Tomcat 10, because Spring Boot 2.7 uses Jakarta EE 8, which uses the javax.* namespace, while Tomcat 10 is Jakarta EE 9 or higher, which uses the jakarta.* namespace. This is a big breaking change in the Java world, and you cannot just mix and match incompatible dependencies.
You either need to upgrade to Spring Boot 3, or you need to downgrade to Tomcat 9.
Also, in this case, you should let Spring Boot control the version of tomcat-embed-core, and not specify the version yourself. Spring Boot 2.7.7 specifies tomcat-embed-core 9.0.70 (search for tomcat-embed-core), while Spring Boot 3.0.1 specifies tomcat-embed-core 10.1.4. Don't try to change it yourself, especially not to incompatible version. Changing to different minor or patch versions will usually work, but should generally not be done either because it increases your maintenance overhead, where otherwise you'll only need to increase the Spring Boot version to receive new compatible dependency versions.

Related

Liberty Websphere cannot load javax.transaction.Transactional when using java 11

After updating to Java 11 we get the following message:
[4/3/20, 11:47:09:184 CEST] 0000002d com.ibm.ws.classloading.internal.util.FeatureSuggestion I CWWKL0084W: The javax.transaction.TransactionManager class could not be loaded. Try enabling the jdbc-4.0 feature or a newer version of the feature in the server.xml file.
We are already using jdbc-4.3 (had the same message on 4.2 as well). The application itself does not give any errors that I can see. The application is made with maven that has the compile plugin configured with 11.
There are no problems when compiling and running tests for the application on java 11, and this only appears when deployed to liberty. Should we explicitly include a dependency for this in the war, or is this an issue that should be fixed in liberty?
From later releases on, Java EE is not included any more. The transaction classes are in the javax.transaction package.
Adding the following dependency should solve it:
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
(Not sure if it helps with your deployment, but it works with Spring Boot 2)

Maven dependency with older spring boot version

Is it somehow possible to use Maven dependency with older Spring Boot version? The project is using version 2.x and the custom dependency uses 1.5.x.
Could not found any documentation on the topic.
I'm asking because of getting a NoClassDefFoundError while introspecting class inside the custom jar file.
No. Spring Boot 2.X is a major version which is not backwards compatible with Spring Boot 1.5.X. Same goes for major Spring Framework versions, you can't mix Spring Framework 5.X and 4.X.
Maven only manages project dependencies. It has nothing to do with your problem.
Basically there can only be one version of any given combination of groupId and artifactId in any maven project. So with plain vanilla maven, the answer is 'No'. But there is the maven-shade-plugin that can be used to change the group- and artifact ids of any dependency.

java.lang.IllegalArgumentException: Jetty ALPN/NPN has not been properly configured

Getting java.lang.IllegalArgumentException: Jetty ALPN/NPN has not been properly configured, while using gRPC(google pub/sub) to publish/consumes messages from Kafka.
Try adding a runtime dependency on netty-tcnative-boringssl-static. See gRPC's SECURITY.md. Note that the version of netty-tcnative necessary changes over time; you should look at the version of the document for a particular release (e.g., this is for 1.2.0).
Finally, went back to boot class class path approach. Prefixed the jetty-alpn.jar to boot class path and it starts working fine in cloud foundry now.
Adding the ALPN client JAR which matches my JDK version fixed this issue for me. In eclipse, you need to set up the jar as a bootstrap entry for the tomcat server.
You can find more info about it here : https://medium.com/#Parithi/jetty-alpn-npn-has-not-been-properly-configured-solution-418417ee6502
As suggested by google, use jetty container instead of tomcat, this solution works, but in our production, applications deployed on tomcat container, but of course I need it to work on tomcat in production.
On debugging the gRPC code, found that guava version causing the issue, updated the guava version 18.0, (where in some classes missed in previous versions), solved the problem , but failed while deploying in CF
Customized emebed-tomcat-core, and it works fine consistently, but again, team say no to custom tomcat container.
Java –jar apm-asset-xxxx.jar – works fine locally, but need to provide a custom command to CF start, didn’t have luxury to change the CF start process.
Finally, trick, the class loader to use tcnative-boring-ssl, library instead of tomcat-core library at runtime, by providing the following dependency in pom.xml. For the past 3 days, this solution is working CF.
org.springframework.boot
spring-boot-starter-web
org.hibernate
*
org.apache.tomcat.embed
tomcat-embed-core
org.apache.tomcat.embed
tomcat-embed-core
provided
Maven manifest plugin to promote the tc-native library to the top in the classloader.
In POM, try to place the gRPC dependency before the spring boot dependency (the order of dependencies matters). I did that and the issue was solved. For example:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-language</artifactId>
<version>0.13.0-beta</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot dependencies and security fixes

im using spring boot in a recommended way, that is by adding
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
and then adding dependencies i need, like:
compile('org.springframework.boot:spring-boot-starter-web')
That dependency pulls some predefined version of tomcat that will host my microservice.
but what happens when there is a security fix for tomcat released? does spring team track all the security issues in all the project they use and bump spring-boot version when new fix is released? or do i have to track it by myself and control dependencies (like tomcat) manually instead of using 'the spring-boot way'?
Whenever we release a new version of Spring Boot, we update the managed dependency versions to the latest appropriate release of that dependency. Appropriate means that we won't, for example, move to a new major or minor version of a dependency in a maintenance release of Spring Boot.
Generally speaking, a new version of a managed dependency (even if it contains a security fix) won't trigger the release of a new version of Spring Boot. It's impossible for us to know exactly how a dependency is being used and if the fix is relevant to all, some, or even any of Spring Boot's users.
This means that you do need to keep track of security vulnerabilities yourself. If a vulnerability affects you and Spring Boot has not yet updated its managed version then you can easily override that version in your build script. For example, if you are using Gradle:
ext['tomcat.version']='8.0.36'
Or Maven:
<properties>
<tomcat.version>8.0.36</tomcat.version>
</properties>

Provided dependency in library, using previous version in project

If a library declares provided dependency on eg servlet-api using v3.0.1; would it be possible for users to use version 2.5 for their library, that will be used on third party web application?
In other words:
mylib (srv 3.0.1) <-- some_framework(srv 2.5) <-- user_webapp (tomcat 6 or 7)
Moreover: v2.5 is declared as javax.servlet:servlet-api:2.5 and version v3.0.1 is declared as javax.servlet:javax.servlet-api:3.0.1, so there is a difference.
Would it be a problem for some_framework to specify different servlet-api dependency (eg 2.5) than defined as provided in mylib (eg 3.0)? I assume that since scope is provided (and available only in compile time), dependency tools (mvn, gradle...) will not download it in some_framework, and they have (and are allowed) to declare dependency manually.
(yeah, i am aware of differences between 3.0 and 2.5, and that is not a question. I also assume everything compiles correctly, etc. I am just interested how maven would compile some_framework, on which dependency: 2.5 or 3?).
Let me answer my own question, as [SO] never helped with tricky ones:)
I created simple maven project (that will act as some_framework). It depends on jodd-servlet (mylib), that has servlets 3.0.1 listed as provided dependency. When I run
mvn dependency:resolve
i do not see servlets in the list of dependencies. Now, if current project (i.e. some_framework) lists servlets v2.5 as dependency; and then if I run the same command again, I see only dependency on 2.5.
Therefore, we may say that provided dependencies are not transparent or exported.

Categories