Ivy doesn't find my artifact in filesystem - ivy

I've got an artifact in my local filesystem, but Ivy doesn't resolve it unless I put the <filesystem> resolver inside a <chain>. And it renames the artifact extension when it resolves it.
Here's my ivy.xml:
<ivy-module version="2.0">
<info organisation="apache" module="hello-ivy"/>
<dependencies>
<dependency org="myorg" name="mymodule" rev="1.1-SNAPSHOT"/>
</dependencies>
</ivy-module>
And here's my ivysettings.xml:
<ivysettings>
<settings />
<resolvers>
<filesystem name="local">
<artifact pattern="/path/to/my/artifact/[module]/dist/[module]-[revision].zip" />
</filesystem>
</resolvers>
</ivysettings>
My build.xml:
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="hello-ivy" default="deps">
<target name="deps" description="--> retrieve dependencies with ivy">
<ivy:settings file="ivysettings.xml"/>
<ivy:resolve />
<ivy:retrieve />
</target>
</project>
The artifact is a .zip file. It's in the right place and named correctly (in accordance with the <artifact>'s pattern attribute. But when I run ant, it fails to resolve the artifact:
[ivy:resolve] :::: WARNINGS
[ivy:resolve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve] :: UNRESOLVED DEPENDENCIES ::
[ivy:resolve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve] :: myorg#mymodule;1.1-SNAPSHOT: no resolver found for myorg#mymodule: check your configuration
[ivy:resolve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve] :::: ERRORS
[ivy:resolve] unknown resolver null
[ivy:resolve] no resolver found for myorg#mymodule: check your configuration
Why doesn't it find my module?
Then: if I put the <filesystem> element inside a <chain> element, it resolves:
[ivy:resolve] found myorg#mymodule;1.1-SNAPSHOT in local
[ivy:resolve] downloading /path/to/my/artifact/mymodule/dist/mymodule-1.1-SNAPSHOT.zip
[ivy:resolve] ..................(lots of dots here).....(37899kB)
[ivy:resolve] [SUCCESSFUL ] myorg#mymodule;1.1-SNAPSHOT!mymodule.jar (430ms)
So that's strange. Why did the <chain> make a difference?
And BTW, why is my module now a JAR??? The source is a ZIP file, I swear. It's the right one, too - I just rebuilt the ZIP, and the latest changes are in my JAR file. Why did Ivy rename it?

The default type of an artifact in ivy is jar and the default extension is jar, too.
This will lead to the renaming.
You have to define your dependency like this (explicitly define the artifact):
<dependency org="myorg" name="mymodule" rev="1.1-SNAPSHOT">
<artifact name="mymodule" type="zip" conf="A,B"/>
</dependency>
But you have to define the filesystem resolver properly:
<filesystem name="local">
<artifact pattern="/path/to/my/artifact/[module]/dist/[module]-[revision].[ext]" />
</filesystem>
The best approach would be to define a proper ivy.xml for your special dependency, which clearly defines what artifacts are available. And put this in your dist folder.
See:
https://ant.apache.org/ivy/history/latest-milestone/ivyfile/publications.html
https://ant.apache.org/ivy/history/latest-milestone/ivyfile/artifact.html
And it is often a good idea to run ant with ant -v when debugging ivy. This will give great additional infos.

Related

Why does Artifactory require an explicit artifact for some Ivy dependencies

I have an Artifactory server that I use to resolve Ivy dependencies. When I want to add a dependency to my ivy.xml, I sometimes have to add an explicit nested <artifact> tag, and I don't understand why.
Example A:
<dependency org="com.google" name="guava" rev="[7,)" conf="compile,runtime" />
Example B
<dependency org="com.twelvemonkeys.common" name="common-image" rev="3.0.1" conf="compile,runtime">
<artifact name="common-image" ext="jar"/>
</dependency>
Looking at the cached dependencies in the Artifactory tree view, there's nothing that indicates that the last example should need extra info to resolve the dependency, but Artifactory suggests it itself, and the resolution doesn't work without out.
I'm using Ivy against a repository with Maven layout. My settings where generated by Artifactory and look something like:
<?xml version="1.0" encoding="UTF-8"?>
<ivy-settings>
<settings defaultResolver="main" />
<resolvers>
<chain name="main">
<ibiblio
name="public"
m2compatible="true"
root="http://example.org/artifactory/remote-repos" />
</chain>
</resolvers>
</ivy-settings>
Why does Artifactory require an explicit artifact for some Ivy dependencies and not for others?
Edit 20151005: Added Ivy settings example
The tool performing the dependency resolution is the Ivy client and not Artifactory.
Based on the dependency deceleration the Ivy resolver decides which artifact to request from the repository (in your case it is Artifactory).
The artifact feature provides more control on a dependency for which you do not control its ivy file.
It enables to specify the artifacts required, if the dependency has no ivy file.
For more information about the artifact feature and when it should be used consult the Ivy documentation.

ivy and artifactory resolving failure

Having a small issue with ivy, artifactory and the spring repo. I was attempting to use:
<dependency org="org.springframework.ldap" name="spring-ldap-core" rev="1.3.2.RELEASE" conf="compile->default"/>
<dependency org="org.springframework.ldap" name="spring-ldap" rev="1.3.2.RELEASE" conf="compile->default"/>
with ivy settings:
<resolvers>
<filesystem name="local">
<ivy pattern="${repository.dir}/[module]/ivy.xml" />
<artifact pattern="${repository.dir}/[module]/[artifact].[ext]" />
</filesystem>
<chain name="chain">
<resolver ref="local"/>
<ibiblio name="artifactory-spring" m2compatible="true" root="http://artifactory.xxx.com:8081/artifactory/spring-release"/>
<ibiblio name="artifactory" m2compatible="true" root="http://artifactory.xxx.com:8081/artifactory/repo1"/>
</chain>
</resolvers>
However, I'm getting errors (ant publish -verbose mode)
[ivy:cachepath] CLIENT ERROR: Not Found url=http://artifactory.xxx.com:8081/artifactory/spring-release/spring-ldap/jars/spring-ldap-1.3.2.RELEASE.jar
[ivy:cachepath] artifactory-spring: no ivy file nor artifact found for org.springframework.ldap#spring-ldap;1.3.2.RELEASE
[ivy:cachepath] tried http://artifactory.xxx.com:8081/artifactory/repo1/org/springframework/ldap/spring-ldap/1.3.2.RELEASE/spring-ldap-1.3.2.RELEASE.pom
[ivy:cachepath] CLIENT ERROR: Not Found url=http://artifactory.xxx.com:8081/artifactory/repo1/org/springframework/ldap/spring-ldap/1.3.2.RELEASE/spring-ldap-1.3.2.RELEASE.pom
[ivy:cachepath] tried http://artifactory.xxx.com:8081/artifactory/repo1/org/springframework/ldap/spring-ldap/1.3.2.RELEASE/spring-ldap-1.3.2.RELEASE.jar
[ivy:cachepath] CLIENT ERROR: Not Found url=http://artifactory.xxx.com:8081/artifactory/repo1/org/springframework/ldap/spring-ldap/1.3.2.RELEASE/spring-ldap-1.3.2.RELEASE.jar
indicating that repo1 doesn't have version 1.3.2 and the spring maven repo doesn't have the pom or anything. How do I get ivy (or maybe artifactory?) to deal with the spring maven repo properly? I'm guessing the spring repo is simply not m2compatible, though I've tried flagging the ibiblio setting to false for this.
Thanks!
You have configured your settings file to download from the non-existent "xxx.com" domain.
Good news is that you don't need a settings file at all, by default ivy will download from the Maven Central repository.
Bad news is that there is no 1.3.2.RELEASE version of the spring-ldap artifact:
spring-ldap versons
spring-ldap-code versions
The following ivy file works:
<dependency org="org.springframework.ldap" name="spring-ldap-core" rev="1.3.2.RELEASE" conf="compile->default"/>
<dependency org="org.springframework.ldap" name="spring-ldap" rev="1.3.1.RELEASE" conf="compile->default"/>

Ivy Resolver Namespaces and the Resolve task

I am working with two ivy repositories that have inconsistent naming, I am looking at using namespaces to help with the mappings, but do namespaces affect operations besides "install" such as "resolve"?
I just found the namespace doco in the manual.... I think this approach would be overly complex.
I suggest creating two repository declarations as follows, with the appropriate file system pattern:
<ivysettings>
<settings defaultResolver="central"/>
<resolvers>
<!-- Default resolver used to resolve 3rd party software from Maven Central -->
<ibiblio name="central" m2compatible="true"/>
<!-- Team1's repository. ivy and artifact patterns can be customized -->
<filesystem name="team1-repo">
<ivy pattern="${ivy.settings.dir}/repo/1/[organisation]/[module]/ivys/ivy-[revision].xml"/>
<artifact pattern="${ivy.settings.dir}/repo/1/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
<!-- Team2's repository. ivy and artifact patterns can be customized -->
<filesystem name="team2-repo">
<ivy pattern="${ivy.settings.dir}/repo/2/[organisation]/[module]/ivys/ivy-[revision].xml"/>
<artifact pattern="${ivy.settings.dir}/repo/2/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
</resolvers>
<!-- This optional section tells which resolver to use.
Alternative setup a chain resolver above -->
<modules>
<module organisation="team1" name=".*" resolver="team1-repo" />
<module organisation="team2" name=".*" resolver="team2-repo" />
</modules>
</ivysettings>
Notes:
Obviously this example could be updated to use url resolvers if the ivy repository is located remotely.

Spring Framework dependency not resolved in Ivy

I am trying to download Spring Batch and Spring Framework using Ivy, and I'm not getting very far.
Dependencies in ivy.xml:
<dependency org="org.springframework.batch" name="org.springframework.batch.core" rev="2.1.6.RELEASE" />
<dependency org="org.springframework" name="org.springframework.spring-library" rev="3.0.6.RELEASE" />
ivysettings.xml:
<ivysettings>
<settings defaultResolver="chained"/>
<resolvers>
<chain name="chained">
<url name="com.springsource.repository.bundles.release">
<ivy pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<url name="com.springsource.repository.bundles.external">
<ivy pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
</chain>
</resolvers>
</ivysettings>
build.xml:
...
<ivy:settings file="ivysettings.xml"/>
...
<target name="resolve" description="retrieve dependencies with ivy">
<ivy:retrieve/>
</target>
When I run ant resolve I get the following:
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: UNRESOLVED DEPENDENCIES ::
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: org.springframework#org.springframework.spring-library;3.0.6.RELEASE: not found
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
What am I doing wrong? I've used this page for getting the configuration.
Spring libraries are now published via Maven Central. This means they can be found using the Maven search website:
Spring Framework
Spring Batch
This means you need to declare your dependencies as follows:
<dependency org="org.springframework.batch" name="spring-batch-core" rev="2.1.8.RELEASE"/>
<dependency org="org.springframework" name="spring-core" rev="3.0.6.RELEASE"/>
A settings file now becomes optional (Maven Central is an ivy default).
If you want to create one, use the following:
<ivysettings>
<settings defaultResolver="central"/>
<resolvers>
<ibiblio name="central" m2compatible="true"/>
</resolvers>
</ivysettings>

Issues using ivy

I am new bie to ivy.
I am using packager resolver and that packager resolver resolves the zip file, unzip it, extracts the jar file from it in temp build file, but it stays temporarily and only the jar file which i specified as a module name gets copied to destination rest of all are ignored. Is there a way i can get all the jar files? I use preseverBuildDirectories but is there a better way to do it?
Also is it possible for me to publish an artifact to svn using normal ivy? I got error while i was trying to use ivy 2.1.0 on XP using ant 1.8.0 java.illegalArguementException saying authorization failed. Is there a way i can work through ivy:publish?
Is there a way i can use ivy variable in packager.xml?
Thanks in advance,
Almas
1) Packager resolver
You need to include an ivy file for the repackaged module listing all the artifacts.
Here's my example that downloads the files associated with the Solr distribution
ivysettings.xml
<ivysettings>
<settings defaultResolver="maven2"/>
<caches defaultCacheDir="${user.home}/.ivy2/cache"/>
<resolvers>
<ibiblio name="maven2" m2compatible="true"/>
<packager name="repackage" buildRoot="${user.home}/.ivy2/packager/build" resourceCache="${user.home}/.ivy2/packager/cache" preserveBuildDirectories="false">
<ivy pattern="file:///${ivy.settings.dir}/packager/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="file:///${ivy.settings.dir}/packager/[organisation]/[module]/packager-[revision].xml"/>
</packager>
</resolvers>
<modules>
<module organisation="org.apache.solr" name="solr" resolver="repackage"/>
</modules>
</ivysettings>
Note how the packager resolver specifies a path to both an ivy and packager file.
The ivy file specifies the artifacts that are part of the package in the publications section.
packager/org.apache.solr/solr/ivy-1.4.0.xml
<ivy-module version="2.0">
<info organisation="org.apache.solr" module="solr" revision="1.4.0"/>
<configurations>
<conf name="jars" description="Jars released with SOLR distribution"/>
<conf name="webapps" description="Web applications"/>
</configurations>
<publications>
<!-- jars -->
<artifact name="solr-cell" conf="jars"/>
<artifact name="solr-clustering" conf="jars"/>
<artifact name="solr-core" conf="jars"/>
<artifact name="solr-dataimporthandler" conf="jars"/>
<artifact name="solr-dataimporthandler-extras" conf="jars"/>
<!-- webapps -->
<artifact name="solr" type="war" conf="webapps"/>
</publications>
</ivy-module>
The packager file contains the logic that copies out each artifact listed in the ivy file for the solr module.
packager/org.apache.solr/solr/packager-1.4.0.xml
<packager-module version="1.0">
<property name="name" value="${ivy.packager.module}"/>
<property name="version" value="${ivy.packager.revision}"/>
<resource dest="archive" url="http://ftp.heanet.ie/mirrors/www.apache.org/dist/lucene/solr/1.4.0/apache-solr-1.4.0.tgz" sha1="521d4d7ce536dd16c424a11ae8837b65e6b7bd2d">
<url href="http://www.apache.org/dist/lucene/solr/1.4.0/apache-solr-1.4.0.tgz"/>
</resource>
<build>
<!-- Jar artifacts -->
<move file="archive/apache-${name}-${version}/dist/apache-${name}-cell-${version}.jar" tofile="artifacts/jars/${name}-cell.jar"/>
<move file="archive/apache-${name}-${version}/dist/apache-${name}-clustering-${version}.jar" tofile="artifacts/jars/${name}-clustering.jar"/>
<move file="archive/apache-${name}-${version}/dist/apache-${name}-core-${version}.jar" tofile="artifacts/jars/${name}-core.jar"/>
<move file="archive/apache-${name}-${version}/dist/apache-${name}-dataimporthandler-${version}.jar" tofile="artifacts/jars/${name}-dataimporthandler.jar"/>
<move file="archive/apache-${name}-${version}/dist/apache-${name}-dataimporthandler-extras-${version}.jar" tofile="artifacts/jars/${name}-dataimporthandler-extras.jar"/>
<!-- War artifacts -->
<move file="archive/apache-${name}-${version}/dist/apache-${name}-${version}.war" tofile="artifacts/wars/${name}.war"/>
</build>
</packager-module>
2) Publish to subversion
I've never used it myself but I think you need to configure the subversion resolver and use this to publish your artifacts
3) Using ivy variable in packager file
The packager file listed above uses two ivy variables. Not sure what your question is.
Update: Supporting 3rd party jars
The publications section of the ivy file include the version number in the name of the 3rd party jar:
ivy file
..
<publications>
<artifact name="abc-1.0" conf="jars"/>
<artifact name="pqr-2.0" conf="jars"/>
</publications>
..
packager file
..
<build>
<move file="archive/apache-${name}-${version}/dist/abc-1.0.jar" tofile="artifacts/jars/abc-1.0.jar"/>
<move file="archive/apache-${name}-${version}/dist/pqr-2.0.jar" tofile="artifacts/jars/pqr-2.0.jar"/>
</build>
..