how to add my external jar file to class path - maven

I am new to maven environment, need some ones help.
Added my external jar file (directoryhelper.jar) in lib folder as below in pom.xml
<dependency>
<groupId>com.test.directoryhelper</groupId>
<artifactId>DirectoryHelper</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/directoryhelper.jar</systemPath>
</dependency>
compilation is successful, but during run time I am getting
java.lang.NoClassDefFoundError.
how to add the directoryhelper.jar to class path.

Maven out of the box will come up with a JAR file (default packaging). This JAR file only contains (main) artifacts of the project. If you take just that and run it, clearly the dependencies are missing -- by design.
Typically Maven artifacts are reused in combination with their POM so that at the point of use it's know what the dependencies are. Edit: if you're using APKs and installing them on a phone, there may be mechanisms to deal with dependencies, I'm answering this merely from a Maven standpoint.
If you want to create a JAR with dependencies you have to tell Maven to do so, that's not the default.
Ways of having Maven do that are (probably not exhaustive):
Maven Assembly plugin, jar-with-dependencies predefined descriptor:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
...
Maven Shade plugin

That way it'll create a single-jar of large size and build time will be large everytime you try to build.
I instead prefer adding all jars to a lib folder and including in the classpath (jar's manifest), because of which when we have to make some change or redeploy to the client or some place, we can simply give the small jar (not all the dependencies merged within jar)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.kalindiinfotech.webcrawler.MainGUI</mainClass>
<!-- <mainClass>com.KalindiInfotech.busbookingmaven.form.LoginForm</mainClass>-->
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

Related

How to stop maven from output "[WARNING] Configuration option 'appendAssemblyId' is set to false."?

I have a maven project generating a jar and not appending maven-assembly-plugin's appendAssemblyId.
How can I get maven to stop issuing the warning: "Configuration option 'appendAssemblyId' is set to false." ?
EDIT: I was asked to include the pom file, which I'm not permitted to do. I'm including the maven-assembly-plugin block which causes the error.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>some.company.hello</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- prevent appending <descriptorRef> "jar-with-dependencies" to final jar name -->
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<!-- For inheritance merges -->
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
This answer explains the technical details, but I think the key is the phrase that you mentioned in your question.
I have a maven project generating a jar and not appending maven-assembly-plugin's appendAssemblyId.
If I'm understanding correctly, I take this to mean that in your pom file, you have an entry that says
<packaging>jar</packaging>
What this does is create a jar file that competes with the output of the maven-assembly-plugin, and maven-assembly-plugin wins out, resulting in only one jar file. In fact, if you were to set appendAssemblyId back to true, you will get two files in the output directory - <artifact>.jar and <artifact>-jar-with-dependencies.jar.
So, first, you should remove the <packaging> tag I mentioned above, and add the following to the <executions> section of your pom file so that there won't be two conflicting/competing jar files (and the warning will go away):
<execution>
<id>default-jar</id>
<phase>none</phase>
</execution>

Packaging custom javadoc doclet with maven

I've written my own java doclet and want to package it into a single jar file to use it later on.
I'm currently using maven with these settings to generate it:
<build>
<finalName>Doclet</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>de.test.tools.doclet.Doclet</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- Maven Assembly Plugin -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>de.test.tools.doclet.Doclet</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
Problem:
Everything is properly packaged into the jar but my sources are missing.
If I try to do a simple mvn package it tells me that the sun package doesn't exist.
error: package com.sun.javadoc does not exist
I think the last part is the main reason behind why I can't find my sources in the jar and thus my question is how I can tell maven to ignore those imports.
The problem is that maven cannot find package com.sun.javadoc which is in the tools.jar in the /lib folder of the java installation dir.
Eclipse was able to execute it because I added it to the classpath there but maven had no idea where he can get the resources from. So adding the following system dependency solved the problem for me:
<dependency>
<scope>system</scope>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>YOUR_JAVA_VERSION</version>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
Replace the version with your version and make sure java home is known in your environment.
Note: This dependency doesn't work on MacOS. See: JDK tools.jar as maven dependency - Summary: Use Profiles for each OS to be able to specify the correct path.
I only need to support Linux + Windows so it is the best solution for me.

Can I force Maven to build a JAR even though POM packaging specifies WAR?

I'd like to build our project from the command line as a JAR without modifying the POM, which has the <packaging>war</packaging> configuration.
Is there a way to do this?
If you are free to chose how maven is executed it is possible to call maven to invoke the jar goal directly:
mvn jar:jar
I was not able to explicitly build a jar while preventing the building of a war as well. But I realized I didn't have to. With this configuration of the maven-assembly-plugin, and the packaging set to WAR in my POM, a fat-jar and a war will always be created.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<finalName>myApp</finalName>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.company.app.Startup</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
If this questions / answer seems confusing / not useful to searchers, feel free to delete it. Thanks to everyone who helped me get here.

dozer with maven

I wanted to download the latest release of Dozer mapper from github, but I didn't find any jar.
There is pom.xml file and I try to compile with command mvn package. I also added every dependencies to pom.xml file. It created dozer-5.5.0-SNAPSHOT.jar.
Next I imported this jar to my project, but it throws me java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory.
I also tried to create POM project in the netbeans and build with dependencies. After import to my project, it throws me the same exception.
I don't have any experiences with maven. How can I get correct JAR file?
Guess your dozer-package has a dependency to slf4j, right?
Then you should checkout this Maven-Plugin: Maven-Assembly-Plugin
This will put your required dependencies into the jar.
Here you can read, how to use it
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>your.main.class</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
If you want always execute the assemby-plugin when you invoke mvn clean package
add this to your maven-assembly-plugin:
<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>
You have a correct jar. Simple add commons-beanutils lang and slf4j to you project with dozer or add this libraries as a maven dependencies.
Jars required for Dozer dependency.
Make the entry in pom.xml file.Make sure the required Jars are present.
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.3.1</version>
</dependency>
<properties>
<osgi.version>4.3.0</osgi.version>

Recommended practices for distributing/using maven projects outside the build lifecycle

There are many occasions where I am not sure whats the best to handle dependencies for a maven project. That is while executing a jar thats the result of mvn package.
Things I have tried
1) Maven-shade plugin
For some use cases ( such as hadoop jobs ) I find it convenient to use the Maven shade plugin to integrate with the package step ( it builds an all inclusive uber-jar ). The downside is that the uber-jar is too massive. Also, I cant get the maven shade to work on datanucleus dependencies as it messes up something.
2) distribute the dependencies along with the jar.
//something like this
$ mvn package dependency:copy-dependencies
$ java -cp target/project.jar:target/dependency com.MyMainClass
generates a directory with all the dependencies along with the jar.
What I would like to do is
3) just be able to distribute the jar and handle the dependencies while executing the jar. Since mvn package puts the pom in the jars manifest folder, all the information is there right ? . Now, I would like it if there was a one line command to be able to run this jar asking maven to manage the dependencies. Even more awesome if someone knows if such a thing can be used as a hadoop job.
I think there is no solution for question in your point 3.
My three options, in all cases you can run application with simple java -jar target/project.jar. Nothing more is needed.
1. Maven Assembly Plugin with jar-with-dependencies descriptor
(manifest in jar configuration is missed here)
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
2. Maven dependency plugin
Maven dependency plugin, properly jar configured (classpath) and maven assembly custom descriptor for packing all together.
(you can simplify this, if your project is not using snapshot dependencies)
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>your.package.MainApp</mainClass>
<packageName>your.package</packageName>
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>lib/$${artifact.artifactId}.$${artifact.extension}/customClasspathLayout>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeScope>test</excludeScope>
<includeScope>compile</includeScope>
<stripVersion>true</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
3. Maven One Jar
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<configuration>
<attachToBuild>true</attachToBuild>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>

Resources