Lee
Lee

Reputation: 535

How to distribute Java application with library dependence chain?

I have a Java project Foo, it has dependence on bar.jar and its maven build is as following:

-- foo/

---- foo.jar

---- lib/

------ bar.jar

------ (other lib jars)

The foo.jar's MANIFEST.MF has field Class-Path: . lib/bar.jar ... (other lib jars) and Main-Class: com.abc.foo.Main and it can be invoked by command java -jar foo.jar

The bar.jar is created from another Java project Bar which has dependence on httpclient-4.5.jar.

So the question is, when distributing the build of Foo which contains bar.jar in its subfolder lib already, do I need to include the httpclient-4.5.jar as well?


Update: I figured out the real question I want to ask is about Transitive Dependencies. According to https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies, Maven is able to discover the lib(dependence) that your own lib requires.

In my case is that Maven can figure out foo depends on bar and bar depends on httpclient-4.5.jar, and it will grab the httpclient-4.5.jar to Project Foo's Maven Dependencies list.

This works well for most dependencies in my project, i.e. the dependencies' dependencies also appear in my Maven Dependencies. However, there is one dependency(bar.jar) that Maven does not retrieve its dependencies(httpclient-4.5.jar). That's the key issue I have right now.

Upvotes: 0

Views: 998

Answers (1)

johnnymnmonic
johnnymnmonic

Reputation: 804

You can use maven-assembly-plugin with it you can build a bundle zip for distribute you java project.

for example

in the pom.xml

<dependencies>

    <!-- foo dependencies -->
    <dependency>
        <groupId>com.company.bar</groupId>
        <artifactId>bar</artifactId>
        <version>1.0.0-RELEASE</version>
    </dependency>

</dependencies>

<build>

    <finalName>foo</finalName>

    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>

   <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>../lib/</classpathPrefix>
                        </manifest>
                        <manifestEntries>
                            <Build-Time>${maven.build.timestamp}</Build-Time>
                            <Build-Host>${agent.name}</Build-Host>
                            <Build-User>${user.name}</Build-User>
                            <Build-Maven>Maven ${maven.version}</Build-Maven>
                            <Build-Java>${java.version}</Build-Java>
                            <Build-OS>${os.name}</Build-OS>
                            <Build-Label>${project.version}</Build-Label>
                            <Build-Path>${basedir}</Build-Path>
                            <Build-Number>${buildNumber}</Build-Number>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.5.5</version>
            <executions>
                <execution>
                    <id>distro-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <descriptors>
                            <descriptor>src/main/asembly/asembly.xml</descriptor>
                        </descriptors>
                        <!-- <finalName>${project.artifactId}-${project.version}.jar</finalName> -->
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

you must give the specification of what it's in the bundle into the asembly.xml

<?xml version="1.0" encoding="UTF-8"?>
<assembly 
  xmlns="http://maven.apache.org/plugins/maven-assembly-     plugin/assembly/1.1.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">

<id>dist</id>
<formats>
    <format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
    <fileSet>
        <directory>target</directory>
        <outputDirectory>./bin/</outputDirectory>
        <includes>
            <include>foo.jar</include>
        </includes>
    </fileSet>
    <fileSet>
        <includes>
            <include>readme.txt</include>
        </includes>
    </fileSet>
</fileSets>
<dependencySets>
    <dependencySet>
        <outputDirectory>/lib/</outputDirectory>
        <useProjectArtifact>false</useProjectArtifact>
        <unpack>false</unpack>
        <scope>runtime</scope>
    </dependencySet>
</dependencySets>
</assembly>

when you do mvn clean install then in the target forlder, must appear the bundle as foo-dist.zip

in the zip you will have in the /lib folder bar.jar and every other jar declared as dependency and in the forlder /bin foo.jar.

Upvotes: 1

Related Questions