在Maven程序集中为依赖项创建Symlink

时间:2014-05-16 19:26:02

标签: maven dependencies maven-assembly-plugin

我有一个Maven程序集,在解压缩tar后,会创建三个目录 每个包含一个/ lib目录。例如,

folder1/lib
folder2/lib
folder3/lib

目前,我在每个/ lib目录中打包相同的.jar。由于这是浪费空间,我想知道我是否只能拥有该.jar的一个副本,并为其他两个可以引用该.jar的位置创建类似符号链接的内容?

谢谢!

3 个答案:

答案 0 :(得分:4)

对于非常类似的情况,这是maven-antrun-plugin的解决方案。 Zookeeper依赖项先前由${basedir}/target/package/lib放入maven-dependency-plugin。现在我正在为${basedir}/target/package/lib/zookeeper/lib创建所有库的符号链接,这些符号链接指向上方2个。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>prepare-delivery</id>
            <phase>package</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <target>
                    <!-- Prepare zookeeper layout. -->
                    <mkdir dir="${basedir}/target/package/lib/zookeeper/lib"/>
                    <apply executable="ln" dir="${basedir}/target/package/lib/zookeeper/lib" relative="true">
                        <arg value="-s"/>
                        <srcfile prefix="../../"/>
                        <targetfile/>
                        <fileset dir="${basedir}/target/package/lib" includes="**"/>
                        <mapper type="identity"/>
                    </apply>
                </target>
            </configuration>
        </execution>
    </executions>
</plugin>

antrun的插件管理设置如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
</plugin>

答案 1 :(得分:2)

我认为这在Maven包装和装配中是不受支持的。 Another Stack Overflow question from just a year ago asked the same thing得到了“不支持”的答案。此功能已经有两个JIRA(至少)已经开放了很长时间:one for the assembly pluginone for Plexus components。我想说这种直接支持的可能性并不好。

仅供参考,如果我说“源项目”,我将引用组装tar的项目。如果我说“目的地项目”,我的意思是解开焦油的人。这假设您在双方都有Maven项目 - 如果这个假设是错误的,您应该依靠命令行实用程序为您进行定位或解压缩。

因为听起来像是在Maven构建的上下文中解压缩tar,所以有办法解决这个问题。据我所知,如果符号链接对您很重要,那么最佳解决方案是使用junction plugin,exec-maven-plugin或maven-antrun-plugin。

即使在Windows上,联结插件也具有便携的优点。问题是进行解包的项目必须明确了解tar原始结构的结构,这通常是不可取的,因为如果改变了预期的符号,它现在必须更新。该插件似乎也很难维护,所以就是这样。

exec插件允许您调用命令行实用程序或脚本来进行链接,但是您必须使用配置文件来获取跨平台功能。这样做的最大好处是,执行拆包的项目完全不知道tar的原始结构。该机制的细节是一年前我提到的问题。

对于我的项目,我可能会对Ant的symlink task使用antrun - 可以让Ant将所有符号链接记录到源端的文件中,然后将该文件与Maven一起打包。然后,接收项目可以检查文件并重新创建其符号链接。这允许用于tar分发的符号链接从其源项目更改而不对目标项目进行任何更改。我的项目只支持OS X和Linux,所以这是可以接受的 - 您需要决定哪种方法最适合您。

在任何一种情况下,您都会遇到这样的情况:执行拆包的项目必须知道tar在打包之前的方式。

答案 2 :(得分:1)

您可以使用ant-run插件的符号链接任务/目标

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
        <execution>
            <phase>package</phase>
            <configuration>
                <target>
                    <symlink link="folder2/lib/${project.artifactId}-${project.version}.jar"
                             resource="folder1/lib/${project.artifactId}-${project.version}.jar"/>
                    <symlink link="folder3/lib/${project.artifactId}-${project.version}.jar"
                             resource="folder1/lib/${project.artifactId}-${project.version}.jar"/>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

如果希望符号链接具有相对路径,则可以在资源中提供相对路径,如下所示

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
        <execution>
            <phase>package</phase>
            <configuration>
                <target>
                    <symlink link="folder2/lib/${project.artifactId}-${project.version}.jar"
                             resource="../../folder1/lib/${project.artifactId}-${project.version}.jar"/>
                    <symlink link="folder3/lib/${project.artifactId}-${project.version}.jar"
                             resource="../../folder1/lib/${project.artifactId}-${project.version}.jar"/>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>