`java.lang.NoClassDefFoundError` from javaagent built by `maven package` - maven

I've been trying to build javaagent (containing premain()) to .jar file using maven mvn package, and keep getting java.lang.NoClassDefFoundError exception related to external dependencies. For details, I added kafka-client dependecies and maven-jar-plugin to pom.xml like below
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<index>true</index>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib</classpathPrefix>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${project.url}</url>
<key>value</key>
<Premain-Class>com.my.java.monitoring.Agent</Premain-Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
After reading How can I create an executable JAR with dependencies using Maven?, I tried using maven-assembly-plugin instead, like below
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<index>true</index>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Premain-Class>com.my.java.monitoring.Agent</Premain-Class>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- this is used for inheritance merges -->
<phase>package</phase>
<!-- append to the packaging phase. -->
<goals>
<goal>single</goal>
<!-- goals == mojos -->
</goals>
</execution>
</executions>
</plugin>
but I get this error =>
Failed to find Premain-Class manifest attribute in target/my-java-agent.jar Error occurred during initialization of VM agent library failed to init: instrument
Can anyone who has experience building javaagent .jar file with dependencies, please help.

Related

Include only certain packages in a Maven generated non-runnable jar

I'm trying to build a non-executable jar file that only includes certain packages from my project to use as a library for common code. I'm planning on deploying that to Nexus and including it in other projects.
I can make it manually in eclipse by right clicking on the project, selecting Export, selecting JAR file (NOT Runnable Jar File) then checking the packages that I want to include. I'm trying to mimic this behavior in Maven. I have been able to replicate the non-runnable part in maven by not including a main in the manifest, but still have to find out how to include only certain packages.
This project actually builds 2 jar files already (from 2 different main's in the program - a test GUI and the regular application). I'm having trouble finding information on how to do the non-runnable jar and selecting certain packages only.
Here is the existing build portion of my pom file is below. Build-third is the non-runnable jar:
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>build-first</id>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>com.joy.fb20.da.exec.jDaExecutive</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>DaExecutive</finalName>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
<execution>
<id>build-second</id>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>com.joy.fb20.gui.jExampleAppGui</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>ExampleAppGui</finalName>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<execution>
<id>build-third</id>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>ddslib</finalName>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</plugin>
</plugins>
</build>
Tried this myself and it is possible.
Create a new maven profile
Add pluginManagement section to that new profile for maven-jar-plugin and if needed for maven-resources-plugin also
Use this pluginManagement to configure inclusions/exclusions of sources/resources and override artifacts final name here to have different name for that separate jar
Example
<profiles>
<profile>
<id>subset</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<finalName>subset</finalName>
<includes>
<include>org/example/stuff/**</include>
</includes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
Using this profile maven creates subset.jar that has everything under org/example/stuff/**
See more about excluding: How to exclude a set of packages from maven build jar?
Of course it might be possible to do all this also without pluginManagement but in my opinion pluginManagement provides clean & flexible way to configure this kind of stuff so i recommend that.
You should be able to do that by using a custom assembly descriptor and specifying your fileset and / or file includes / excludes. See https://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_fileSet

How to avoid WARNING message "already attached to project, ignoring duplicate"

I've tried to avoid the maven warning message which comes from assembly plug in (I compile 2 jar files which are compiled from the same module)
Part of my pom.xml :
maven-jar-plugin
2.3.1
default-jar
none
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<executions>
<execution>
<id>MockFX</id>
<configuration>
<finalName>MockFX</finalName>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>mock.DSlauncher.FX.FX_DataSourceLauncher</mainClass>
</manifest>
</archive>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
<execution>
<id>MockFutures</id>
<configuration>
<finalName>MockFutures</finalName>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>mock.DSlauncher.Futures.Futures_DataSourceLauncher</mainClass>
</manifest>
</archive>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
During the compilation process I'm getting the next WARNING msg :
[WARNING] Artifact com.my.company:UAT-Mock:jar:jar-with-dependencies:1.0 already attached to project, ignoring duplicate
What should I add to pom.xml in order to avoid the warning ?
Thanks
Just add <attach>false</attach> to the configuration of both executions

Failed to build multiple assemblies in maven. No assemby descriptor found

I'm having some trouble when trying to generate two or more jars from a maven project when using the assembly plugin.
I have the following maven pom.xml file (see below).
However, when I run mvn clean compile assembly:single,
I get the following error:
Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.2-beta-5:single (default-cli) on project hyuga: Error reading assemblies: No assembly descriptors found. -> [Help 1]
What am I missing?
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>dg2cep</id>
<configuration>
<archive>
<manifest>
<mainClass>br.pucrio.inf.lac.konoha.hyuga.core.Bootstrap</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>dg2cep</finalName>
</configuration>
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
<execution>
<id>playback</id>
<configuration>
<archive>
<manifest>
<mainClass>br.pucrio.inf.lac.konoha.hyuga.others.csv.CSVPlayback</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>playback</finalName>
</configuration>
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Ah..you are executing it like this: mvn ... assembly:single ? If so don't do this.. use it within the life cycle like mvn clean package ....

buildnumber-maven-plugin does not resolve its ${buildNumber} property

My trouble is here:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Implementation-Title>${project.name}</Implementation-Title>
<Implementation-Version>${buildNumber}</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
What I'd like to do is to get the build number in runtime through manifest properties. There are plenty of instructions on how to use buildnumber-maven-plugin but I don't have a clue why in my manifest ${buildNumber} variable is not resolved.
<scm> tag is present in POM.
When building I see the following message:
Storing buildNumber: a391951e51a593c5267a77264938d982696ed65a at timestamp: 1426368059203
Still here is the result:
Implementation-Version: ${buildNumber}
Any help is much appreciated. Thank you.

maven build jar with test resources file only

I have a project which will be built has jar.
structure of project as below
> src | - main
> |- java
> - resources
> | - test
> | - resources
so now i want to create 2 jar files using maven
1) main/java and main/resources
2) main/java and test/resources
My POM
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>com.tool.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
You never specified what is happening for you that is not what you're after, but looking at your example, it looks like you've got two different versions of the same plugin defined in your POM to try and hack what you want.
You can do what you're after by using the <execution> tag to define the desired behavior.
<plugin>
<!-- jar plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<!-- use these to define different execution tasks during the package phase -->
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>${project.mainClass}</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</execution>
<execution>
<id>test-jar</id>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix> <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
After running this, you should have two jar's in your output directory, one named [your artifactID]-[version].jar and one named [your artifactID]-[version]-tests.jar

Resources