ivy:install from maven with classifiers

2020-07-11 04:48发布

问题:

I'm trying to ivy:install jogl and gluegen from maven to my local depository. I cannot get the native dependencies to install correctly.

My ivysettings is

<ivysettings>
    <settings defaultResolver="central"
            defaultConflictManager="all"
    />
    <caches defaultCacheDir="${ivy.cache.dir}"
            artifactPattern="[organisation]/[module]/[type]s/[artifact]-[revision](-[classifier]).[ext]" 
    />
    <resolvers>
        <ibiblio name="central" m2compatible="true"
                 pattern="[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"
        />
        <filesystem name="depository">
            <ivy pattern="${dest.repo.dir}/[organisation]/[module]/ivys/ivy-[revision](-[classifier]).xml" />
            <artifact pattern="${dest.repo.dir}/[organisation]/[module]/[type]s/[artifact]-[revision](-[classifier]).[ext]" />
        </filesystem>
    </resolvers>
</ivysettings>

My install target is

<ivy:install settingsRef="ivy.settings" 
    organisation="org.jogamp.jogl" module="jogl-all-main" revision="2.1.5-01"
    from="${from.resolver}" to="${to.resolver}" transitive="true" overwrite="true" />

where from.resolver is central and to.resolver is depository.

The classifiers are e.g., native-windows-i586, native-linux-armv6, etc. The pom file in question is at http://repo1.maven.org/maven2/org/jogamp/jogl/jogl-all-main/2.1.5-01/jogl-all-main-2.1.5-01.pom

I correctly resolve jogl-all-main. When the dependencies are resolved, only the last one in the pom file is resolved, namely jogl-all-2.1.5-01-natives-windows-i586.jar. Is there any way to use the ivy:install task to install to my local depository from the maven central repository?

回答1:

The short answer is that ivy has very limited support for additional artifact files associated with a Maven module.

I apologise for repeating myself, but you are best advised to run a Maven repository manager to cache remote Maven repositories. This avoids the necessity to compromise between differing formats.

Origin behind this restriction

A remote Maven POM does not explicitly list its module's artifacts. There is no limit on the number of possible classifier values.... The only assumption that can be made is that the module might contain an additional "javadoc" or "sources" artifact. (Common in open source projects).

The Maven documentation describes classifiers as follows:

classifier: The classifier allows to distinguish artifacts that were built from the same POM but differ in their content. It is some optional and arbitrary string that - if present - is appended to the artifact name just after the version number.

As a motivation for this element, consider for example a project that offers an artifact targeting JRE 1.5 but at the same time also an artifact that still supports JRE 1.4. The first artifact could be equipped with the classifier jdk15 and the second one with jdk14 such that clients can choose which one to use.

Another common use case for classifiers is the need to attach secondary artifacts to the project’s main artifact. If you browse the Maven central repository, you will notice that the classifiers sources and javadoc are used to deploy the project source code and API docs along with the packaged class files.

Ivy repositories work differently. The module's ivy file has a publications section that explicitly lists the module's contents.

For a greater insight into how ivy interprets Maven repositories I would recommend the following posting.

  • How are maven scopes mapped to ivy configurations by ivy

Possible work-around

The following example uses the retrieve task to write out the downloaded dependencies into the desired repository format. The result is missing checksum files, but that may not matter.

├── build.xml
├── ivy.xml
└── target
    └── repo
        └── org
            └── jogamp
                └── jogl
                    ├── jogl-all
                    │   └── 2.1.5-01
                    │       ├── jogl-all-2.1.5-01.jar
                    │       ├── jogl-all-2.1.5-01-javadoc.jar
                    │       ├── jogl-all-2.1.5-01-natives-android-armv6.jar
                    │       ├── jogl-all-2.1.5-01-natives-linux-amd64.jar
                    │       ├── jogl-all-2.1.5-01-natives-linux-armv6hf.jar
                    │       ├── jogl-all-2.1.5-01-natives-linux-armv6.jar
                    │       ├── jogl-all-2.1.5-01-natives-linux-i586.jar
                    │       ├── jogl-all-2.1.5-01-natives-macosx-universal.jar
                    │       ├── jogl-all-2.1.5-01-natives-solaris-amd64.jar
                    │       ├── jogl-all-2.1.5-01-natives-solaris-i586.jar
                    │       ├── jogl-all-2.1.5-01-natives-windows-amd64.jar
                    │       ├── jogl-all-2.1.5-01-natives-windows-i586.jar
                    │       └── jogl-all-2.1.5-01-sources.jar
                    └── jogl-all-main
                        └── 2.1.5-01
                            ├── jogl-all-main-2.1.5-01.jar
                            ├── jogl-all-main-2.1.5-01-javadoc.jar
                            └── jogl-all-main-2.1.5-01-sources.jar

ivy.xml

<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
    <info organisation="com.myspotontheweb" module="demo"/>

    <configurations>
        <conf name="repo" description="Artifacts that make up local repository"/>
    </configurations>

    <dependencies>
        <dependency org="org.jogamp.jogl" name="jogl-all-main" rev="2.1.5-01" conf="repo->default">
            <artifact name="jogl-all-main"/>
            <artifact name="jogl-all-main" e:classifier="sources"/>
            <artifact name="jogl-all-main" e:classifier="javadoc"/>
        </dependency>

        <dependency org="org.jogamp.jogl" name="jogl-all" rev="2.1.5-01" conf="repo->default">
            <artifact name="jogl-all"/>
            <artifact name="jogl-all" e:classifier="sources"/>
            <artifact name="jogl-all" e:classifier="javadoc"/>
            <artifact name="jogl-all" e:classifier="natives-android-armv6"/>
            <artifact name="jogl-all" e:classifier="natives-linux-amd64"/>
            <artifact name="jogl-all" e:classifier="natives-linux-armv6"/>
            <artifact name="jogl-all" e:classifier="natives-linux-armv6hf"/>
            <artifact name="jogl-all" e:classifier="natives-linux-i586"/>
            <artifact name="jogl-all" e:classifier="natives-macosx-universal"/>
            <artifact name="jogl-all" e:classifier="natives-solaris-amd64"/>
            <artifact name="jogl-all" e:classifier="natives-solaris-i586"/>
            <artifact name="jogl-all" e:classifier="natives-windows-amd64"/>
            <artifact name="jogl-all" e:classifier="natives-windows-i586"/>
        </dependency>
    </dependencies>

</ivy-module>

Notes:

  • Need to explicitly list each desired artifact to be downloaded. As stated eariler only the "javadoc" and "sources" classifiers can be assumed.

build.xml

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

    <!--
    ================
    Build properties
    ================
    -->
    <property name="repo.dir" location="target"/>

    <!--
    ===========
    Build repo
    ===========
    -->
    <target name="install" description="Download and install dependencies">
        <ivy:retrieve pattern="${repo.dir}/[conf]/[orgPath]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"/>
    </target>

</project>