Diagnose NoClassDefFoundError during Spring Boot when class is available to ClassLoader - java

I have a Java/Maven project (POM-based) which builds and launches fine when using java -jar on the uber JAR produced by my Maven build on the command line, using the spring-boot-maven-plugin:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.3.RELEASE</version>
<configuration>
<mainClass>com.company.Application</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
The JAR is created (~100MB), and launches as expected.
However, I'm unable to launch this same application in Eclipse using the right-click -> Run As -> Java Application configuration on the main class I've defined in my POM. It's a Maven project, and M2E is up-to-date/refreshed, etc.
The error is:
java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.LoggerFactory
So clearly some dependency issues with the logging frameworks. However: My first head-scratcher was, why does this work in Maven using the CLI, and fail in Eclipse using M2E?
So I went and looked at the classpaths, and they seem identical. (Looking at the Maven Dependencies list in Eclipse, and the BOOT-INF directory contained in my uber JAR.) The interesting bits are:
slf4j-api 1.7.25
log4j-over-slf4j 1.7.25
logback-core 1.2.3
logback-classic 1.2.3
commons-logging 1.1.3
So, I debugged. I placed a breakpoint on NoClassDefFoundError, and captured this. Note that the debugger is paused on the thrown exception, and the watch expression in the upper-right is getClass().getClassLoader().classes, which is a Vector.
How is it possible that we're throwing on LoggerFactory, even though this very class is present in the current ClassLoader? Where should I look next?
Edit: Since it's causing some confusion, the class in which Eclipse has caught this error (Category.java) is not one of my classes. It's inside a dependency (see Eclipse titlebar) and as a result cannot be modified.

Related

How to link StepDefination classes from Classpath (jar) in Cucumber IntelliJ Plugin

I would like to use existing step definition classes coming from maven jar dependency.
My cucumber tests works if ran from Runner Class (with glue to packages) & mvn CLI. But the
problem is with IntelliJ Cucumber plugin for the steps which are coming from jar. In feature file steps that I am using from the jar are shown as "Undefined step reference:...". I am not even able to run directly from feature file.
Is there a way I can configure cucumber plugin to use stepdefinations from classloader/jar?
Posting the solution worked for Me:
Use IntelliJ 2020.1 +
In cucumber run configuration : select jar manifest for classpath
Deploy the Jar with source jar as well to Nexus as below
You can simple do this by adding maven-source-plugin plugin to your build
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
In other project add dependency and confirm source is downloaded from repo
File -> Project Structure -> Libraries -> Select the Artifact -> Sources , Make sure it's not in red.
Update IntelliJ to use latest version, for me IntelliJ version 2019 did not work but 2020.1 was able to find the step definitions.
PS: I use Java8 with Lambda exp and I can confirm it works.
Updating Intellij from version 2019.3 to 2022.2 solved the issue without changing anything else.
My project is in Java 8

How to fix NoClassDefFoundError on SpringApplication (Pivotal)

I've built a SpringBoot 2.1.5.RELEASE application using STS. Runs fine from STS. Dependencies downloaded into my .m2. Everything looks OK so far.
This application is packaged as a jar. I added main class using pom property. Manifest looks OK.
Now, I push this to Pivotal. It picks up java_buildpack_offline and appears to be installing but dies with
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication.
I'm new to cloud, so I'm hoping I'm missing a step somewhere. It just doesn't feel right to package a war with dependencies in the /lib folder. What would be the next step in sorting this out? Is there a dependency I need to include that specifically handles SpringBoot on cloud?
It seems that your jar file is not executable. For fixing it try to add the spring-boot-maven-plugin plugin, I hope it will help:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
...
</plugins>
</build>

Cannot compile with maven while importing a local project as dependency

I'm creating a common library that will be used accross several Spring application. I've extracted the common classes I want to share between these application into a new Spring application named "Common". I've used mvn install on this application to put it in my local maven repository. On my main project, I've added the maven dependency, with the same version, in the pom.xml.
Now, if I try to launch mvn compile on my main project, I got this error :
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project recruitment: Compilation failure: Compilation failure:
[ERROR] /D:/[...]/application/src/main/java/com/example/application/service/Service.java:[8,37] package com.example.common.exception does not exist
Indicating that my common library is not present and thus my application cannot find package coming from it.
If I try to launch my Spring application from the main (using Spring Boot), it launchs perfectly and behaves like before.
I'm using IntelliJ on Windows, maven is bundled with IntelliJ with the default installation. If I check in my local maven repository I can find the common library jar. IntelliJ does not show any error on my imports, it recognizes my library.
There seem to be some conflict between IntelliJ, which read the pom.xml to find libraries imported for my application, and maven that use the same pom.xml to compile my code.
I used mvn compile -X to have more information and the funny part is that maven is using the common library jar from the local repository :
[INFO] Changes detected - recompiling the module!
[DEBUG] Classpath:
[DEBUG] D:\[...]\application\target\classes
[DEBUG] C:\[...]\.m2\repository\com\example\common\0.0.1\common-0.0.1.jar
Do you have any idea why I can't compile my project with maven while
I can launch it as a Spring application ?
Here is my dependency in my pom.xml :
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
</dependency>
And the common library definition :
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>0.0.1</version>
<name>common</name>
<description>Common project with generic technical modules</description>
Okay, that's embarassing... I just found the solution ! It has been two days looking for a solution to this tricky situation and I just found what was missing, or rather what was too much.
This bad boy :
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
The Spring boot maven plugin is what makes my Spring boot application launchable from maven, and it seems that it affects the way the common jar library is made, or the way it is imported.
I don't really understand why exactly it affects my import, but I deleted the plugin above in my common library pom.xml, I reinstalled in my local repository and I launch mvn install again on my main application... And it now works !
I think that launching via Spring boot used a little bit of Spring boot magic to make it works that the maven way lacks.
If someone understands it better and can explain it, that would be great and the accepted answer I think.
The reason for that is that application classes are packaged in BOOT-INF/classes so that the dependent module cannot load a repackaged jar’s classes
Proper config will look like:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.1.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Taken from
https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/html/#repackage-examples

How to configure MuleSoft with Maven?

I am trying to create my first MuleSoft application using Maven. I have used CMD to confirm that both Java and Maven are installed. I've also configured my environment variables.
I then open the MuleSoft Anypoint Studio, and create my first named "mulesoft-sample" I select to use Maven, and leave all default settings as they are.
Once I click finish, the Console begins to download a number of files
These continue to be downloaded until after it would seem the near end of the files, it throws an error:
There was an error running the studio:studio goal on project mulesoft-sample
In Console, I see the errors listed below.
I was originally trying to use the latest version of Maven (3.5.0). However, I found a video tutorial that said 3.3.9 was a verified version for MuleSoft. So I thought perhaps the newest version wasn't supported and instead used 3.3.9. However, it is still failing. I've also tried changing the environment variable to other options, such as going straight to \bin, rather than the complete directory (taking shots in the dark here). Unfortunately, nothing has worked and I'm running out of option.
Can anyone tell me why I'm getting these errors, and my build will not succeed? How to correct the error?
In anypoint studio go on windows>prefernces.then click on java>installed JREs. and add your Java JDK folder and note that only JDK, not JRE. then you can test your maven
This error occurs when the right java is not pointing with Anypoint Studio . In the studio navigate to windows > preferences the search java. Make sure jdk is selected and not jre . If still problem continues try updating your java and reinstalling maven .
Download the latest maven on your local machine, then goto anypoint
studio windows->preferences->anypoint studio->maven
provide the maven path and click Test Maven configuration(green
check mark obtained if the URL is properly provided)
Mule Maven Plugin configuration.
1.1. Use mule mule-app-maven-plugin to build the application.
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-app-maven-plugin</artifactId>
<version>${mule.tools.version}</version>
<extensions>true</extensions>
<configuration>
<copyToAppsDirectory>false</copyToAppsDirectory>
</configuration>
</plugin>
No need for additional Mule Maven plugins.
This is the default mule plugin set when creating your Mule project on AnyPoint (AP) Studio.
1.2. Make sure you set flag copyToAppsDirectory to false.
This flag is set to true by default so you must change it manually.
Maven Dependency Plugin Configuration.
2.1. Now we need to add a plugin to copy the generated artifact to the MULE_HOME/apps directory, i.e. to deploy the application to the standalone local mule server.
We will use the maven-dependency-plugin.
Just add these plugin after the mule maven plugin section in your application pom.xml.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy</id>
<phase>deploy</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.mule.support.ba</groupId>
<artifactId>bonmarche-case-00145615</artifactId>
<version>1.0.0</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>C:/mule-home/apps</outputDirectory>
<destFileName>bonmarche-case.zip</destFileName>
</artifactItem>
</artifactItems>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
2.2. Update the attributes within the tag (in grey) with the corresponding values on your environment.
2.3. As you see in 2.1, we are configuring the deployment to apps folder on Maven 'deploy' phase. You may choose a different phase to copy the artifact, but it must be bound to any phase after the package phase, so that the artifact exists in the repository.
Disable the default execution of Maven Deploy Plugin to prevent deploying the generated artifact to an external repository. This may be changed depending on your project needs.
Add this plugin after maven-dependency-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
Build your application and verify the generated ZIP file is copied to MULE_HOME/apps directory.
$> mvn clean deploy
I have faced same issue and got resolved by changing the JRE to JDK in preferences==>java==>Installed JRE's there change to JDK and restarted the any point studio. This resolved the issue to me.

Not able to start Tomcat for MAven Project inside Eclipse

Not able to start Tomcat for maven project in Eclipse I am getting:
java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.FilterDispatcher
while starting tomcat.
the same is working outside eclipse(making the war and deploying in Tomcat)
Can any one suggest what to do?
My answer will be slightly off-topic but If I dare, I really recommend using jetty and using hot deployment in a separate process, not to launch it from within maven, but as a real server in /etc/init.d. Then you could deploy your app easily with an external script, activable from within eclipse, that will do a hot deploy of context in jetty.
It takes time to get this config but it's the fastest I have found and uses much less memory than using jetty within eclipse, and much much less than using tomcat. Hot deploy is also quite interesting in jetty.
You build cycle will look like
edit / save from eclipse
build / package through maven from eclipse (eclipse indigo is a charm for that)
deploy your app in jetty through a external tool script from eclipse.
Regards,
Stéphane
It has to do with tomcat looking for those classes in src/main/webapp/WEB-INF/lib, You can add the dependency plugin to your pom.xml like this.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>src/main/webapp/WEB-INF/lib</outputDirectory>
</configuration>
</plugin>
This plugin will copy all the pom dependencies to WEB-INF/lib and tomcat can find all the jars when you it out of workspace

Categories