Maven - Load jar contained in dependency - java

I'm new to maven and I know that this is a common problem but can't make my project work.
I have an jar A which contains only a manifest and a lib folder with a jar B.
I'm able to add A as dependency in this way:
<dependency>
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>1.0.0</version>
<scope>compile</compile>
</dependency>
Maven successfully builds but at runtime I get a ClassNotFoundException for a class contained in B.
So, how can I include B?
My plugins section is like this:
<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-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>

IMHO you should create two project A and B. Having module B I would install it in local Maven repo (mvn install) and the pull it like regular Maven dependency.
Probably your IDE see B's classes as you have jar in lib folder.

Related

Error build maven multi-module - jar file

Currently I have a multi module project with maven, in the super pom I have added the modules of the projects. From the SparkAppBuilder module I intend to build the jar project that contains the SparkDriver and SparkProcess projects.
To do this from the SparkAPPBuilder module, add the maven-assembly-plugin plugin, I see that it builds the project by adding my 2 modules, but the problem is that it is generating the jar with all the dependencies that are in my local repository, so the jar weighs more than 150MB.
This is my SparkAppBuilderPOM:
<profile>
<id>dev</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.streaming.example.DirectStreaming</mainClass>
</manifest>
</archive>
<finalName>JavaStreamingDirect</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.streaming.example.DirectStreaming</mainClass>
</manifest>
</archive>
<finalName>JavaStreamingDirect</finalName>
</configuration>
</plugin>
</plugins>
</build>
</profile>
...
<dependencies>
<dependency>
<groupId>com.spark.driver</groupId>
<artifactId>SparkDriver</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.spark.streaming</groupId>
<artifactId>SparkProcess</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
</dependencies>
Do you know why you add my entire local repository in the assmbly phase?
Thanks so much.
Regards
A jar-with-dependencies also contains all transitive dependencies. Those are usually needed to run the project because they are the dependencies of your dependencies.
So it is not unusual that this jar is large. You should look in your mvn dependency:tree where most of the stuff comes from -- then you might be able to reduce the amount by changing the dependencies of your modules.
So: The jar-with-dependencies does not contain the whole local repository, just the whole dependency tree.

Force Maven to Pick up Dependencies in Project Directory

I am using Maven to manage my dependencies and am trying to pull a few, proprietary, jar files from my project directory. (Yes, I know, I'm a crazy idiot who doesn't get the purpose of Maven and should never do this.) On compilation, I get the typical warnings about pointing to files in my project directory. However, the specified jar files are not placed in my .m2 directory, and thus, the project does not compile as dependencies are missing.
In pom.xml:
<dependency>
<groupId>org.sample</groupId>
<artifactId>sample</artifactId>
<scope>system</scope>
<version>2.0.3</version>
<systemPath>${project.basedir}/WebContent/WEB-INF/lib/my_file.jar</systemPath>
<type>jar</type
<optional>true</optional>
</dependency>
Question is, am I declaring my groupId and artifactId correctly? Is there a way to force Maven to use several, random, jar files in my project directory?
Thanks for the help.
You have to add the jar in your classpath as well for mvn to pickup your system dependencies.
<Class-Path>libs/my_file.jar</Class-Path>
Plugin Config
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven.jar.plugin.version}</version>
<configuration>
<archive>
<manifestEntries>
<Build-Jdk>${jdk.version}</Build-Jdk>
<Implementation-Title>${project.name}</Implementation-Title>
<Implementation-Version>${project.version}</Implementation-Version>
<Specification-Title>${project.name} Library</Specification-Title>
<Specification-Version>${project.version}</Specification-Version>
<Class-Path>libs/my_file.jar</Class-Path>
</manifestEntries>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.app.MainClass</mainClass>
<classpathPrefix>libs/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<repositories>
<repository>
<id>my-local-repo</id>
<url>file:///${project.parent.basedir}/dependencies/lib</url>
</repository>
</repositories>
regardless you can add maven plugin to copy the depdencies from m2
to the same directory with this plugin
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<copyPom>true</copyPom>
<!-- <addParentPoms>true</addParentPoms>-->
<outputDirectory>${project.basedir}/../dependencies/lib/</outputDirectory>
<!-- <useSubDirectoryPerArtifact>true</useSubDirectoryPerArtifact>-->
<useRepositoryLayout>true</useRepositoryLayout>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptors>
<descriptor>repository.xml</descriptor>
</descriptors>
</configuration>
</plugin>

Maven custom directory structure - no sources to compile despite specifying sourceDirectory

I am using a custom directory structure and have specified the directory in sourcedirectory tag. But still I get the message No sources to compile. Although the build is successful.
My directory structure:
So instead of src/main/java, I am using java. (And I have a reason to do that, so right now it's not possible to switch to src/main/java)
Here's my pom.xml:
<artifactId>application</artifactId>
<name>application</name>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.test.skip>true</maven.test.skip>
</properties>
<build>
<sourceDirectory>java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<excludes>
<exclude>**/old/**/*.java</exclude>
</excludes>
<includes>
<include>java/com/**/*.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<excludes>
<exclude>**/old/**/*.java</exclude>
</excludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.start.Start</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
When I run command mvn clean package, I get following output:
The source is not compiled and resultant jar is empty. All the sources I have referred for using custom directory structure with maven say that using sourceDirectory should solve the problem. But in my case it doesn't solve
EDIT
I am using custom directory structure as using standar directory structure did not work for me. Hers' my question related to that:
Getting error in linking a source folder in eclipse maven
EDIT2:
I am linking source in java directory. That is, on the file system, application->java does not exist, but in eclipse through link source option, I have added the Java source folder from a different directory. Therefore it appears in eclipse. Also I have run maven commands with mvn command line as well as through eclipse.
If I understand your issue correctly, You have an application folder and the actual source (java) folder is from somewhere else in the file system.
And you linked the external folder as java source through eclipse for compilation.
By linking in Eclipse, maven will not automatically know where the source files are. Maven follows standard directory structure for looking up java and test files.
You can use this Build Helper plugin to customize the way maven looks up sources.
An example talked here
This is your problem: <include>java/com/**/*.java</include>
You should not include the sourcedirectory, just the paths relative to it.
Follow these steps of this working example and compare it step by step with your project to figure out what's wrong:
create a folder.
create inside the folder a pom.xml with the following content:
<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.yourdomain.yourproject</groupId>
<artifactId>yourapp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>yourapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.javadoc.skip>true</maven.javadoc.skip>
</properties>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.yourdomain.yourproject.content.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</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-release-plugin</artifactId>
<version>2.5.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<dependencies>
<dependency>
<groupId>org.jvnet.wagon-svn</groupId>
<artifactId>wagon-svn</artifactId>
<version>1.12</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
create this folder structure inside your root folder:
src/main/java/com/yourdomain/yourproject/content/
create a Main.java in content folder with the following content:
package com.yourdomain.yourproject.content;
public class Main
{
public static void main(String[] args)
{
System.out.println("HELLO");
}
}
go back to your root folder and execute mvn clean install
a target folder will be created with the jar in there.
you can execute it with java -jar target/yourapp-1.0-SNAPSHOT.jar

How to include jars of Eclipse project's classpath in pom.xml

I have an Eclipse Maven project with a Referenced Libraries folder. This folder contains the same jars that are included in project's actual classpath. To compile the project using Maven, when I use
mvn clean install
it cannot get the jars which are in classpath. So I tried using the following
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Whenever I try to compile, it gives me errors stating that it could not find the classes, those classes which I have already added on the classpath of the project.
I also tried
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<includes>
<include>/Referenced Libraries</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
but it doesn't do anything. What am I doing wrong ? How do I make the pom.xml file to get jars from the project's classpath in order to compile the project? Any help will be appreciated please. Thank You.

How to instruct maven to automatically add dependency jars when they include a artifact that i created?

Well i have reusable code which i developed using Maven and the result artifact is a JAR.
Now to use it in another project , i have simply added the this dependency to that project's POM.xml,
but maven is not auto detecting and including the dependencies for the jar.
How do i go about do this ?
Appreciate any pointers in this regard .
You should try to build the developed(reusable) code with dependencies. I'm not quite sure if this will help (I had some issues with the build with dependencies, too), but I think it's worth a try.
So you should add this to the pom.xml (of the reusable project):
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
For details, have a look at this question and the maven-documenation
I solved this by manually adding the pom file for the jar I created.
[file structure]
GroupIdFolder
ArtifactIdFolder
VersionFolder
ownjar.jar [artifact I created]
ownjar.pom [file I mannually created]
Then in the .pom file put in the dependencies.
<project>
<dependencies>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
</project>

Categories