Creating library jar with dependent jars with maven dependency plugin - java

I want to create a jar (No main class) which is later used as UDF in apache pig. When i creating the jar with maven the dependent jars are not include inside the output jar.
pom file looks like this
<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.test</groupId>
<artifactId>AppName</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>xzloader-java-pig-udf</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<classifier>h2</classifier>
<version>0.13.0</version>
</dependency>
</dependencies>
</project>
But the resulted jar always throw
NoClassDefFoundException
when running with apache pig

Here is an extract of my pom.xml which builds a jar with dependencies:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- append to the packaging phase. -->
<goals>
<goal>attached</goal> <!-- goals == mojos -->
</goals>
</execution>
</executions>
</plugin>
The difference I see is the goal: you use single, I use attached.

Related

How to extract a sub-part of a library with maven?

In my pom.xml file, I declare a dependency with the apache library : commons.math3-3.6.1.jar (21 subdirectories. The size of this library is about 2162Ko).
From my point of view, this library is heavy for my use. I would like to extract only
the part I need: org.apache.commons.math3.ode.
I've read a lot of explanations, but I haven't found anything that would help me.
Does anyone have an idea?
Thank you for your help.
RLB
For information: currently, I create the .jar file with the command :
mvn package assembly:single.
This jar file has a size of 2.2 MB, which includes the commons.math3 library and another one.
With the command :
mvn package,
the generated jar file is 8Kb in size. It includes only my own code.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.rlb</groupId>
<artifactId>FlyingBall</artifactId>
<version> 0 </version>
<name>FlyingBallCode</name>
<description>My description </description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>org.siani.javafmi</groupId>
<artifactId>fmu-framework</artifactId>
<version>2.6.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<excludes>
<!-- RLB : Exclude the class which contain the main function, before jar creation. -->
<exclude>siani/javafmi/FlyingBallMain.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</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>
</pluginManagement>
</build>
</project>

Selma code generate

According to the https://github.com/xebia-france/selma/blob/master/examples/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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mapper</groupId>
<artifactId>Selma</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.2.4</version>
<configuration>
<defaultOutputDirectory>
${project.build.directory}/generated-sources/selma
</defaultOutputDirectory>
<processors>
<processor>fr.xebia.extras.selma.codegen.MapperProcessor</processor>
</processors>
</configuration>
<executions>
<execution>
<id>process</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>fr.xebia.extras</groupId>
<artifactId>selma-processor</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>fr.xebia.extras</groupId>
<artifactId>example-common</artifactId>
<version>0.16-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/selma</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>fr.xebia.extras</groupId>
<artifactId>selma-processor</artifactId>
<version>0.15</version>
<scope>provided</scope>
</dependency>
<!-- This is the only real dependency you will have in your binaries -->
<dependency>
<groupId>fr.xebia.extras</groupId>
<artifactId>selma</artifactId>
<version>0.15</version>
</dependency>
</dependencies>
</project>
I create a selma sample, but codes could not generated. And when running, there is an error
Caused by: java.lang.ClassNotFoundException:com.mapper.mapper.SelmaMapperSelmaGeneratedClass
Is there any other configuration should be added to generate codes?
I misunderstood the meaning to compile time, indeed, I should run the maven command clean install. Then the codes are generated.
to use Selma inside eclipse without Maven, you should add both processor and api jar to the path of the annotation processor plugin.
This should be somewhere in project settings, see plugin documentation for this purpose: https://www.eclipse.org/jdt/apt/introToAPT.php .

Maven build is not generating main class files in JAR file-could not find or load main class error

The build was successful without any errors, but I checked the Jar file and there was no class files in it.
I the following command to
$mvn package command
with the following 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.cms.service.utils</groupId>
<artifactId>CMS_Job</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>CMS_Job</name>
<url>http://maven.apache.org</url>
<properties>
<jdk.version>1.7</jdk.version>
<junit.version>4.11</junit.version>
<log4j.version>1.2.17</log4j.version>
<maven-compiler-plugin.version>3.0</maven-compiler-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
<build>
<finalName>CMS_Job</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>**/log4j.properties</include>
</includes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.cms.service.utils.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- exclude junit, we need runtime dependency only -->
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
And this is my folder structure is described in the image(Linked)
This is how my jar file contents look like(Check the path on top)
I am new to maven environment.
Please help

Maven jar with dependencies?

I want to build the project so that final jar include all the dependencies in a single jar file
(if not possible includes classes from dependencies in to the jar file)
i followed the thread Including dependencies in a jar with Maven but lt included
the dependencies also which i even did not mention in my pom. Here is my POM which has just two dependencies.
I want when when final is built , it includes it specific dependencies mentioned in pom(either in classes or jar form)
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.myProject</groupId>
<artifactId>utils</artifactId>
<version>1</version>
</dependency>
Here you find an example pom.xml how to solve it with the maven-shade-plugin
When you run mvn package it generates an Jar file target/app-with-dependencies.jar. This Jar file include the compiled classes of the project itself and only the dependencies org.slf4j:slf4j-log4j12 and com.myProject:utils. It does not include the dependencies on which org.slf4j:slf4j-log4j12 depend.
<?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>sub.optimal</groupId>
<artifactId>shadedemo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.shade.version>2.3</maven.shade.version>
<maven.antrun.version>1.7</maven.antrun.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>com.myProject</groupId>
<artifactId>utils</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven.shade.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven.shade.version}</version>
<configuration>
<quiet>true</quiet>
<verbose>false</verbose>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>app-with-dependencies</finalName>
<artifactSet>
<includes>
<!--
here you define the dependencies which
you want to be included
-->
<include>org.slf4j:slf4j-log4j12:*</include>
<include>com.myProject:utils:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>${maven.antrun.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete>
<fileset dir="${project.build.directory}" includes="${project.name}-*.jar" />
</delete>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
One way is to use maven assembly plugin, the pom.xml configuration is like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.taobao.top.appstore.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>

Running java main program using maven

While running the executing the maven main class using below command:
mvn exec:java -Dexec.mainClass="com.xoxo.amqtest.SubscriberDriver"
I assumed that all the jars must be picked up from the maven repo. But instead it throws below exception.
java.lang.NoClassDefFoundError: com/xoxo/infra/protectedpkg/ProtectedPackageLoadException
This maven project runs fine in eclipse. Is there any way to specify maven to pick all the dependencies from maven repo instead of adding all the dependencies like below
java -cp ./:./target/amq-subscriber-1.0.0-SNAPSHOT-jar-with-dependencies.jar:/x/home/stvu/.m2/repository/com/xoxo/submodule/infra-jsse-2.0.1.jar com.xoxo.amqtest.SubscriberDriver
Edit:
<?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>
<parent>
<groupId>com.xoxox.infra</groupId>
<artifactId>infra-parent</artifactId>
<version>13.2.3</version>
<relativePath />
</parent>
<groupId>com.xoxox.amqtest</groupId>
<artifactId>amqsubscriber</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>amq_sub_test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.xoxox.infra</groupId>
<artifactId>infra</artifactId>
</dependency>
<dependency>
<groupId>com.xoxox.kernel</groupId>
<artifactId>KernelDAL</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.11</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit-addons</groupId>
<artifactId>junit-addons</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
com.xoxox.infra.maven.plugins
</groupId>
<artifactId>
infra-codegenerator-maven-plugin
</artifactId>
<versionRange>
[13.3.0,)
</versionRange>
<goals>
<goal>generate-code</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
I've done this in the past using exec-maven-plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>execute-your-main</id>
<phase>process-classes</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.xoxo.amqtest.SubscriberDriver</mainClass>
<arguments>
<argument>ADD_YOUR_ARGUMENTS_IF_NEEDED</argument>
</arguments>
</configuration>
</execution>
</plugin>
take look at appassembler plugin.
http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/
Configuration will look like
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
<configuration>
<programs>
<program>
<mainClass>fun.Tester</mainClass>
<id>app</id>
</program>
</programs>
</configuration>
</plugin>
it will create directory name 'appassembler' in you target directory which will have all dependent jars and executable according to platform in 'bin' directory

Categories

Resources