Issue
I have the following maven configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>${main.class}</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<classpathLayoutType>repository</classpathLayoutType>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Class-Path>./lib/*.jar</Class-Path>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
assembly.xml:
<assembly>
<id>assembly</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<includes>
<include>com.relax-gaming.casinoworld:casinoworld</include>
</includes>
</dependencySet>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<unpack>false</unpack>
<excludes>
<exclude>com.relax-gaming.casinoworld:casinoworld</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>
my manifest content is:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: username
Build-Jdk: 11
Specification-Title: project title
Specification-Version: 0.0.1-SNAPSHOT
Implementation-Title: Project title
Implementation-Version: 0.0.1-SNAPSHOT
Implementation-Vendor-Id: groupid
Main-Class: path.to.main.class
Class-Path: ./lib/*.jar
My jar is bundled as follows:
-my.code.package (from src/main/java)
+ META-INF
- MANIFEST.MF (where the above configuration is)
+ lib
- dep1.jar (all the dependencies as jar files)
-my.resources.file (from src/main/resources)
When i run the file using java -jar i get NoClassDefFound errosr cause the libraries are not loaded.
I imagine that the thing wrong is my classpath inside the manifest file. What should it be ?
Solution
So, Turns out you kinda can't.
My solution was as follows:
update the assembly.xml and pom.xml as follows:
assembly:
<assembly>
<id>assembly</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<excludes>
<exclude>groupId:artifactIdOfResourceIWant</exclude>
</excludes>
</dependencySet>
<dependencySet>
<outputDirectory>lib-packed</outputDirectory>
<unpack>false</unpack>
<includes>
<include>groupId:artifactIdOfResourceIWant</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>
pom :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>${main.class}</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
This basically unpacks all dependencies normally, but leaves the specific one you need to remain unpacked as a jar file within the jar file. This reduces complexity to only the jars you need unpacked.
now, the issue with that still remains that Class-Path can only take dir/* syntax to load all jars externally, and it cannot be used to load a jarfile (even with specific names) So to leave the jar bundled inside and have it automatically loaded i basically need to modify my code to have a custom classloader that reads that file.
Answered By - mangusbrother
Answer Checked By - Willingham (JavaFixing Volunteer)