Maven assembly plugin is not including the project packages [duplicate] - java

This question already has answers here:
Building a fat jar using maven
(7 answers)
Closed 1 year ago.
I'm trying to build a fat jar with maven assembly plugin for distributing a desktop application.
My POM looks like
<build>
<!-- To parse properties files under resources folder : -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.acme.qpguard.editor.Application</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The command mvn assembly: single is creating a fat jar with other dependencies, but fat jar does no include my classes.
So while starting the jar, I'm getting an error
Error: Could not find or load main class com.acme.qpguard.editor.Application
How can I fix my POM so that it includes my project files too
Please note that the project is running fine in Eclipse.

Thanks, #Mayur and #Randy Casburn. Your pointers definitely helped me in finding a fix using maven shaded plugin.
I'm posting the fix as someone may find this useful at a later point of time
<build>
<!-- To parse properties files under resources folder : -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.acme.qpguard.editor.Application</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note: I have to apply a filter for removing signature files from some jars as it was breaking the execution.

Related

Reading properties files "inStream parameter is null"

I have read property files before and I realize there are many links on the topic but I think my properties file is not getting packaged correctly due to plug-ins. My Eclipse project has a properties file in src/main/resources called environment.properties. I have tried reading it through a method, even trying to declare the method as both static and non-static at different times:
static Properties properties = new Properties();
public void getClassPathProperties() {
LOGGER.debug("getClassPathProperties Enter");
try (final InputStream input = Utils.class.getClassLoader().getResourceAsStream("environment.properties")) {
properties.load(input);
LOGGER.debug("properties found:");
for (Object key : properties.keySet()) {
LOGGER.debug("" + ((String) key) + "=" + properties.getProperty((String) key));
}
} catch (Exception e) {
LOGGER.error("Unable to find environment.properties on classpath to Utils.class");
e.printStackTrace();
}
LOGGER.debug("getClassPathProperties Exit");
}
I tried the static declaration first but also tried non-static when a few posts mentioned it works until being declared as a static. I have also tried placing the environment.properties file manually within the the JAR file in different places without success. From Eclipse the exception is:
14:33:52.676 [main] ERROR com.goprecise.ams.handlers.utils.Utils - Unable to find environment.properties on classpath to Utils.class
java.lang.NullPointerException: inStream parameter is null
at java.base/java.util.Objects.requireNonNull(Objects.java:246)
at java.base/java.util.Properties.load(Properties.java:403)
and from the Maven command line an NPE on Properties.load() is reported (the LOGGER.error() message is from the code shown). The pom.xml is:
<?xml version="1.0"?>
... header ...
<properties>
<version.org.kie>7.48.0.Final-redhat-00004</version.org.kie>
<version.org.powermock>1.7.4</version.org.powermock>
<version.junit>4.12</version.junit>
<version.org.slf4j>1.7.26</version.org.slf4j>
<java.module.name>${project.name}</java.module.name>
</properties>
<dependencyManagement>
<dependencies>
... depeendencies
</dependencies>
</dependencyManagement>
<dependencies>
... many more dependencies
</dependencies>
<build>
<sourceDirectory>${project.build.directory}/generated-sources/java</sourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>*.png</include>
</includes>
</resource>
<resource>
<directory>${project.build.directory}/maven-shared-archive-resources</directory>
<filtering>true</filtering>
<includes>
<include>*.part</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filter-src</id>
<goals>
<goal>filter-sources</goal>
</goals>
<configuration>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-repository-resources</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>UTF-8</encoding>
<resources>
<resource>
<directory>target/generated-sources/annotations</directory>
<includes>
<include>repoindex.html</include>
<include>*.wid</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<outputDirectory>target/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessors>
<annotationProcessor>org.jbpm.process.workitem.core.util.WidProcessor</annotationProcessor>
</annotationProcessors>
<compilerArgs>
<arg>-AwidName=${project.artifactId}</arg>
<arg>-AgenerateTemplates=true</arg>
<arg>-AgenerateWids=true</arg>
<arg>-AwidsResources=${project.artifactId}.wid:widtemplate.st</arg>
<arg>-AtemplateResources=kie-deployment-descriptor.xml:kie-ddtemplate.st,serviceinfo.json:serviceinfo.st,repoindex.html:repoindex.part,index.html:indextemplate.st,${project.artifactId}.bpmn2:defaultprocess.st</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<!-- root module has no assembly so ignore it -->
<ignoreMissingDescriptor>true</ignoreMissingDescriptor>
<descriptors>
<descriptor>${project.basedir}/assembly/assembly.xml</descriptor>
</descriptors>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
<executions>
<execution>
<id>integration-test-execution</id>
<phase>verify</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<builddir>${project.build.directory}</builddir>
</systemPropertyVariables>
<failIfNoTests>false</failIfNoTests>
<test>${it.test}</test>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
<argLine>${failsafe.arg.line}</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.commonjava.maven.plugins</groupId>
<artifactId>project-sources-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>project-sources</id>
<goals>
<goal>archive</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
</excludes>
<argLine>-Xmx1024m -Dfile.encoding=UTF-8</argLine>
<systemPropertyVariables>
<apple.awt.UIElement>true</apple.awt.UIElement>
<org.uberfire.nio.git.daemon.enabled>false</org.uberfire.nio.git.daemon.enabled>
<org.uberfire.nio.git.ssh.enabled>false</org.uberfire.nio.git.ssh.enabled>
<org.uberfire.sys.repo.monitor.disabled>true</org.uberfire.sys.repo.monitor.disabled>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>default-jar</id>
</execution>
<!-- No OSGi manifestEntries for <goal>jar</goal>: if it supported, then felix has already added them -->
<execution>
<id>test-jar</id>
<goals>
<goal>test-jar</goal>
</goals>
<configuration>
<skipIfEmpty>true</skipIfEmpty>
<excludes>
<exclude>**/logback-test.xml</exclude>
<exclude>**/jndi.properties</exclude>
</excludes>
<archive>
<manifestEntries>
<Bundle-SymbolicName>${java.module.name}.tests</Bundle-SymbolicName>
<Bundle-Version>
${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}.${osgi.snapshot.qualifier}
</Bundle-Version>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-Vendor>${project.organization.name}</Bundle-Vendor>
</manifestEntries>
</archive>
</configuration>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<configuration>
<resourceBundles>
<resourceBundle>org.jbpm.contrib:template-resources:${version.org.kie}</resourceBundle>
</resourceBundles>
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I want the code in the JAR to find the properties at run-time: if the property file does not belong in src/main/resources (the typical place) where does it belong? If a plug-in is interfering with this how can I configure the plugin to enable my reading properties (or would simply moving the file enable it to be read)?
It's the declaration:
<resource>
<directory>src/main/resources</directory>
...
<includes>
<include>*.png</include> <!-- just this one isn't enough -->
</includes>
</resource>
If you (re-)declare the resources explicitely it's not cummulative with the defaults, i.e. the defaults are overriden. Have a look at your target/classes and you will find just PNG images there.
See resources:[testR|r]esources:
Always uses the project.build.[testR|r]esources element to specify the resources to copy.
and POM Reference, Super POM:
<project>
...
<build>
...
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
which means: Take all from these dirs by default but take nothing from these dirs if overridden (unless you include it when overriding).
So the property file also needs to be added to src/test/java because it is being called from test cases. Two separate JARs are actually created in the target directory:
ams-pam-workitemhandlers-2.0.1.1.jar
ams-pam-workitemhandlers-2.0.1.1-tests.jar
I think the application will find the resource file in src/main/resources or I will have to move it out but the test cases definitely find it in src/test/resources.

Bind a file inside a maven built EAR

Below is my project structure.
I require to copy a file from the location \MainProject\src\non-packaged-resources to the \MainProject\sub-project2\sub-project2-web\src\main\resources location on building the MainProject.
Below is the build section of the pom file of my sub-project2-web but the file is not copied while building.
<build>
<finalName>sub-project2-web</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceExcludes>**/.copyarea.db</warSourceExcludes>
<packagingExcludes>**/.copyarea.db</packagingExcludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>/src/main/resources</outputDirectory>
<resources>
<resource>
<directory>/src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When observing the build log, it skips the file being copied with the below error
skip non existing resourceDirectory
But the maven build gets successful.
Goal is to bind the file which exists inside the \MainProject\src\non-packaged-resources to all the ears (sub-project1.ear, sub-project2.ear) on building the maven project. First I am trying to test this in the sub-project2-web only.
Please advice on how to provide correct paths based on this requirement.
I am using maven 2.2.1 version (project is built on this.)
Define the paths with reference to your project base directory as follows.
<outputDirectory>${project.basedir}/sub-project2/sub-project2-web/src/main/resources</outputDirectory>
<directory>${project.basedir}/src/non-packaged-resources</directory>
Then add it in the pom.xml file in the maven-resources-plugin.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.basedir}/sub-project2/sub-project2-web/src/main/resources</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Based on the above answer I found the correct way to get the locations of the parent and the base directories. Below worked for me.
<build>
<finalName>sub-project2-web</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceExcludes>**/.copyarea.db</warSourceExcludes>
<packagingExcludes>**/.copyarea.db</packagingExcludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.basedir}/src/main/resources</outputDirectory>
<resources>
<resource>
<directory>${project.parent.parent.basedir}/src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

cannot get resources folder into jar when using spring boot maven plugin

Im trying to build an executable jar that runs with spring boot, but I cant get the spring xml from the resources folder into the jar. It looks like my outputDirectory is wrong. What is the correct way to define it such that it is packaged within the jar?
Here is my pom file
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources/my-resources</directory>
<includes>
<include>*xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>netexchange.exchange.main.ExchangeMain</mainClass>
</manifest>
</archive>
<outputDirectory>${basedir}/target</outputDirectory>
<finalName>Matcher-with-config</finalName>
<addResources>true</addResources>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
</build>
So I figured out a solution which was to copy the specific resource into question into the folder "src/main/resources". Spring boot build automatically includes all files in that folder, and then you can import them with the annotation "#ImportResource({ "classpath:config.xml" })"
My updated pom looks like this:
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources/bitcoin-ethereum</directory>
<includes>
<include>*xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources/matcher</directory>
<includes>
<include>*xml</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources/common</directory>
<includes>
<include>*xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>netexchange.exchange.main.ExchangeMain</mainClass>
</manifest>
</archive>
<outputDirectory>${basedir}/target</outputDirectory>
<finalName>Matcher</finalName>
<addResources>true</addResources>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
</build>

maven how to configuration xml file into pom.xml

when running at cmd normally command is java -jar xxx.jar param1.
my command is java -jar n2n-adaptor-cimbr-news-pdf-jar-with-dependencies.jar hostserver.xml
how to conficuration hostserver.xml at pom.xml? so tat no need run param at cmd.
<modelVersion>4.0.0</modelVersion>
<groupId>n2n</groupId>
<artifactId>n2n-adaptor-cimbr-news-pdf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.7</java.version>
<main.class>com.n2n.newsPDF.MainNewsCIMBRHostServer</main.class>
</properties>
<build>
<finalName>${project.artifactId}</finalName>
<pluginManagement>
<plugins>
<!-- We specify the Maven compiler plugin as we need to set it to Java
1.8 -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>${main.class}</mainClass>
</manifest>
</archive>
<suiteXmlFiles>
<suiteXmlFile>${project.build.directory}/resources/hostserver2.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>hostserver2.xml</include>
</includes>
</resource>
</resources>
</build>
after i make configuration it can't running when i run java -jar n2n-adaptor-cimbr-news-pdf-jar-with-dependencies.jar.
please kindly advice.
Thanks
Sharon
This is a problem you need to solve within Java, not Maven. You define the parameters of your Java Main class. If you want to replace command line parameters with resources, this is the place to go.

Maven package resources with classes

I'm generating a War file with Maven and publishing the classes jar as well:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
Is it also possible to publish the resources from the war in the classes jar?
My advice would be to put these resources in their own separate jar module and then have the war use them as a dependency. That way the war and any other project could refer to the resources as if it was any other dependency.
But if you don't want to do that or you can't, I think you'll have to use a classifier. As I said, this isn't ideal. Here's a detailed tutorial on how to do it:
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>only-library</id>
<goals><goal>jar</goal></goals>
<phase>package</phase>
<configuration>
<classifier>only-library</classifier>
<excludes>
<exclude>**/Main*</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>everything</id>
<goals><goal>jar</goal></goals>
<phase>package</phase>
<configuration>
<classifier>everything</classifier>
<includes>
<include>**/*</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Categories