Error when trying to use optional token in artifacts pattern - ivy

Up until now, I was only generating a dist/imasUtils.jar file in the build (using Ant), and publiching it with the following Ant code:
<ivy:resolve/>
<ivy:publish resolver="imas-ssh" overwrite="true" publishivy="true">
<artifacts pattern="dist/[artifact].[ext]"/>
</ivy:publish>
So far, this worked, but now I want to publish also the source, so I am also generating dist/imasUtils_src.zip. According to my understanding of the ivy manual, I could do this:
<ivy:resolve/>
<ivy:publish resolver="imas-ssh" overwrite="true" publishivy="true">
<artifacts pattern="dist/[artifact](_[type]).[ext]"/>
</ivy:publish>
and that would recognize both of my files dist/imasUtils.jar and dist/imasUtils_src.zip, the only difference is that when I published them the type attribute would be null for the jar file.
Instead, I am getting the following error message:
/[myDirectory]/build.xml:119: impossible to publish artifacts for net.conselldemallorca.imas#imasUtils;1.2.0:
java.io.IOException: missing artifact net.conselldemallorca.imas#imasUtils;1.2.0!imasUtils.jar
at org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:225)
at org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:172)
at org.apache.ivy.Ivy.publish(Ivy.java:621)
at org.apache.ivy.ant.IvyPublish.doExecute(IvyPublish.java:311)
at org.apache.ivy.ant.IvyTask.execute(IvyTask.java:271)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
...
My ivy.xml file:
<ivy-module version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info organisation="net.conselldemallorca.imas"
module="imasUtils" revision="${ivy.revision}"/>
<publications>
<artifact />
</publications>
</ivy-module>
and my organization ivy-settings.xml file:
<ivysettings>
<property name="ivy.pattern" value="artifacts/[organisation]/[module]/r[revision]/ivy-[revision].xml" override="false"/>
<property name="artifact.pattern" value="artifacts/[organisation]/[module]/r[revision]/[artifact].[ext]" override="false"/>
<settings defaultResolver="shared"/>
<resolvers>
<ssh name="imas-ssh" host="MYHOST" publishPermissions="0770">
<ivy pattern="/var/www/html/Ivy/${ivy.pattern}"/>
<artifact pattern="/var/www/html/Ivy/${artifact.pattern}"/>
</ssh>
<chain name="shared">
<url name="imas">
<ivy pattern="http://ivy.proves.imasmallorca.net/Ivy/${ivy.pattern}"/>
<artifact pattern="http://ivy.proves.imasmallorca.net/Ivy/${artifact.pattern}"/>
</url>
<ibiblio name="public" m2compatible="true"/>
</chain>
</resolvers>
</ivysettings>
I am using Apache Ant 1.9.3 and Ivy 2.4.0

I suspect the problem might be the way you've defined the "type" in the pattern. You also need to declare more than one file in your ivy file's publications section.
I suggest the following change to your ivy file:
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<publications>
<artifact name="imasUtils" type="jar"/>
<artifact name="imasUtils" type="zip" e:classifier="src"/>
</publications>
And corresponding change in the publish task's pattern:
<ivy:publish .. >
<artifacts pattern="dist/[artifact](_[classifier]).[ext]"/>
</ivy:publish>
The "classifier" is an example of a custom extra attribute.
Example:
Convert ivy.xml to pom.xml
The following link provides more explanation on how ivy interacts with Maven repos which has a fixed understanding of a "sources" attribute.
how to publish 3rdparty artifacts with ivy and nexus

Related

Why can't Ivy resolve my configurations

I've got an Ivy and Artifactory setup to publish and depend on builds with.
In Artifactory I have an Ivy file along the lines of:
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info organisation="org" module="module" branch="HEAD" revision="0.277-SNAPSHOT" status="integration" publication="20140724114055">
</info>
<configurations>
<conf name="compile" visibility="public" description="Default required to compile the full module"/>
<conf name="build" visibility="public" extends="compile" description="Incorporates additional build tools onto the classpath"/>
</configurations>
<publications defaultconf="compile">
<artifact name="module" type="jar" ext="jar"/>
<artifact name="module-src" type="source" ext="zip"/>
<artifact name="module-doc" type="doc" ext="zip"/>
</publications>
<dependencies>
<dependency org="junit" name="junit" rev="4.8.1" conf="compile->*"/>
<dependency org="net.sf.proguard" name="proguard" rev="4.11" conf="build">
<artifact name="proguard" ext="jar"/>
</dependency>
</dependencies>
</ivy-module>
When I come to depend on this module in another project I specify the compile configuration but get told by IvyDE that compile does not exist.
<?xml version="1.0" encoding="ISO-8859-1"?>
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info
organisation="org"
module="module2"
status="integration">
</info>
<configurations>
<conf name="compile" description="Default required to compile the full module" />
</configurations>
<dependencies>
<dependency transitive="true" org="org" name="module" rev="latest.integration" conf="compile">
<artifact name="module" type="jar" ext="jar" />
<artifact name="module-src" type="source" ext="zip" />
<artifact name="module-doc" type="doc" ext="zip" />
</dependency>
</dependencies>
</ivy-module>
With this setup I get the error message
"configuration not found in org#module;0.277-SNAPSHOT: 'compile'"
I do get the jar if the dependency conf is updated to compile->* but I don't get the source or javadoc downloaded unless they are explicitly defined as dependencies. I am also expecting that junit will appear on the build path as it is defined as a compile dependency but there is no sign of that appearing while it doesn't know what the compile configuration is I guess.
Any suggestions please!
It seems the reason for this was Ivy not finding the ivy in artifactory correctly. Using a URL resolver rather than a ibiblio resolver and defining the ivy pattern everything is working correctly.

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.

Can't Download json-lib in Ivy

I want to download json-lib-2.3-jdk15.jar. I find ivy don't have classifier tag, so I use maven one, below is the ivy.xml
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"
xmlns:m="http://ant.apache.org/ivy/maven">
<info organisation="xxxx" module="xxx" status="integration"/>
<dependencies>
<dependency org="net.sf.json-lib" name="json-lib" rev="2.3">
<artifact name="json-lib" type="jar" m:classifier="jdk15"/>
</dependency>
</dependencies>
</ivy-module>
And ivysetting.xml
<ivysettings>
<settings defaultResolver="default" />
<include url="${ivy.default.settings.dir}/ivysettings-public.xml" />
<include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
<include url="${ivy.default.settings.dir}/ivysettings-local.xml" />
<include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
<caches artifactPattern="[organisation]/[module]/([branch]/)[type]s/([platform]/)[artifact]-[revision](.[ext])" />
<resolvers>
<filesystem name="local">
<ivy
pattern="${ivy.local.default.root}/[organisation]/[module]/([branch]/)[revision]/ivy.xml" />
<artifact
pattern="${ivy.local.default.root}/[organisation]/[module]/([branch]/)[revision]/[type]s/([platform]/)[artifact](.[ext])" />
</filesystem>
<ibiblio name="public" m2compatible="true" usepoms="true" pattern="[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />
<chain name="default" returnFirst="true">
<resolver ref="local" />
<resolver ref="public"/>
</chain>
</resolvers>
</ivysettings>
But I still can't download it. It seems like m:classifier not work. Any suggestion about this? Thanks.
I finally find the root reason. I should not use
xmlns:m="http://ant.apache.org/ivy/maven
I should use
xmlns:m="http://ant.apache.org/ivy/extra
Another thing, in my case, I was add "conf" distribute in "artifact" tag, which will make the jar download fail. So do not add "conf" in "artifact".
Works for me.... What version of ivy are you using?
The following example contains some suggested enhancements
Example
Apache Ant(TM) version 1.8.2
Apache Ivy 2.3.0-rc2
ivy.xml
<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven">
<info organisation="xxxx" module="xxx"/>
<configurations>
<conf name="jdk15" description="JDK 1.5 dependencies"/>
</configurations>
<dependencies>
<dependency org="net.sf.json-lib" name="json-lib" rev="2.3" conf="jdk15->master">
<artifact name="json-lib" type="jar" m:classifier="jdk15"/>
</dependency>
</dependencies>
</ivy-module>
Notes:
It's always a good idea to use configurations. In this case I've created one called "jdk15" to group the files with jdk15 classifiers
The remote "master" configuration is special and contains no transitive dependencies (See following link for explanation)
How are maven scopes mapped to ivy configurations by ivy
ivysettings.xml
<ivysettings>
<settings defaultResolver="central" />
<resolvers>
<ibiblio name="central" m2compatible="true"/>
</resolvers>
</ivysettings>
Notes:
This is a minimal ivy settings file. (In fact you could omit the file and it would be functionally the same).
Are you using the "local" resolver? In my experience it's unnecessary (Unless you're publishing artifacts during your build)

Retrieving dependencies with empty type

I'm trying to figure out how to omit the [type] part in an Ivy retrieve pattern for artifacts that don't have type declared. I use the following ant statement:
<ivy:retrieve pattern="${lib.dir}/[artifact](-[type]).[ext]" conf="compile" />
Despite the parentheses, Ivy produces files like
junit-jar.jar
junit-javadoc.jar
junit-source.jar
The latter two ones are as expected but the first one should be "junit.jar" instead.
The result is the same as when I omit the parentheses.
Edit:
What I'm doing up to now to work around the problem: I have multiple retrieve statements in the build.xml:
<ivy:retrieve pattern="${lib.dir}/[artifact]-[type].[ext]" type="source" />
<ivy:retrieve pattern="${lib.dir}/[artifact].[ext]" type="jar" />
(The "conf" attribute in the original post is not related to this topic.)
But that looks rather silly when there's the feature of optional tokens.
The type defaults to jar, it can't be ommited. See Documentation
So this (-[type]) does not have an affect.
Perhaps you could do something like this in the build.xml (if you control the ivy.xml).
<ivy:retrieve pattern="${lib.dir}/[artifact].[ext]" conf="compile" />
<ivy:retrieve pattern="${lib.dir}/[artifact](-[type]).[ext]" conf="extras" />
You'd have to publish the jar in the compile config and the other jars in the extra config.
Or just name the other ones junit-javadoc and junit-source in the ivy.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0">
<info organisation="junit"
module="jnuit"
revision="4.8.2"
status="release"
publication="20110531150115"
default="true"
/>
<configurations>
<conf name="default" visibility="public"/>
</configurations>
<publications>
<artifact name="junit" type="jar" />
<artifact name="junit-sources" type="jar" />
<artifact name="junit-javadoc" type="jar" />
</publications>
</ivy-module>

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>
..