【问题标题】:How to distribute Java application with library dependence chain?如何使用库依赖链分发 Java 应用程序?
【发布时间】:2016-09-15 08:56:48
【问题描述】:

我有一个Java项目Foo,它依赖于bar.jar,它的maven构建如下:

-- foo/

---- foo.jar

---- 库/

------bar.jar

------(其他 lib jars)

foo.jar 的 MANIFEST.MF 有字段Class-Path: . lib/bar.jar ... (other lib jars)Main-Class: com.abc.foo.Main 可以通过命令java -jar foo.jar 调用

bar.jar 是从另一个依赖于 httpclient-4.5.jar 的 Java 项目 Bar 创建的。

所以问题是,在分发已经在其子文件夹 lib 中包含 bar.jar 的 Foo 构建时,我是否还需要包含 httpclient-4.5.jar?


更新: 我发现我想问的真正问题是关于传递依赖的。根据https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies,Maven 能够发现您自己的库所需的库(依赖)。

在我的例子中,Maven 可以确定 foo 依赖于 bar,而 bar 依赖于 httpclient-4.5.jar,它会将 httpclient-4.5.jar 抓取到 Project Foo 的 Maven 依赖项列表中。

这适用于我项目中的大多数依赖项,即依赖项的依赖项也出现在我的 Maven 依赖项中。但是,有一个依赖项(bar.jar),Maven 不会检索其依赖项(httpclient-4.5.jar)。这是我现在面临的关键问题。

【问题讨论】:

    标签: java maven jar dependencies


    【解决方案1】:

    您可以使用 ma​​ven-assembly-plugin 与它一起构建一个捆绑 zip 来分发您的 java 项目。

    例如

    在 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>
    

    你必须在 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>
    

    当您在目标文件夹中执行 mvn clean install 时,捆绑包必须显示为 foo-dist.zip

    在 zip 中,您将在 /lib 文件夹 bar.jar 和声明为依赖项的所有其他 jar 以及 forlder /bin foo.jar 中拥有。

    【讨论】:

    • 感谢您展示示例。我已经更新了我的问题。你认为 maven-assembly-plugin 还合适吗?
    • 实际上,仅当问题是制作包含所有依赖项的分发独立可执行包时才适合。阅读您的更新,问题是其他的。
    • 尝试观察 de bar.jar pom.xml 并验证 httpclient-4 工件依赖项是如何声明的,验证依赖项之间的某种冲突,或者 bar.jar pom.xml 中的声明是否准确范围也可以传递,或者不被排除等。否则,您总是可以在 foo.jar pom.xml 中包含 httpclient-4 工件作为依赖项,在这种情况下必须出现 Maven 依赖项
    • 我意识到我应该问的真正问题。将为这个更清晰的问题开始一个新的帖子。感谢您的帮助。
    • 请在stackoverflow.com/questions/39522009/…查看我的新问题。谢谢。
    猜你喜欢
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    相关资源
    最近更新 更多