【问题标题】:Can I use the path to a Maven dependency as a property?我可以使用 Maven 依赖项的路径作为属性吗?
【发布时间】:2011-01-22 12:35:55
【问题描述】:

我的 pom.xml 中有一个 maven 依赖项:

<dependency>
    <groupId>com.foo</groupId>
    <artifactId>Bar</artifactId>
    <version>1.2.3</version>
</dependency>

我想使用二进制文件的系统路径作为属性(这样我就可以将它传递给由 maven 启动的外部进程)。我可以用一种尴尬的方式做到这一点:

<properties>
    <my.lib>${settings.localRepository}/com/foo/Bar/1.2.3/Bar.jar</my.lib>
</properties>

但我真的很想用更标准的机制,比如:

<properties>
    <my.lib>${com.foo:Bar:1.2.3}</my.lib>
</properties>

我这样的可能吗?

【问题讨论】:

  • 我有点困惑:如果您想将Bar.jar 称为系统库,则需要指定&lt;scope&gt;system&lt;/scope&gt;&lt;systemPath&gt;${my.lib}&lt;/systemPath&gt;,但似乎您想在其他地方使用${my.lib}。展示你想如何使用${my.lib}的完整示例...
  • @dma_k OP希望将物理路径传递给maven触发的外部进程的依赖项。

标签: maven-2


【解决方案1】:

假设 com.foo:Bar:jar:1.2.3 工件在您的 POM 中声明为依赖项,以下属性返回本地存储库中 jar 的路径:

${maven.dependency.com.foo.Bar.jar.path}

更新:这是一个简单的 POM 演示:

<?xml version="1.0" encoding="UTF-8"?>
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.stackoverflow</groupId>
  <artifactId>q2359872</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>q2359872</name>
  <properties>
    <my.lib>${maven.dependency.junit.junit.jar.path}</my.lib>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <executions>
          <execution>
            <phase>process-resources</phase>
            <configuration>
              <tasks>
                <echo>${my.lib}</echo>
              </tasks>
            </configuration>
            <goals>
              <goal>run</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

运行 mvn process-resources 会产生以下输出:

$ mvn 进程资源 [INFO] 正在扫描项目... [信息] --------------------------------------------- ------------------------- [INFO] 楼q2359872 [INFO] 任务段:[流程资源] [信息] --------------------------------------------- ------------------------- [信息] [资源:资源{执行:默认资源}] [INFO] 使用 'UTF-8' 编码复制过滤的资源。 [信息] 跳过不存在的资源目录 /home/pascal/Projects/stackoverflow/q2359872/src/main/resources [信息] [antrun:运行{执行:默认}] [INFO] 执行任务 [回声] /home/pascal/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar [INFO] 已执行的任务 [信息] --------------------------------------------- ------------------------- [信息] 构建成功 [信息] --------------------------------------------- ------------------------- [INFO] 总时间:7 秒 [INFO] 完成时间:Tue Mar 02 14:41:32 CET 2010 [INFO] 最终内存:7M/68M [信息] --------------------------------------------- -------------------------

【讨论】:

  • 我无法证明此功能在 Maven 中有效。这只适用于maven-antrun-plugin(参见jira.codehaus.org/browse/MANTRUN-110)。请提供一个完整的 pom 示例,正如我想的那样,您引用的不是&lt;project&gt;&lt;properties&gt;,而是其他一些属性。
  • @dma_k 您提到的 Jira 问题除了 antrun 文档中存在错误外没有显示任何内容。现在,您可以自己测试这个解决方案。顺便说一句,我总是测试我的答案:)
  • @Pascal 感谢您的更新!我完全相信你,它适用于你的网站 :) 我的问题是:它是否应该与 maven-antrun-plugin 结合使用。你在你的例子中展示了这一点,太棒了!从示例中我看到这是maven-antrun-plugin 特有的功能,即如果我想用${my.lib} 变量替换资源(不使用任何额外的pugin) - 我做不到,对吧?
  • @dma_k 我做了一个测试,过滤期间该属性不可用。我不知道它是否与stackoverflow.com/questions/2246524/… 中的情况相同,即是否表达式在过滤期间不可用,因为过滤和插值不共享相同的算法,或者它是否是 antrun 属性。
【解决方案2】:

您需要编写一个新的 maven 插件,将属性值设置为依赖项的完全解析路径名。 maven-dependency-plugin 不会为您执行此操作。

它将复制您的依赖项,然后您可以通过该路径名引用它。

【讨论】:

    【解决方案3】:

    这是一个正确的实现,使用maven-dependency-plugin properties goal,它可以在pom中的任何地方使用:

    <?xml version="1.0" encoding="UTF-8"?>
    <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.stackoverflow</groupId>
        <artifactId>q2359872</artifactId>
        <version>2.0-SNAPSHOT</version>
        <name>q2359872</name>
    
        <properties>
            <!-- Must be listed in the dependencies section otherwise it will be null. -->
            <my.lib>${org.jmockit:jmockit:jar}</my.lib>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.jmockit</groupId>
                <artifactId>jmockit</artifactId>
                <version>1.11</version>
            </dependency>
        </dependencies>
        <build>
            <defaultGoal>generate-sources</defaultGoal>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.3</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>properties</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <!-- Example usage: -->
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.2</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>exec</goal>
                            </goals>
                            <phase>generate-sources</phase>
                        </execution>
                    </executions>
                    <configuration>
                        <executable>echo</executable>
                        <arguments>
                            <argument>path to jar=</argument>
                            <argument>${org.jmockit:jmockit:jar}</argument>
                            <argument>my.lib=</argument>
                            <argument>${my.lib}</argument>
                        </arguments>
                    </configuration>
                </plugin>
                <!-- end of Example usage -->
            </plugins>
        </build>
    </project>
    

    输出是……

    jpyeron@black /projects/wkspc/tmp/foo
    $ /cygdrive/c/programs.x86_64/apache-software-foundation/apache-maven-3.1.1/bin/mvn
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building q2359872 2.0-SNAPSHOT
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] --- maven-dependency-plugin:2.3:properties (default) @ q2359872 ---
    [INFO]
    [INFO] --- exec-maven-plugin:1.2:exec (default) @ q2359872 ---
    path to jar= C:\Documents and Settings\jpyeron\.m2\repository\org\jmockit\jmockit\1.11\jmockit-1.11.jar my.lib= C:\Documents and Settings\jpyeron\.m2\repository\org\jmockit\jmockit\1.11\jmockit-1.11.jar
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 2.032s
    [INFO] Finished at: Wed Sep 17 12:07:18 EDT 2014
    [INFO] Final Memory: 10M/153M
    [INFO] ------------------------------------------------------------------------
    

    【讨论】:

    • 如果您的示例使用不同的依赖项,则可能不会那么混乱。对于那些感兴趣的人,如果您需要 JMockit 的 jar,您的属性将是这样的: ${org.jmockit:jmockit:jar} 也就是说: ${groupId:artifactId :jar}
    • 这应该是公认的答案。另一个是特定于 ant 插件的。
    • Jason,请提一下这里的关键是使用maven-dependency-plugin。最初我只是使用 ${org.jmockit:jmockit:jar} 语法,花了很长时间才意识到问题所在。
    • 这非常适合我的情况,我需要将 superpom 中的依赖路径解析为最新版本,允许 Maven 的版本控制逻辑为我选择最佳版本(无需猜测文件结束的位置上)。
    • 您提供的示例运行良好。我已将一个 exe 文件添加到公司仓库并将其放入 pom.xml 文件中。我也有分类器和类型标签。 ie_64exe 我在尝试运行时收到错误消息。无效文件。不知何故,${groupId:artifactId:exe} 不足以创建文件路径。
    【解决方案4】:

    如果上面的工作都没有,您总是可以使用 gmaven 积极地深入到MavenProject 对象并获取您的工件信息。就我而言,我在配置文件中声明了以下工件:

                <!-- Neo4J connector. This dependency is scoped to be usable by maven-exec-plugin 
                    which installs it in Glassfish -->
                <dependency>
                    <groupId>com.netoprise</groupId>
                    <artifactId>neo4j-connector</artifactId>
                    <version>${neo4j.connector.version}</version>
                    <type>rar</type>
                    <!-- Set in test scope to avoid release issues -->
                    <scope>test</scope>
                </dependency>
    

    为了获取它的路径并将其放入 maven 属性中,我编写了以下 gmaven 脚本:

                    <!-- Small script used to build maven property for neo4j-connector path -->
                    <plugin>
                        <groupId>org.codehaus.gmaven</groupId>
                        <artifactId>gmaven-plugin</artifactId>
                        <version>1.3</version>
                        <executions>
                            <execution>
                                <id>get-neo4j-connector-rar-path</id>
                                <phase>validate</phase>
                                <goals>
                                    <goal>execute</goal>
                                </goals>
                                <configuration>
                                    <source>
                                        <![CDATA[
    println "initial value of neo4j.connector.rarPath is \""+project.properties['neo4j.connector.rarPath']+"\""                             
    
    // Duplicate model in a Mavenproject, allowing me to get associated artifact
    // So sad I can't get the embdder object
    
    // More info here : http://maven.apache.org/ref/3.0.3/maven-core/apidocs/org/apache/maven/project/MavenProject.html
    def mavenProject = new org.apache.maven.project.MavenProject(project)
    
    // More infos on Artifact there : http://maven.apache.org/ref/3.0.3/maven-artifact/apidocs/org/apache/maven/artifact/Artifact.html
    def neo4jConnector = mavenProject.getArtifacts().find { artifact -> artifact.getArtifactId()=='neo4j-connector' }
    // Now resolve dependency to produce an artifact
    // notice maven property interpolation doesn't do toString, so we have to do it ourselves
    project.properties['neo4j.connector.rarPath'] = neo4jConnector.getFile().getAbsolutePath()
    
    println "usable neoj4Connector can be found at "+project.properties['neo4j.connector.rarPath']
    
                                        ]]>
                                    </source>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
    

    这是一种蛮力方法,但它确实比我以前在那里看到的解决方案好得多。

    【讨论】:

      【解决方案5】:

      有一个插件可能是您正在寻找的...bitstrings.org (home)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-18
        • 1970-01-01
        • 1970-01-01
        • 2020-06-02
        相关资源
        最近更新 更多