ivy:install from maven with classifiers
Asked Answered
P

1

10

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?

Phobe answered 24/7, 2014 at 20:11 Comment(2)
I would highly recommend installing a Maven repository manager (like Nexus or Artifactory) to proxy and cache 3rd party repositories like Maven Central. Substantially simpler solution.Aftershock
@Mark Thanks for the suggestion. I'm stuck using the local ivy repository solution since all of our projects are configured that way, and updating them at this point would be a major undertaking. It hasn't been a problem until now, and if necessary, I can manually publish. I was hoping for a more elegant solution though.Phobe
A
16

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.

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>
Ardine answered 25/7, 2014 at 0:35 Comment(5)
Wow, very thorough. I will take a closer look at this tomorrow, but I appreciate the effort you put into this answer!Phobe
@Phobe In my humble opinion, Mark is totally right and his solution doesn't require to modify yet another thing within JOGL to support another build tool. JogAmp (JOGL, JOAL, JOCL) already supports Ant, Maven and Gradle. I'll quote Mark's answer in the future, I'll probably use it in JOGL user's guide.Maier
@Maier thank you for your kind words, glad to help.Aftershock
I'm not sure whether this answer will work. You are suggesting e:classifier, while you should be using maven classifier. The way to solve this problem, is to declare also the maven namespace, i.e. (xmlns:m="ant.apache.org/ivy/maven" xmlns:e="ant.apache.org/ivy/extra") , and then use m:classifier instead of e:classifier.Englebert
It seems to me that this does not set the type of the artifacts. If i run java -jar ivy-2.5.0.jar -settings settings.xml -ivy ivy.xml -types jar -cachepath cache.txt, then cache.txt contains all of the artifacts, including sources and javadoc, not just the classes jar. However, if i set both the type and ext attributes on the artifact elements, then everything works as expected.Dubuffet

© 2022 - 2024 — McMap. All rights reserved.