Maven shade IllegalStateException - Required class information is missing - java

I just finished building an application using JavaFX and Hibernate, which builds and run perfectly on IntelliJ, so I choose to generate a "fat-jar" using maven shade plugin, since I make use of some libraries with automatic module names, so I cannot use jlink.
Jar is created fine, it loads the initial screen correctly, however when it tries to make connection to my database, specifically this line is the problematic (JPAUtil.java:19);
factory = Persistence.createEntityManagerFactory(persistenceUnit, properties);
I get the following exceptions;
java.lang.IllegalStateException: Required class information is missing
at org.jboss.jandex.Indexer.rebuildNestedType(Indexer.java:926)
at org.jboss.jandex.Indexer.resolveTypePath(Indexer.java:786)
at org.jboss.jandex.Indexer.resolveTypeAnnotation(Indexer.java:705)
at org.jboss.jandex.Indexer.resolveTypeAnnotations(Indexer.java:613)
at org.jboss.jandex.Indexer.index(Indexer.java:1602)
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:64)
at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:52)
at org.hibernate.boot.archive.internal.JarFileBasedArchiveDescriptor.visitArchive(JarFileBasedArchiveDescriptor.java:147)
at org.hibernate.boot.archive.scan.spi.AbstractScannerImpl.scan(AbstractScannerImpl.java:48)
at org.hibernate.boot.model.process.internal.ScanningCoordinator.coordinateScan(ScanningCoordinator.java:76)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:98)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:254)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:175)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:76)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:171)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:119)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:61)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:50)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at com.it.util.JPAUtil.getEntityManagerFactory(JPAUtil.java:19)
at com.it.controller.HomeController.initializeSettings(HomeController.java:1571)
at com.it.controller.HomeController.initialize(HomeController.java:1407)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
at com.it.Home.start(Home.java:23)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)
I know the syntax is correct as I mentioned before it runs correctly on IDE, so I suspect it is something missing on the jar file generated by shade, however I've spend almost 3 days on this already and I simply cannot find a reason. Information shown on the stacktrace doesn't help much, at least I don't see anything - I did even looked to all classes mentioned on the stacktrace and they all seem to be on the generated Jar.
Hoping anyone here had something similar or is maybe more familiar than me on the maven shade process. Any help or point to look at would be appreciated.
Additional files which would help to identify the problem is as follow;
persistence.xml - other properties are loaded from a XML file on the code.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="Project-Postgre">
<description>Hibernate JPA Configuration</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value = "false" />
</properties>
</persistence-unit>
</persistence>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.it</groupId>
<artifactId>Project</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.release>11</maven.compiler.release>
<javafx.version>14</javafx.version>
</properties>
<name>Project</name>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/de.jensd/fontawesomefx -->
<dependency>
<groupId>de.jensd</groupId>
<artifactId>fontawesomefx</artifactId>
<version>8.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.20.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc10 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc10</artifactId>
<version>19.7.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>${maven.compiler.release}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.3</version>
<configuration>
<mainClass>com.it.HomeFX</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>project-classifier</shadedClassifierName>
<outputFile>target\shade\${project.artifactId}.jar</outputFile>
<transformers>
<transformer implementation=
"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.it.HomeFX</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
JPAUtil
public static EntityManagerFactory getEntityManagerFactory(String persistenceUnit, String connectionURL, String user, String password) {
if (factory == null) {
Map<String, String> properties = new HashMap<>();
properties.put("javax.persistence.jdbc.url", connectionURL);
properties.put("javax.persistence.jdbc.user", user);
properties.put("javax.persistence.jdbc.password", password);
factory = Persistence.createEntityManagerFactory(persistenceUnit, properties);
}
return factory;
}

I had the same error using:
spring.version:5.2.7.RELEASE
spring.boot.version:2.3.1.RELEASE
postgresql-version:42.2.16
It happens with all versions of postgres from 42.2.15. Version 42.2.14 (or earlier) works fine for me.

I had the same problem. I tried to downgrade PostgreSQL JDBC driver version to 42.0.0. Exception gone and everything works fine.

The issue is caused by invalid bytecode produced by javac 1.8 (e.g. AdoptOpenJDK 1.8u222 is known to be affected).
Here's the issue (with reproducer): https://github.com/wildfly/jandex/issues/92
The fix is to update to org.jboss:jandex:2.2.3.Final which includes the workaround (and a couple of other fixes for type annotations), or use Java 11 compiler (== javac 11).
Just in case, org.postgresql:postgresql:42.2.15 triggers the issue since it uses the Checker Framework for nullness verification, and it includes multiple #Nullable and #NonNull annotations to make the verifications pass.
The upcoming org.postgresql:42.2.18 and org.postgresql:42.3.0 will have the relevant workarounds, so it would work with old jandex versions as well.
If you are reading here, I would recommend adding forbidden-apis and jandex bytecode parsers (e.g. de.thetaphi.forbiddenapis and com.github.vlsi.jandex Gradle plugins) to your build pipeline to capture invalid bytecode early (which might otherwise come unnoticed), especially if you still use javac 1.8.

I have managed to overcome this issue by switching from Hibernate to OpenJPA.
Hibernate did not provide enough information to debug the problem and when switching to OpenJPA I just had to add this to my pom.xml;
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-all</artifactId>
<version>3.1.2</version>
</dependency>
Shade created the JAR with all required libraries and connection to database was successfully.

Eventually, fixed in PostgreSQL JDBC Driver version 42.2.19, see https://jdbc.postgresql.org/documentation/changelog.html#version_42.2.19.
Update your version to 42.2.19 and it should solve the problem.

Related

How to configure Surefire to include '*Spec' Spock tests?

How can I make sure that certain tests are executed in a Maven build and not silently ignored?
I was recently forced to switch to Groovy 3. As a result, I updated my Spock version as well. Unfortunately, I missed the fact that Spock 2 requires JUnit 5. I only had JUnit 4 and Spock tests, therefore the Maven Surefire plugin used the JUnit 4 provider to execute tests. All Spock test were ignored. I just noticed this by accident.
I'm looking for a way to check if certain (or any) tests ending in *Spec are among the tests executed. I looked at the Maven Surefire and the Maven Enforcer plugin but could not find anything which suits my needs. If I'm skipping test execution completely this check should not fail.
Edit: This is a shortened version of the Spock example project as kriegaex suggested posting some pom.xml files. The problem applies to all Java projects, though. To me, a solution within the build process of the project itself would be superior to configuring CI/CD jobs as this can can easily be forgotten when moving/migrating the project to another CI pipeline.
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.spockframework</groupId>
<artifactId>spock-example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spock Framework - Example Project</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<groovy.version>3.0.7</groovy.version>
</properties>
<build>
<plugins>
<!-- Mandatory plugins for using Spock -->
<plugin>
<!-- The gmavenplus plugin is used to compile Groovy code. To learn more about this plugin,
visit https://github.com/groovy/GMavenPlus/wiki -->
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.12.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Optional plugins for using Spock -->
<!-- Only required if names of spec classes don't match default Surefire patterns (`*Test` etc.) -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<useModulePath>false</useModulePath> <!-- https://issues.apache.org/jira/browse/SUREFIRE-1809 -->
<useFile>false</useFile>
<includes>
<include>**/*Test</include>
<include>**/*Spec</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-bom</artifactId>
<version>2.0-M5-groovy-3.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Mandatory dependencies for using Spock -->
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-junit4</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Sorry for the misunderstanding about spock-junit4. You only need that if you want to run JUnit 4 extensions, such as PowerMock runner, under Spock 2. If you want to run JUnit 4 tests beside Spock 2 tests, you need org.junit.vintage:junit-vintage-engine:5.7.1 for Spock 2.0-M5. Adding that dependency, fixes your POM for me.
However, I took the liberty to upgrade to Spock 2.0 final, Groovy 3.0.8 and JUnit 5.7.2, all in harmony with Spock 2.0. If you use a default Maven directory layout and name your Spock specs src/test/groovy/*Test instead of *Spec, you can even do without the Surefire class name filter. You should however specify Java source and target levels. Without them, my JDK complained about the default 1.5.
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.spockframework</groupId>
<artifactId>spock-example</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Spock Framework - Example Project</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<groovy.version>3.0.8</groovy.version>
</properties>
<build>
<plugins>
<!-- Mandatory plugins for using Spock -->
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.12.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<useModulePath>false</useModulePath> <!-- https://issues.apache.org/jira/browse/SUREFIRE-1809 -->
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-bom</artifactId>
<version>2.0-groovy-3.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.7.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<scope>test</scope>
</dependency>
<!-- Required if you want to run JUnit 4 tests alongside Spock 2 -->
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
P.S.: Actually, first I wanted to close your question as a duplicate of that one. But because since then the version numbers have changed a bit, I thought I would post a new answer here for your convenience.
Update: You can make sure that both testes named *Test and *Spec are executed, by fixing the filter in your question by adding .java or .class extensions. Weirdly enough, .groovy will not work, which is a known Surefire quirk.
<includes>
<include>**/*Test.class</include>
<include>**/*Spec.class</include>
</includes>
or
<includes>
<include>**/*Test.java</include>
<include>**/*Spec.java</include>
</includes>

Maven TinyB failure: package tinyb does not exist

I am trying to do a program where I need using Aws sdk and TinyB library. FOr that reason I have decided to use maven to create the project and resolve the dependencies. However, I have been trying to compile the project with the package TinyB for more than a week without success. I would be very grateful if someone could teach me what I am doing wrong.
The failure message I am receving is the following:
C:/Users/fran/Desktop/RSSI_AWS_PROJECT/BleDistanceMeasurement/src/main/java/org/tfm/app/BleMng.java:[7,1]
package tinyb does not exist
And my pom.xml is:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.tfm.app</groupId>
<artifactId>BleDistanceMeasurement</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>BleDistanceMeasurement</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.327</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-iot</artifactId>
<version>1.10.34</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-iot-device-sdk-java</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-iot-device-sdk-java-samples</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.kura</groupId>
<artifactId>tinyb</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>tinyb</id>
<url>https://repo.eclipse.org/content/groups/releases/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I have opened the project with Eclipse IDE to know what is happening but I have seen that eclipse is recognizing the dependencies correctly.
TinyB dependencie scan
Project dependencies
TinyB library I have downloaded and compiled the source from here:
https://github.com/intel-iot-devkit/tinyb
But there is no maven repositories directly from intel so I have added the one form eclipse kura:
<!-- https://mvnrepository.com/artifact/org.sputnikdev/bluetooth-manager-tinyb -->
<dependency>
<groupId>org.sputnikdev</groupId>
<artifactId>bluetooth-manager-tinyb</artifactId>
<version>1.0</version>
</dependency>
This one gives me problems when compiling, it seems as if the repository hasn't been downloaded. But the foder with the jar exists (it shows the error quoted previously).
I have made some little programs with TinyB and they are working perfectly, so the program is compiled and installed correctly. The problem is I am not using maven in this little programs (I just add the import and point to the .jar when executing). Like this:
sudo java -cp examples/java/HelloTinyB.jar:/usr/lib/lib/java/tinyb.jar HelloTinyB
I have also try this other maven repository:
<!-- https://mvnrepository.com/artifact/org.sputnikdev/bluetooth-manager-tinyb -->
<dependency>
<groupId>org.sputnikdev</groupId>
<artifactId>bluetooth-manager-tinyb</artifactId>
<version>1.3.2</version>
</dependency>
In this case it recognizes the dependencies and compiles. The problem is it gives error when I try to execute the program:
java.lang.RuntimeException: Native library is out of date. Please update the native library.
at tinyb.BluetoothManager.getBluetoothManager (BluetoothManager.java:317)
Thank you very much for your help.
I see you are trying to use eclipse Kura too.
Did you achieve making it work?
I have the same issue.
By the way, I see that maybe your dependencies are not really valid, as sputnikdev has a library over tinyB, but, finally I have the same problem than you. These are my main dependencies:
<!-- https://mvnrepository.com/artifact/org.sputnikdev/org.eclipse.smarthome.binding.bluetooth.transport.tinyb -->
<dependency>
<groupId>org.sputnikdev</groupId>
<artifactId>bluetooth-manager</artifactId>
<version>1.5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/intel-iot-devkit/tinyb -->
<dependency>
<groupId>intel-iot-devkit</groupId>
<artifactId>tinyb</artifactId>
<version>0.5.1</version>
</dependency>
<dependency>
<groupId>org.sputnikdev</groupId>
<artifactId>bluetooth-manager-tinyb</artifactId>
<version>1.3.3</version>
</dependency>

limit jetty scanning in maven plugin

I'm having problems getting a webapp to start quickly in using the maven jetty plugin in eclipse. I'm using the jetty:run goal.
After turning on the logging the problem seems to be that jetty scans all the jars in my webapp for web app configuration. Just including a dependency to jersey-media-moxy causes jetty to add 48 seconds to its start up time.
How do I limit this scanning in the jetty-maven-plugin? I've found Jetty startup delay due to scanning but before I make some external jetty configuration and include this is the maven configuration, I want to make sure that there isn't a more straightforward option.
http://eclipse.org/jetty/documentation/current/quickstart-webapp.html looks promising, but I'm unsure how to proceed (as this doesn't mention the maven plugin either).
my pom.xml file is included below:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my-app</groupId>
<artifactId>my-app</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>my-app</name>
<build>
<finalName>my-app</finalName>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.9.v20150224</version>
<configuration>
<war>${project.basedir}/target/my-app.war</war>
<stopPort>8088</stopPort>
<stopKey>foo</stopKey>
<stopWait>10</stopWait>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<!-- artifactId>jersey-container-servlet-core</artifactId -->
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<artifactId>jersey-container-servlet</artifactId>
</dependency>
<!-- uncomment this to get JSON support -->
<!-- -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
<!-- -->
</dependencies>
<properties>
<jersey.version>2.16</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
This is what I use for my projects to speed up Jetty startup just from the maven pom.xml file (no external configuration is required):
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<webApp>
<!-- no need to scan anything as we're using servlet 2.5 and moreover, we're not using ServletContainerInitializer(s) -->
<!-- for more relevant information regarding scanning of classes refer to https://java.net/jira/browse/SERVLET_SPEC-36 -->
<webInfIncludeJarPattern>^$</webInfIncludeJarPattern>
<containerIncludeJarPattern>^$</containerIncludeJarPattern>
<!--<webInfIncludeJarPattern>.*/spring-[^/]*\.jar$|.*/.*jsp-api-[^/]\.jar$|./.*jsp-[^/]\.jar$|./.*taglibs[^/]*\.jar$</webInfIncludeJarPattern>-->
</webApp>
</configuration>
</plugin>
Use any regex of your choice (if you're using servlet initializers). Note that ^$ excludes everything.

Java: Enum : NoClassDefFoundError

I am facing issues while using enum in my J2EE application. I am using enum in a switch case inside my stateless service bean.
During runtime I see following exception on switch statement:
Caused by: java.lang.NoClassDefFoundError: com/comp/service/TestServiceImpl$1
This issue has been extensively discussed on one of the thread on SO. But I do not see any solution mentioned to resolve this issue.
In my case I use JBOSS EAP6.1 server. JDK version is 1.7. Code is built using Maven in Eclipse IDE. And application is deployed as EAR archive. How do I add this extra generated class file in classpath inside my EAR archive? Is there any other way to resolve this issue?
Update 29 June 2014:
I tried to build application from command line. Then this extra class file is generated. And I am able to deply and execute application successfully. It seems to be bug with eclipse then. Any idea how to resolve it?
pom.xml from EAR project:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>demo-maven</artifactId>
<groupId>com.comp.demo</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>demo-ear</artifactId>
<packaging>ear</packaging>
<name>demo - ear</name>
<url>www.comp.com</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<distribution>repo</distribution>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
</license>
</licenses>
<dependencies>
<!-- Depend on the ejb module and war so that we can package them -->
<dependency>
<groupId>com.comp.demo</groupId>
<artifactId>demo-web</artifactId>
<type>war</type>
</dependency>
<dependency>
<groupId>com.comp.demo</groupId>
<artifactId>demo-service</artifactId>
<type>ejb</type>
</dependency>
</dependencies>
<build>
<finalName>${project.parent.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>${version.ear.plugin}</version>
<configuration>
<!-- Tell Maven we are using Java EE 6 -->
<version>6</version>
<!-- Use Java EE ear libraries as needed. Java EE ear libraries
are in easy way to package any libraries needed in the ear, and automatically
have any modules (EJB-JARs and WARs) use them -->
<defaultLibBundleDir>lib</defaultLibBundleDir>
<modules></modules>
<fileNameMapping>no-version</fileNameMapping>
</configuration>
</plugin>
<!-- The JBoss AS plugin deploys your ear to a local JBoss EAP container -->
<!-- Due to Maven's lack of intelligence with EARs we need to configure
the jboss-as maven plugin to skip deployment for all modules. We then enable
it specifically in the ear module. -->
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- When built in OpenShift the 'openshift' profile will be used when invoking mvn. -->
<!-- Use this profile for any OpenShift specific customization your app will need. -->
<!-- By default that is to put the resulting archive into the 'deployments' folder. -->
<!-- http://maven.apache.org/guides/mini/guide-building-for-different-environments.html -->
<id>openshift</id>
<build>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>${version.ear.plugin}</version>
<configuration>
<outputDirectory>deployments</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
pom.xml from ejb project:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>demo-maven</artifactId>
<groupId>com.comp.demo</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>demo-service</artifactId>
<packaging>ejb</packaging>
<name>demo - service</name>
<url>www.comp.com</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<distribution>repo</distribution>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
</license>
</licenses>
<dependencies>
<!-- Declare the APIs we depend on and need for compilation. All of them
are provided by JBoss EAP 6 -->
<!-- Import the EJB API, we use provided scope as the API is included in
JBoss EAP 6 -->
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<!-- Import the CDI API, we use provided scope as the API is included in
JBoss EAP 6 -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Import the JPA API, we use provided scope as the API is included in
JBoss EAP 6 -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- JSR-303 (Bean Validation) Implementation -->
<!-- Provides portable constraints such as #Email -->
<!-- Hibernate Validator is shipped in JBoss EAP 6 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.ejb3</groupId>
<artifactId>jboss-ejb3-ext-api</artifactId>
<version>2.0.0-redhat-2</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<!-- Test scope dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.5.Final</version>
<scope>test</scope>
</dependency>
<!-- Optional, but highly recommended -->
<!-- Arquillian allows you to test enterprise code such as EJBs and Transactional(JTA)
JPA from JUnit/TestNG -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-ejb-plugin</artifactId>
<version>${version.ejb.plugin}</version>
<configuration>
<!-- Tell Maven we are using EJB 3.1 -->
<ejbVersion>3.1</ejbVersion>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- The default profile skips all tests, though you can tune it to run
just unit tests based on a custom pattern -->
<!-- Seperate profiles are provided for running all tests, including Arquillian
tests that execute in the specified container -->
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.surefire.plugin}</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<!-- An optional Arquillian testing profile that executes tests in your
JBoss EAP instance -->
<!-- This profile will start a new JBoss EAP instance, and execute the
test, shutting it down when done -->
<!-- Run with: mvn clean test -Parq-jbossas-managed -->
<id>arq-jbossas-managed</id>
<dependencies>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-managed</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
<!-- An optional Arquillian testing profile that executes tests in a remote
JBoss EAP instance -->
<!-- Run with: mvn clean test -Parq-jbossas-remote -->
<id>arq-jbossas-remote</id>
<dependencies>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-remote</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
I ran into a similar issue, and the easy workaround was to define the Enum as public instead of private.
(Didn't have time to verify, but my hunch is that this causes the class to not be created as Name$1.class but rather something like Name$Enumname.class, which seemed to be the problem)
In my case, to avoid that NoClassDefFoundError in the code line of the switch statement, the only solution i saw was to replace switch statement by "else if" statements:
if (enumValue == EnumClass.Enum1) {
....
} else if (enumValue == EnumClass.Enum2) {
....
} else if (enumValue == EnumClass.Enum3) {
....
} else {
....
}
Exception caused by:
Caused by: java.lang.ClassNotFoundException: com.test.services.impl.MyServiceImpl$1
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1358)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1180)
Test with Java 8, Tomcat 8.5, Spring boot.
I have a project configuration quite similar to yours: eclipse, Maven, JDK 1.6, JBoss EAP6.2, and I have the same problem with a java.lang.NoClassDefFoundError when using an enum in a switch case.
I have found a workaround for it: generate an ear file (it is a war in my case) and install it manually from the JBoss administration console. I noticed the war includes the $1 needed classes and then you won't get the exception.
This is just a workaround, but it works for me. A good point of this workaround is that subsequent deployments done through eclipse work!
I will be listening to the answers to your question because I want a real solution.

Maven-plugin-plugin default-descriptor error message after upgrade to 3.1.1

I am upgrading my system's Maven runtime from 3.0.5 to 3.1.1 and trying to build my project using mvn clean install like I normally would. Using the older Maven runtime, the build would always succeed. However, I am now always getting this error message during the build:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-plugin-plugin:3.2:descriptor (default-descriptor) on project XYZ: Execution default-descriptor of goal org.apache.maven.plugins:maven-plugin-plugin:3.2:descriptor failed: 48188 -> [Help 1]
I thought that perhaps it was due to my dependencies and plugins being outdated, so I ran mvn versions:use-latest-versions to update my pom.xml versions. That still did not fix this issue. Any ideas?
UPDATE
By popular demand, here is what my pom.xml file looks like. Note that all dependency and plugin versions were updated by mvn versions:use-latest-versions except for Sitebricks and qdox, due to breaking changes that I didn't want to integrate into my project.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.company</groupId>
<artifactId>my-own-project</artifactId>
<version>1.0.1-SNAPSHOT</version>
<name>My Cool Maven Plugin</name>
<packaging>maven-plugin</packaging>
<distributionManagement>
<repository>
<id>someID</id>
<url>http://some.url.com</url>
</repository>
</distributionManagement>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.11</version>
</dependency>
<dependency>
<groupId>com.google.sitebricks</groupId>
<artifactId>sitebricks</artifactId>
<version>0.8.5</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.qdox</groupId>
<artifactId>qdox</artifactId>
<version>1.12</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<effort>Max</effort>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</reporting>
</project>
Upgrading and using below dependency with config resolved my issue:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<!-- see http://jira.codehaus.org/browse/MNG-5346 -->
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
I had exactly the same problem and tried probably every hint provided in the possible duplicate Basic maven plugin project not working, Mojo plugin descriptors not generating, but nothing worked. Eventually in turned out that an old version 2.6.1 of the library com.ibm.icu:icu4j that was used by some other 3rd party module was responsible. I got rid of the icu4j dependency entirely and maven-plugin-plugin run with out problems thereafter.

Categories