在使用 IVY 的项目中包含来自文件系统的项目 JAR 无法提取源代码和 javadoc

Posted

技术标签:

【中文标题】在使用 IVY 的项目中包含来自文件系统的项目 JAR 无法提取源代码和 javadoc【英文标题】:Include a project JAR from filesystem in project using IVY fails to pull in sources and javadoc 【发布时间】:2014-11-18 15:13:24 【问题描述】:

所以我在一天的大部分时间里都在尝试这个,而且我已经很接近了。我有两个项目,我想将一个作为 JAR 发布到共享文件位置,然后将其拉入另一个项目,包括我生成的源文件和 javadoc .jar 文件。实际的ivy:publish 是成功的,并且文件在远程文件系统中正确创建。

但是,当尝试在我的第二个项目中包含 JAR 时,我只能拉入基础 JAR,而不是包含源代码和 javadoc 的 JAR。

我的文件命名如下:[projectname]-[version](-[classifier]) 所以在远程位置我得到foo-1.0.0.jarfoo-1.0.0-sources.jarfoo-1.0.0-javadoc.jarivy-1.0.0.xml 以及.sha.md5 每个JAR 文件,但我的常春藤只拉foo-1.0.0.jar

我想强调的是,我已经成功地自动从 mavenrepo 远程存储库中提取了源代码和 javadocs,而且效果非常好。我只是不明白为什么它在找到并从文件系统中很好地拉下类 JAR 时拒绝将源和 javadoc JAR 拉入 IVY 缓存。

这是我用来从远程文件系统中提取文件的解析器模式:

/path/to/remote/location/[organisation]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]

我用来将文件推送到共享位置的模式是:

/path/to/remote/location/[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]

我一直在搜索人们拥有的文档和示例,但文档也可能是用克林贡语编写的,因为它具有所有意义,并且示例来自 2010 年,或者不从文件系统中获取源代码.

想法:

这不是权限问题(如果是,IVY 将无法下拉任何内容) 不是连接问题(见上文) 我发布项目的方式可能存在问题(如果您认为是这种情况,我可以根据要求提供更多详细信息) 我怀疑 IVY 根本没有拉下(或似乎读取)远程文件系统上的 ivy-1.0.0.xml 文件。毕竟,这就是我声明源和 javadoc JAR 存在的地方。 不只是这个项目,我尝试对第三个项目遵循相同的过程,只是让 IVY 只从远程文件系统中获取类 .jar 文件。 我可能没有以 IVY 期望读取的方式创建/命名文件。我查看了 mavencentral 中使用的文件结构,并试图复制他们如何命名和布置文件,但它不起作用。

我尝试过的:

几乎所有我能想到的 IVY 模式组合。 反复删除缓存文件以查看IVY是否正确解析远程文件系统中的所有文件(它没有,它只是重新抓取类JAR并在缓存目录中生成一个ivy-1.0.0.xml文件)李>

很高兴发布配置并明确说明我在做什么,如果你想要我等等,只需发表评论并询问你想要什么。

IVY 配置在第二个项目中:

<ivy-conf>

    <property name="ivy.shared.dir"
    value="/path/to/remote/repo/maven-repo/shared" />

    <property name="ibiblio-maven2-root" value="http://repo1.maven.org/maven2/"
    override="false" />

    <property name="ibiblio-spring-core-root" value="http://maven.springframework.org/"
    override="false" />

    <property name="local.pattern"
    value="[organisation]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]"/>

    <property name="maven2.pattern"
    value="[organisation]/[module]/[revision]/[module]-[revision]" />

    <property name="spring.pattern" value="org/[organisation]/[module]/[revision]/" />

    <property name="maven2.pattern.ext" value="$maven2.pattern(-[classifier]).[ext]" />

    <property name="spring.pattern.ext" value="$spring.pattern(-[classifier]).[ext]" />

    <settings defaultResolver="default" />

    <resolvers>

        <filesystem name="shared" m2compatible="true">
            <artifact pattern="$ivy.shared.dir/$local.pattern" />
        </filesystem>

        <ibiblio name="maven2" root="$ibiblio-maven2-root" pattern="$maven2.pattern.ext"
        m2compatible="true" />

        <ibiblio name="spring" m2compatible="true" pattern="$spring.pattern.ext"
        root="$ibiblio-spring-core-root" />


        <chain name="internal">
            <resolver ref="shared" />
        </chain>

        <chain name="external">
            <resolver ref="maven2" />
            <resolver ref="spring" />
        </chain>

        <chain name="default" returnFirst="true">
            <chain ref="external" />
            <chain ref="internal" />
        </chain>

    </resolvers>

    <modules>
        <module organisation="company.com.au" name="name"
        resolver="default" />
    </modules>
</ivy-conf>

两个 IVY 文件(两个项目之间)的唯一区别是这一行,它是推送到远程服务器的模式:

<property name="shared-repo" 
    value="[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />

以及将解析器中的标签更改为shared-repo

远程位置的IVY文件:

<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
    <info organisation="company" module="simple-email" revision="1.0.0" status="integration" publication="20140924154556">
    </info>

    <configurations defaultconfmapping="default">
        <conf name="compile" visibility="private"/> 
        <conf name="test" extends="compile" visibility="private"/> 
        <conf name="master"/> 
        <conf name="runtime"/> 
        <conf name="default" extends="master,runtime"/>
        <conf name="sources" visibility="public" description="this configuration contains the source artifact of this module, if any."/>
        <conf name="javadoc" visibility="public" description="this configuration contains the javadoc artifact of this module, if any."/>
    </configurations> 

    <publications>
        <artifact name="simple-email" type="jar" ext="jar" conf="master"/>
        <artifact name="simple-email" type="source" ext="jar" conf="sources" m:classifier="sources"/>
        <artifact name="simple-email" type="javadoc" ext="jar" conf="javadoc" m:classifier="javadoc"/>
    </publications>

    <dependencies>

        <!-- Unit Testing -->
        <dependency org="junit" name="junit" rev="4.8.2" conf="test->default"/>

        <!-- Log4j Logging -->
        <dependency org="log4j" name="log4j" rev="1.2.13" conf="runtime->default;test->default;compile->default"/>

        <!-- SLF Logging -->
        <dependency org="org.slf4j" name="slf4j-simple" rev="1.6.1" conf="runtime->default;compile->default;test->default"/>
        <dependency org="org.slf4j" name="slf4j-api" rev="1.6.1" conf="runtime->default;compile->default;test->default"/>

        <dependency org="javamail" name="javamail" rev="1.4" conf="runtime->default;compile->default;test->default"/>


    </dependencies>

</ivy-module>

缓存中生成的IVY文件:

<ivy-module version="2.0">
    <info organisation="company"
    module="simple-email"
    revision="1.0.0"
    status="release"
    publication="20140924162544"
    default="true"
/>
    <configurations>
        <conf name="default" visibility="public"/>
    </configurations>
    <publications>
        <artifact name="simple-email" type="jar" ext="jar" conf="default"/>
    </publications>
</ivy-module>

远程服务器上的目录结构:

Org
|--Module
    |--Version
      |--ivy-1.0.0.xml
      |--ivy-1.0.0.md5
      |--ivy-1.0.0.sha
      |--simple-email-1.0.0-javadoc.jar
      |--simple-email-1.0.0-javadoc.jar.md5
      |--simple-email-1.0.0-javadoc.jar.sha
      |--simple-email-1.0.0-sources.jar
      |--simple-email-1.0.0-sources.jar.md5
      |--simple-email-1.0.0-sources.jar.sha
      |--simple-email-1.0.0.jar
      |--simple-email-1.0.0.jar.md5
      |--simple-email-1.0.0.jar.sha

Ivy 缓存目录结构:

Org
|--Module
   |--ivy-1.0.0.xml
   |--ivydata-1.0.0.properties
   |--jars
      |--simple-email-1.0.0.jar

在 ANT 脚本上发布任务:

<target name="ivy-publish" depends="archive">
    <ivy:publish resolver="shared" pubrevision="$project.jar.version" overwrite="true">
        <artifacts pattern="$dist.dir/[artifact].[ext]"/>
    </ivy:publish>
</target>

【问题讨论】:

您需要发布您的配置和远程 ivy 文件的内容。这很可能是常春藤配置问题。您声明发布到 Maven 存储库可以正常工作。那是因为 ivy 会派生它的配置(参见:***.com/questions/7104364/…)。 我已经添加了您要求的信息,但我从未使用过 Maven,所以我不知道什么是 maven 范围或它们是如何工作的。 【参考方案1】:

说明

理论

首先,这个设置有点复杂,但也很熟悉,因为 ivy 将 Maven 模块转换为 ivy 模块。问题在于理解 Maven“范围”是如何转换为 ivy“配置”的。

How are maven scopes mapped to ivy configurations by ivy

您的远程模块

解决您的具体问题,我认为问题在于您如何下载人工制品。您的远程模块声明了以下文件:

   <publications>
        <artifact name="simple-email" type="jar" ext="jar" conf="master"/>
        <artifact name="simple-email" type="source" ext="jar" conf="sources" m:classifier="sources"/>
        <artifact name="simple-email" type="javadoc" ext="jar" conf="javadoc" m:classifier="javadoc"/>
    </publications>

神奇的部分是配置。在这种情况下,您有一个与以下配置关联的文件:

主人 来源 javadoc

其次,远程模块声明了一组相当复杂的配置。以下是与“默认”设置相关的内容:

<configurations defaultconfmapping="default">
    ..
    ..
    <conf name="master"/> 
    <conf name="runtime"/> 
    <conf name="default" extends="master,runtime"/>
    ..
    ..
</configurations> 

所以...只包括“主”人工制品。这可以解释为什么默认情况下会排除源代码,这是有道理的,因为通常用户会想要编译后的二进制文件。

ivy 如何下载人工制品

简单(我不想使用配置)

这是我们深入了解依赖映射的魔力的地方。大多数时候,用户并不关心时间。所以要忽略它们,我通常建议在每个依赖项的末尾添加一个 conf="default"

<dependency org="company" name="simple-email" rev="1.0.0" conf="default"/>

在我和远程模块之间创建以下关系:

<local "default" configuration> -> <remote "default" configuration>

换句话说,只给我默认值,即编译后的二进制文件,不包括其他更多可选的东西,如源代码和 javadoc。

使用配置

一旦您了解了配置,您就会想要在本地声明它们。例如:

<configurations>
    <conf name="compile" description="Required to compile application"/>
    <conf name="sources" description="Source code"/>
</configurations>

我们声明我们有两个桶或依赖的逻辑分组。

现在我们让我们的依赖声明更加了解我们的本地配置:

<dependency org="company" name="simple-email" rev="1.0.0" conf="compile->default;sources"/>

我们现在有 2 个映射:

<local "compile" configuration> -> <remote "default" configuration>
<local "sources" configuration> -> <remote "sources" configuration>

我们现在可以在 ANT 构建文件中单独引用或使用这些配置。例如创建一个类路径:

<ivy:cachepath pathid="compile.path" conf="compile"/>

我们使用检索任务将源 jar 放在构建目录中:

<ivy:retrieve pattern="build/src/[artifact]-[revision](-[classifier]).[ext]" conf="sources"/>

示例

在这个人为的示例中,我想将源 jar 下载到 build/src 目录中,并将编译依赖项下载到 lib 目录中:

├── build
│   └── src
│       └── log4j-1.2.17-sources.jar
├── build.xml
├── ivy.xml
└── lib
    └── log4j-1.2.17.jar

build.xml

<project name="demo" default="retrieve" xmlns:ivy="antlib:org.apache.ivy.ant">

    <target name="retrieve">
        <ivy:retrieve pattern="lib/[artifact]-[revision](-[classifier]).[ext]" conf="compile"/>
        <ivy:retrieve pattern="build/src/[artifact]-[revision](-[classifier]).[ext]" conf="sources"/>
    </target>

</project>

注意:

ivy 下载的文件被分组到“配置”中。每个检索任务都有不同的“conf”属性。 在 ivy 文件中声明配置,并在每个依赖项上定义映射。

ivy.xml

<ivy-module version="2.0">
    <info organisation="com.myspotontheweb" module="demo"/>

    <configurations>
        <conf name="compile" description="Required to compile application"/>
        <conf name="sources" description="Source code"/>
    </configurations>

    <dependencies>
        <dependency org="log4j" name="log4j" rev="1.2.17" conf="compile->default;sources" />
    </dependencies>

</ivy-module>

注意事项:

ivy 文件创建 2 个配置 神奇的是依赖项的“conf”属性。这将创建以下映射“compile->default”和“sources->sources”。这意味着编译依赖来自远程默认(通常设置),而本地源来自远程源。

【讨论】:

这一切对我半睡半醒的大脑来说都是有意义的。我必须在星期二回去工作时看看 有详细解释的cookie @JamesMassey :-) google.ie/… 您的回答帮助我发现了为什么我的源代码和 javadocs 没有被拉入。简单电子邮件项目缓存中的 ivy.xml 是默认生成的,不是从回购。关于如何让 ivy 使用远程 ivy.xml 文件而不是生成新文件的任何想法? 我将 路径添加到文件系统解析器中的 ivy 配置文件中,从而解决了问题。感谢您的帮助!

以上是关于在使用 IVY 的项目中包含来自文件系统的项目 JAR 无法提取源代码和 javadoc的主要内容,如果未能解决你的问题,请参考以下文章

如何在 subversion repo 中包含 Ivy 依赖项

在 C++ 中包含来自单独文件夹的文件

在 CMAKE 中包含来自 Android 项目的不同文件夹的静态库

如何在 Android NDK 项目中包含二进制文件?

Ivy 依赖项:log4j-api 已下载但未找到 log4j-api-java9

在项目中包含外部源代码进行调试