Ivy task 'install' not copying/installing documents - ant

I am using ivy with ant to build multiple modules. I need to publish some documents (.docx files). But when I need to install from one ivy repository to other they are not being copied. How do I tell ivy to copy those documents when using install task.
Publications:
<publications>
<artifact name="find" type="jar" conf="core" />
<artifact name="Documentation" type="res" ext="docx"/>
<artifact name="Dep_report" type="res" ext="xml"/>
</publications>
Install task call to copy artifacts from one ivy repository to another:
<ivy:install organisation="${ivy.organisation}" module="${ivy.module}"
revision="${ivy.revision}" from="shared" to="released" overwrite="true" />
Also, I must add that publishing to shared and installing it to released ivy repository don't happen on the same ant call. I added < ivy:resolve /> before calling install and it didn't help either (Do I need to add any attributes to ivy:resolve call??). Do I need to specify dependency on the documentation in ivy.xml file? Install copies jar file and ivy.xml fine but not the docs or xml files. What am I missing? Any help is greatly appreciated.

Issue was not adding conf on artifacts. I needed to add conf="core" for both docx and xml file publication:
<publications>
<artifact name="find" type="jar" conf="core" />
<artifact name="Documentation" type="res" ext="docx" conf="core" />
<artifact name="Dep_report" type="res" ext="xml" conf="core" />
</publications>
Also, for ivy:install needed to add conf="core" as follows:
<ivy:install organisation="${ivy.organisation}" module="${ivy.module}"
revision="${ivy.revision}" from="shared" to="released" overwrite="true" conf="core" />

Related

How to publish custom jars to local Apache Ivy repository

I've read all the tutorials and examples, and still cannot publish a set of custom jars in my local Ivy repository.
Edit: Basically I want the same behavior as maven-install-plugin.
Here's my setup. I have an Ant task which produces the jars in a given folder. The folder name is not fixed but rather passed as a property in file. I want to get all the jars in this folder and install them in my local Ivy repo so that I can use them on a next step.
Here is my Ant from where I call the ivy:publish:
<project name="Install Ivy Dependencies" xmlns:ivy="antlib:org.apache.ivy.ant" basedir="." default="publish">
<loadproperties srcFile="path_to_folder.properties"/>
<property name="file_pattern" value="${path_to_folder}/[artifact].[ext]" />
<property name="pub_revision" value="1.0.0" />
<target name="resolve">
<ivy:configure file="ivysettings.xml" />
<ivy:resolve file="ivy.xml" />
</target>
<target name="retrieve-all" depends="resolve">
<ivy:retrieve pattern="${file_pattern}" conf="*" />
</target>
<target name="publish" depends="retrieve-all">
<ivy:publish resolver="local" organisation="myOrg" update="true" overwrite="true" pubrevision="${pub_revision}">
<artifacts pattern="${file_pattern}"/>
</ivy:publish>
</target>
</project>
Here's my ivysettings.xml:
<ivysettings>
<resolvers>
<filesystem name="local" local="true"/>
</resolvers>
</ivysettings>
And the ivy.xml:
<?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="myOrg" module="myModule" revision="1.0.0"/>
<publications>
<artifact name="my-custom-jar" ext="jar" type="jar"/>
<artifact name="my-custom-jar-source" ext="jar" type="source"/>
</publications>
</ivy-module>
The error that I am getting when I call the ant task is:
impossible to publish artifacts for myOrg#myModule;1.0.0: java.lang.IllegalStateException: impossible to publish myOrg#myModule;1.0.0!my-custom-jar.jar using local: no artifact pattern defined
I've managed to run my scenario and to resolve my issues using this tutorial There were two major issues in my code/integration.
First one is that you cannot tell Ivy to publish the artifacts in its repository without providing a path to it. I did this with the filesystem resolver:
<filesystem name="local" local="true" transactional="local">
<ivy pattern="${ivy.default.ivy.user.dir}/local/[module]/ivy-[revision].xml" />
<artifact pattern="${ivy.default.ivy.user.dir}/local/[module]/[artifact]-[revision].[ext]" />
</filesystem>
The stupid think about it is this should be build in. If you copy it as is, then everything works. If the config is different, or pointing to a different location - nothing works and you are not told why. I read tons of docs about Apache Ivy and it was nowhere mentioned that these patterns should point to the local Ivy repository. I thought these were the paths from where the jars should be taken. I actually complained about this, but the Ivy documentation is very confusing. Also I think the examples there are wrong. Who would like to publish the artifacts in their ivy.settings.dir. In my case this directory was in my repository!
There was a second issue. It is a smaller one and again very hard to see and fix. There's something wrong the revision param and again the documentation is messed up. If you specify one and the same string for the revision and pub revision the artifacts aren't publish without any explanation why. I fixed it by removing the revision from ivy.xml file.
Last, but not least, I didn't manage to run successfully the "thing" as Ant task, but with java -jar $IVY_JAR ... Maybe the issue was because of the versions, but I was too tired to try it with the fix.
P.S.#cantSleepNow thanks for the help.
You need to add artifact pattern to resolver in ivysettings.xml, something like (example from ivy documentation):
<ivysettings>
<resolvers>
<filesystem name="local" local="true">
<ivy pattern="${ivy.settings.dir}/1/[organisation]/[module]/ivys/ivy-[revision].xml"/>
<artifact pattern="${ivy.settings.dir}/1/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
</filesystem>
</resolvers>
</ivysettings>

Finding dependecies between modules of a legacy ANT project for migration to IVY

I am dealing with a project using using ANT to build the source code into a EAR. The project over couple of years has grown to a mammoth size, more than fifty modules, and not surprisingly it takes 2 hours to build the source code.
The obvious decision that I made was to migrate this to a modular build using IVY for dependency management between sub-modules of the EAR, so I build only the modules that have changed and then package a new EAR every time. I am stuck trying to find out a good way of figuring out dependencies between these sub-modules. Note that 3rd party dependencies were easy to crack. I simply move all that is in the lib folder of these sub-modules to IVY. But, the former is where I am stuck.
This is what they do:
Copy source from all modules to a directory
Compile "everything" into a global.jar
Add this global.jar to the classpath
Build every individual module thereafter
Now how do I figure out that for example Module C depends on module A and B and so A and B should go as ivy dependency in the former? One way could be to add one module at a time in eclipse and try building, and then eleminate failures because of missing classes; but there has to be a better way than this, I cannot imagine spending the next one month of life figuring that out :)
First of all you need to create ivy repository. I don't know how to do it. Try to find it on ivy site. After that you need to create build.xml and ivy.xml file.
Example build.xml which builds some product which depends on module1
<project name="ivy.test" xmlns:ivy="antlib:org.apache.ivy.ant">
<target name="resolve">
<!-- this line tells ivy to use ${ivy.settings.file} where are ivy repositories; more info http://ant.apache.org/ivy/history/latest-milestone/settings.html -->
<ivy:configure file="${ivy.settings.file}"/>
<!-- resolve ivy dependencies from ivy.xml and put them in ivy cache dir -->
<ivy:resolve file="${build.dir}/ivy.xml" transitive="false" />
<!-- finally copy resolved dependencies to ${ivy.lib.dir} -->
<ivy:retrieve conf="default" pattern="${ivy.lib.dir}/[artifact].[ext]" />
</target>
</project>
Example ivy.xml used to resolve dependencies (will try to find module1 in one of ivy repository defined in ivysettings file)
<ivy-module version="2.0">
<info organisation="your.organisation" module="modulename">
<ivyauthor name="yourname" />
</info>
<configurations>
<conf name="default" description="default conf" />
</configurations>
<dependencies>
<dependency name="module1" org="your.organisation" rev="latest.release" conf="default->default" />
</dependencies>
</ivy-module>
Example ivy.xml used by module1 project (this project depends on module2 and module3; module1 is also published in repository)
<ivy-module version="2.0">
<info organisation="your.organisation" module="module1"> <!-- module name is used in dependency -->
<ivyauthor name="yourname"/>
</info>
<configurations>
<conf name="default" description="default configuration"/>
</configurations>
<publications>
<artifact name="module" ext="dll" type="dll" conf="default"/>
</publications>
<dependencies>
<dependency name="module2" org="your.organisation" rev="latest.release" conf="default->default" />
<dependency name="module3" org="your.organisation" rev="latest.release" conf="default->default" />
</dependencies>
</ivy-module>

Ivy, what is the master configuration and why is it not pulling jvyaml?

I have the following ivy file:
<configurations defaultconfmapping="buildtime">
<conf name="buildtime" visibility="private" description="Libraries needed only for compilation" />
<conf name="runtime" description="Libraries only needed at runtime" />
<conf name="test" description="Libraries only needed for testing" />
</configurations>
<dependencies>
<dependency org="net.java.dev" name="jvyaml" rev="0.2.1" conf="runtime" />
<dependency org="org.apache.solr" name="solr-core" rev="3.6.0" conf="runtime" />
</dependencies>
and I have an ant retrieve task that looks like this:
<target name="retrieve-all" depends="resolve">
<ivy:retrieve pattern="lib/[conf]/[artifact]-[revision].[ext]" conf="*" />
</target>
The weird thing is, that all the solr dependencies download into lib/runtime as I'd expect, but the jvyaml module does not! It 'resolves', but will not download into the lib/runtime directory unless I change the dependency declaration to:
<dependency org="net.java.dev" name="jvyaml" rev="0.2.1" conf="runtime->master" />
What is this master configuration and why is it needed to pull the jvyaml jar, but not solr?
Thanks
I would suggest restructuring your configurations as follows:
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="compile" description="Libraries needed only for compilation" />
<conf name="runtime" description="Libraries only needed at runtime" extends="compile" />
<conf name="test" description="Libraries only needed for testing" extends="runtime" />
</configurations>
<dependencies>
<dependency org="net.java.dev" name="jvyaml" rev="0.2.1" conf="runtime->default" />
<dependency org="org.apache.solr" name="solr-core" rev="3.6.0" conf="runtime->default" />
</dependencies>
</ivy-module>
Important changes introduced:
Use the more standard "compile" configuration
Configuration inheritance using the "extends" attribute. Compile dependencies can then be automatically included in both the runtime and test configurations.
Use configuration mappings, for example: conf="runtime->default". This makes it obvious which local configuration is associated with which remote configuration.
Configuration mappings explained
Configurations are a powerful ivy feature. When ivy downloads Maven modules it performs an internal translation and assigns a standard set of configurations, listed in this answer:
How are maven scopes mapped to ivy configurations by ivy
When declaring a dependency it's a good idea to always make use of a configuration mapping, so that there is no doubt where the dependencies artifacts are assigned.
For example:
<dependency org="??" name="??" rev="??" conf="runtime->default" />
Here we're saying we want the remote module's default dependencies associated with our local runtime configuration.
In practice, there are only two remote configuration mappings you'll actually need:
default: The remote module's artifact and all it's runtime transitive dependencies
master: The remote module's artifact only (No transitive dependencies)
In conclusion, I think your problem was caused by the fact that the remote Maven module's "runtime" scope does not include Maven module's artifact, instead you were getting the non-existant transitive dependencies of the module jvyaml :-(
Some additional advice
I'd also suggest generating an ivy dependency management report, as follows:
<target name="init" description="Resolve dependencies and populate lib dir">
<ivy:resolve/>
<ivy:report todir="${build.dir}/ivy-report" graph="false"/>
<ivy:retrieve pattern="lib/[conf]/[artifact]-[revision].[ext]"/>
</target>
The report will help explain how each dependency ends up on different configurations. Also really useful for determining how transitive dependencies are being managed.
And finally, here's where the configuration inheritance pays off, creating ivy managed ANT classpaths:
<target name="init" description="Resolve dependencies and set classpaths">
<ivy:resolve/>
<ivy:report todir="${build.dir}/ivy-report" graph="false"/>
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="runtime.path" conf="runtime"/>
<ivy:cachepath pathid="test.path" conf="test"/>
</target>
Notice that the original solr-core is not retrieved either.
After your resolve, go the cache and check the ivy.xml files for both modules.
You will see that they publish their artifacts in conf=master only
<artifact name="jvyaml" type="jar" ext="jar" conf="master"/>
<artifact name="solr-core" type="jar" ext="jar" conf="master"/>
Which means, you have to do explicit configuration mapping to denote that your builtime configuration should evoke the 'master' configuration of your dependencies. (check configuration mapping).
HOWEVER, the dependencies of the solr-core, have the configuration mapping as you could see in the ivy.xml file:
<dependency org="org.apache.solr" name="solr-solrj" rev="3.6.0" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
I think it's the master(*) thingy.
What I usually do is in my own ivy.xml file when I declare dependencies I do the mapping:
<dependency org="net.java.dev" name="jvyaml" rev="0.2.1" conf="runtime->master" />
This one says the runtime be evoking the master configuration in the designated dependency.
You could do
conf="runtime,test->master"
as well

IVY How to find specific dependency configuration is in use?

I have my version.xml in a project where I defined all the IVY configurations and dependencies. I use ANT script to download and retrieve artefacts and everything is OK so far.
What I am looking for is that in anyway I can find if certain configuration is present in version.xml and some dependency is confgured to use it from an ANT script, like check as I want to do some extra stuff if it is configured other wise simply skip. For example my version.xml looks like as follows;
<?xml-stylesheet type="text/xsl" href="http://repository.temenosgroup.com/xsl/version-doc.xsl"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="TEMENOS" branch="MAIN" module="StateEngine" />
<!-- "war->compile(*)" this means the 'war' configuration depends on the
'compile' configuration of the dependency and if the dependency is not
found in 'compile' then use the 'default' (same as '*') config (usually that is all dependencies) -->
<configurations defaultconfmapping="test->test(*);compile->compile(*);componentDep->componentDep(*)">
<conf name="test" description="Test Time dependencies"/>
<conf name="compile" description="Build Time dependencies"/>
<conf name="componentDep" description="To resolve component level dependencies" />
</configurations>
<publications>
<artifact name="#SERVICE_NAME#" type="" ext="zip" />
<artifact name="#SERVICE_NAME#" type="" ext="zip" e:platform="#PLATFORM_WIN#" />
<artifact name="#SERVICE_NAME#" type="" ext="zip" e:platform="#PLATFORM_UNIX#" />
</publications>
<dependencies>
....
<!-- Define Component Level Dependencies Below -->
<dependency org="TEMENOS" branch="MAIN" name="StateMachine" transitive="false" rev="latest-dev" conf="componentDep" >
<artifact name="StateMachineService" ext="zip" e:platform="#PLATFORM_WIN#" type="" conf="componentDep" />
<artifact name="StateMachineService" ext="zip" e:platform="#PLATFORM_UNIX#" type="" conf="componentDep" />
<artifact name="StateMachineService" ext="zip" type="" conf="componentDep" />
</dependency>
</dependencies>
</ivy-module>
So, is there any target available within ANT like 'ivy:...' which can return 'true' or 'false' some how tell me that there is a dependency which is trying to use configuration called 'componentDep'? so that I can do my extra stuff..otherwise skip. I do not want to parse the file myself within ANT as this is not a very good idea.
Note: I am using ANT 1.8.2 and IVY 2.2.0
Hope I am making sense. Please let me know if you need more information.
Thanks,
--
Sjunejo
Ivy normally resolves using a file called ivy.xml.....
I suspect that your version.xml file is designed to be substituted? Perhaps your build is generating the ivy file at run-time?
Reasons for suspicions
The names of the files published by ivy do not appear valid.... I doubt you're creatung 3 files called #SERVICE_NAME#.zip
<publications>
<artifact name="#SERVICE_NAME#" type="" ext="zip" />
<artifact name="#SERVICE_NAME#" type="" ext="zip" e:platform="#PLATFORM_WIN#" />
<artifact name="#SERVICE_NAME#" type="" ext="zip" e:platform="#PLATFORM_UNIX#" />
</publications>
Somewhere else in your build I think there's a filtered copy going on.....
Possible answer to your original question
I think you're looking for an ivy resolution report? This creates a HTML report of the files associated with each of your project's configurations. Used as follows:
<target name="init">
<ivy:resolve/>
<ivy:report todir='${ivy.reports.dir}' graph='false' xml='false'/>
..
</target>

ivy - create local repository to pull multiple jar files from same location

I have a local repository, in which i can put one jar and retrieve it using ivy. Now for svnant, I want to put 4 jar files in one folder and try to use ivy to retrieve it. my patten in org/module/version/module-version.jar. how do i perform this.
In your ivysettings.xml file define a filesystem resolver with an artifact pattern matching the location of your 4 jars.
<ivysettings>
<settings defaultResolver="local-repo"/>
<resolvers>
<filesystem name="local-repo">
<ivy pattern="${ivy.settings.dir}/repo/[organisation]/[module]/[revision]/ivy.xml"/>
<artifact pattern="${ivy.settings.dir}/repo/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"/>
</filesystem>
</resolvers>
</ivysettings>
Ivy will then be able to find your jars.
Update
In order to group the 4 jars as one module save the following ivy.xml file and store it with the jars
<ivy-module version="2.0">
<info organisation="myorg" module="svnant" revision="1.0"/>
<publications>
<artifact name="svnant"/>
<artifact name="svnclientadapter"/>
<artifact name="svnkit"/>
<artifact name="svnjavahl"/>
</publications>
</ivy-module>
Note: The revision number in the ivy.xml must match the revision number of the module
The dependency in the ivy.xml file is then
<dependency org="myorg" name="svnant" rev="1.0"/>

Resources