Dependency on Multiple Artifacts of the Same Module - ant

I just did a very ugly hack.
I have a module A which produces two jars.
moduleA.jar and moduleA.test.jar
The module.test.jar is used by other projects in the same repository and won't be published further to other repositories.
I added this to ivy.xml of moduleA
<publications>
<artifact name="moduleA" type="jar" ext="jar" conf="compile"/>
<artifact name="moduleA.test" type="jar" ext="jar" conf="test"/>
</publications>
How can I consume that in moduleB . I understand that Maven doesn't support multiple artifacts per module, and I read somewhere that this is supported by IVY.
I just don't seem to get it write.
I tried this in ivy.xml of moduleB:
<dependency org="my.org" name="moduleA" rev="SNAPSHOT" conf="compile,test->default,test" />
<dependency org="my.org" name="moduleA.test" rev="SNAPSHOT" conf="compile,test->default,test" />
But this obviously didn't work, since 'name' is the name of the module not artifact. I had a work around using the type attribute:
in moduleA:
<artifact name="moduleA" type="test.jar" ext="jar" conf="test"/>
and in moduleB:
<dependency org="my.org" name="moduleA" rev="SNAPSHOT" conf="compile,test->default,test" />
This worked, but looks very ugly. since I have to produce the file in ANT looking like this:
moduleA-SNAPSHOT.test.jar
any neat solution to depending on multiple artifacts of the same module?
This question id different from:
How do I solve Multiple artifacts of the module X are retrieved to the same file in Apache Ivy?

Assuming that Module A looks like this:
<info organisation="my.org" module="moduleA" .../>
<configurations>
<conf name="compile description="???"/>
<conf name="test description="???"/>
..
</configurations>
<publications>
<artifact name="moduleA" type="jar" ext="jar" conf="compile"/>
<artifact name="moduleA.test" type="jar" ext="jar" conf="test"/>
</publications>
The following Module B declaration will retrieve the moduleA.jar
<dependency org="my.org" name="moduleA" rev="latest.integration" conf="default->compile" />
The following Module B declaration will retrieve the moduleA.test.jar
<dependency org="my.org" name="moduleA" rev="latest.integration" conf="default->test" />
It's the configuration mappings that make it work:
default->compile
^ ^
| |
Local configuration
|
Remote configuration
The local configuration doesn't have to be "default". Obviously if Module B also uses configurations, you could use one of those.

Related

Arquillian Weld-EE test setup with ant+ivy

I set up a project following the getting started guide. I have to use ivy. These are my dependencies:
<dependencies>
<dependency org="org.jboss.spec" name="jboss-javaee-all-6.0" rev="3.0.1.Final" conf="build->default" />
<dependency org="org.jboss.arquillian.junit" name="arquillian-junit-container" rev="1.0.3.Final" conf="test->default(*)" transitive="true"/>
<dependency org="org.jboss.arquillian.junit" name="arquillian-junit-core" rev="1.0.3.Final" conf="test->default(*)" transitive="true"/>
<dependency org="org.jboss.weld.arquillian.container" name="arquillian-weld-ee-embedded-1.1" rev="1.1.2.Final" conf="test->default(*)" />
<dependency org="org.jboss.weld" name="weld-core" rev="1.1.10.Final" conf="test->default(*)" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.6.4" conf="test->default(*)" />
</dependencies>
Problem: Although I map to "*", the deps are not resolved transitive. Do I have to add every single jar by hand, just because I am stuck with ivy? or am I missing something?
Clarification:
I use the mapping "myconf->default()" transitive="true".
I read this as follows: "take the default conf of the dependency and map it to "myconf". (): if the dependeny does not provide "default", use every conf it provides. and all this should be done transitive, meaning every sub-dependency will also be mapped.
But what I get is: just the jars specified, and a lot of CNFE when I run the test.
I read about arquillian-container poms that are referenced in maven projects and I am beginning to fear that there is no working "out of the box" dependency mapping mechanism for ivy and arquillian. I am happy Iif anyone can confirm this or provide a working (best: tested) dependency configuration that I can use. Thank you very much!
I'd recommend that your ivy file always declare a set of configurations. Configurations are the logical groupings of jars within your build.
The following example creates a configuration for the 3 classpaths used in a typical java build:
compile
runtime
test
(Note also the "extends" keyword)
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="compile" description="Required to compile application"/>
<conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
<conf name="test" description="Required for test only" extends="runtime"/>
</configurations>
<dependencies>
<!-- compile dependencies -->
<dependency org="org.jboss.spec" name="jboss-javaee-all-6.0" rev="3.0.1.Final" conf="compile->default" />
<!-- test dependencies -->
<dependency org="org.jboss.arquillian.junit" name="arquillian-junit-container" rev="1.0.3.Final" conf="test->default"/>
<dependency org="org.jboss.arquillian.junit" name="arquillian-junit-core" rev="1.0.3.Final" conf="test->default"/>
<dependency org="org.jboss.weld.arquillian.container" name="arquillian-weld-ee-embedded-1.1" rev="1.1.2.Final" conf="test->default" />
<dependency org="org.jboss.weld" name="weld-core" rev="1.1.10.Final" conf="test->default" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.6.4" conf="test->default" />
</dependencies>
</ivy-module>
The configuration mappings will then map the local configuration to the remote one, as follows:
conf="compile->default"
The remote "default" configuration is normally all you need and will include the remote module's compilation dependencies. For a more detailed explanation of how Maven modules are translated I suggest reading the following answer:
How are maven scopes mapped to ivy configurations by ivy
Finally, your build file can use these configurations to create populated ANT classpaths:
<target name="init" description="Use ivy to resolve classpaths">
<ivy:resolve/>
<ivy:report todir='build/ivy' graph='false' xml='false'/>
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="runtime.path" conf="runtime"/>
<ivy:cachepath pathid="test.path" conf="test"/>
</target>
The "report" task is especially useful to document the versions of each jar on the classpath.

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>

Using status in IVY, works for the "less stable one" (ie integration), not for the other (ie milestone and release)

I am trying desperately to have this working. I've spent the whole day on it and can't find what's wrong.
It seems that IVY can resolve only the "less stable status" in the statuses list, ie for the default ones, only integration not milestone or release.
This is a test ant file.
<project name="helicopter" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant">
<ivy:settings file="ivysettings.xml" id="ivy.instance"/>
<!-- the call to resolve is not mandatory, retrieve makes an implicit call if we don't -->
<ivy:resolve file="ivy.xml" />
<ivy:retrieve type="swc" pattern="../libs/bin/[module]-[revision].[ext]" />
<ivy:retrieve type="src" pattern="../libs/src/[module]-[revision].[ext]" />
</project>
This is the ivysettings.xml
<?xml version="1.0" encoding="UTF-8"?>
<ivysettings>
<settings defaultResolver="local" />
<resolvers>
<filesystem
name="local"
checkmodified="true">
<artifact pattern="C:/repository/[organisation]/[module]/[revision]/[artifact].[ext]" />
</filesystem>
</resolvers>
</ivysettings>
And this 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"
>
<info
organisation="com.org"
module="moduleA"
status="integration"
/>
<publications>
<artifact type="swf" ext="swf" />
<artifact type="src" ext="src.zip" />
</publications>
<dependencies>
<dependency org="com.org" name="moduleB" rev="latest.integration">
<artifact name="moduleB" type="swc" ext="swc" />
<artifact name="moduleB" type="src" ext="src.zip" />
</dependency>
</dependencies>
</ivy-module>
And the moduleB ivy.xml in the repository (folder)
<info organisation="com.org" module="moduleB" revision="0.0.5.0" status="integration" publication="20111201174403"/>
<publications>
<artifact type="swc" ext="swc"/>
<artifact type="src" ext="src.zip"/>
</publications>
<dependencies>
</dependencies>
So this will work, the moduleB will be downloaded all right.
Now if I edit the ivy.xml to get the latest.milestone
<info
organisation="com.org"
module="moduleA"
status="integration"
/>
<publications>
<artifact type="swf" ext="swf" />
<artifact type="src" ext="src.zip" />
</publications>
<dependencies>
<dependency org="com.org" name="moduleB" rev="latest.milestone">
<artifact name="moduleB" type="swc" ext="swc" />
<artifact name="moduleB" type="src" ext="src.zip" />
</dependency>
</dependencies>
</ivy-module>
and edit the ivy.xml of my published moduleB (so editing in the repository folder) to be of status milestone
<info organisation="com.org" module="moduleB" revision="0.0.5.0" status="milestone" publication="20111201174403"/>
<publications>
<artifact type="swc" ext="swc"/>
<artifact type="src" ext="src.zip"/>
</publications>
<dependencies>
</dependencies>
it won't work, the artifact won't be found, although listed
:: problems summary ::
:::: WARNINGS
module not found: com.org#moduleB;latest.milestone
==== local: tried
-- artifact com.org#moduleB;latest.milestone!moduleB.src.zip(src):
C:/repository/com.org/moduleB/revision]/moduleB.src.zip
[0.0.5.0 (MD)]
-- artifact com.org#moduleB;latest.milestone!moduleB.swc:
C:/repository/com.org/moduleB/[revision]/moduleB.swc
[0.0.5.0 (MD)]
Now the FUN PART!
Before using the defaults statuses from IVY I used mine.
It had the exact same behavior (that's why I tried the defaults one then).
The fun bits is that if I had
<statuses default="status-dev">
<status name="status-stable" integration="false"/>
<status name="status-test" integration="false"/>
<status name="status-dev" integration="true" />
</statuses>
The only latest.[status] working will be for status-dev.
Now if I change the status order to
<statuses default="status-dev">
<status name="status-stable" integration="false"/>
<status name="status-dev" integration="true" />
<status name="status-test" integration="false"/>
</statuses>
The only one working will be status-test.
I' puzzled here... :/
Thanks for any help you could provide.
Cheers,
Xavier
I have created a basic project showing the weird behavior.
moduleB is the module being published.
moduleA is the module getting moduleB as a dependency.
Please update the path to the local repository in both ivysettings file
The link to download the file
https://rapidshare.com/files/1326835940/test_ivy.zip
Wow, that looks like a very strange overloading of the dependency construct. I would stick with a simpler ivy.xml, with a single dependency upon moduleB. Just change the rev attribute at runtime using a property file. That is, coalesce all of your dependencies into:
<dependency org="com.org" name="moduleB" rev="${dependency.rev.moduleB}"
conf="build-release->default;build-milestone->default;build-devs->default">
<artifact name="shared" type="swc" ext="swc" />
<artifact name="shared" type="src" ext="src.zip" />
</dependency>
You can even supply a default value to the property (for IvyDE, for example) in your ivy-settings.xml:
<property name="dependency.rev.moduleB"
value="latest.integration"
override="false"/>
Also, you'll want to edit your ivysettings.xml to include a pattern for the repository to find ivy.xml files:
<resolvers>
<filesystem
name="local"
checkmodified="true">
<artifact pattern="C:/repository/[organisation]/[module]/[revision]/[artifact].[ext]" />
<ivy pattern="C:/repository/[organisation]/[module]/[revision]/ivy.xml" />
</filesystem>
</resolvers>

Apache ivy. JbossAS, dependencies and some basic questions on ivy

I'm totally new in ivy, so don't blame for for rather elementary questions.
I'm working on project that depends on some libraries of jbossAS 4.0.3.
To tell exactly - there are jboss-4.0.3-scheduler, jboss-4.0.3-jboss-system, jboss-4.0.3-jboss, jboss-4.0.3-jbossall-client. So i have a logical question - how can I point ivy to find them on public repository? Or that's the wrong direction of leveraging ivy in this situation?
And another simple question - for example, in the past this project depended on castor-0.9.7, axis-1.3 and log4j - after ivy dependency resolution - I had a lot of other jars like activation-1.1.jar, axis-saaj-1.3.jar, mail-1.4.jar and so on. So it was only 3 jars in dependencies in the past - now I have 10. Do i really need them?
And what is the way to know for sure what do i need of this additional jars?? (after all the project was working with old config - 3 jars).
And what if I have some artifact(dependee project). Other project depends on it, but i don't want transitive dependencies to be resolved. That's only a question of interest ))
This is how i am pulling dependencies now (from local repo), and what i want - to pull them from public repo (if it is possible) :
<ivy-module version="2.2">
<info organisation="org.btl" module="BtlAppServer" revision="1.7"/>
<configurations defaultconfmapping="default">
<conf name="compile" visibility="private"/>
<conf name="test" extends="compile" visibility="private"/>
<conf name="master" />
<conf name="runtime" extends="compile" />
<conf name="default" extends="master,runtime"/>
</configurations>
<publications>
<artifact conf="master"/>
</publications>
<dependencies>
<dependencies>
<dependency org="jboss" name="jboss" rev="4.0.3" conf="*->default" />
<dependency org="jboss" name="jbossall-client" rev="4.0.3"
conf="*->default"/>
<dependency org="jboss" name="jboss-system" rev="4.0.3" conf="*->default"/>
<dependency org="jboss" name="scheduler-plugin" rev="4.0.3"
conf="*->default"/>
<dependency org="org.btl" name="BtlCommon" rev="latest.integration" />
</dependencies>
</ivy-module>
setttings file for this stuff :
<ivysettings>
<settings defaultResolver="myChain"/>
<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"/>
<include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
<resolvers>
<chain name="myChain" returnFirst="true">
<resolver ref="local"/>
<!-- JBoss -->
<ibiblio name="jboss-nexus" m2compatible="true"
root="https://repository.jboss.org/nexus/content/groups/developer/"
pattern="[organisation]/[module]/[revision]/[artifact]-[revision](-
[classifier]).[ext]"/>
<ibiblio name="ibiblio" m2compatible="true" />
</chain>
</resolvers>
<modules>
<module organisation='org.btl' resolver='local' />
</modules>
</ivysettings>
File ivy.xml for the second question :
<ivy-module version="2.2">
<info organisation="org.btl" module="BtlCommon" revision="1.7"/>
<configurations defaultconfmapping="default">
<conf name="compile" visibility="private"/>
<conf name="test" extends="compile" visibility="private"/>
<conf name="master" />
<conf name="runtime" extends="compile" />
<conf name="default" extends="master,runtime"/>
</configurations>
<publications>
<!--get the artifact from our module name-->
<artifact conf="master"/>
</publications>
<dependencies>
<dependency org="axis" name="axis" rev="1.3" conf="*->default" />
<dependency org="castor" name="castor" rev="0.9.7" conf="*->default" />
<dependency org="log4j" name="log4j" rev="1.2.15" conf="*->default" >
<exclude org="com.sun.jdmk"/>
<exclude org="com.sun.jmx"/>
<exclude org="javax.jms"/>
</dependency>
</dependencies>
</ivy-module>
Don't know if that can help someway )
The extra jars are produced by transitive dependencies. These may not be needed to compile your project but needed at runtime.
If they are actually needed depends on the dependency itself and your usage of the library. Mail.jar(Java Mail API) for example is only needed if you need to send Mails.
I think it will be quite complicated to really make sure, that you won't need the extra libraries (in the future?). If you are sure now, that you program runs without them, you can just set the transitive attribute to the dependency. And they will not be downloaded.
<dependency org="axis" name="axis" rev="1.3" conf="*->default" transitive="false"/>
I found the Jboss dependencies in the java.net repository for revision="4.2.2.GA". Seems the best option. But I couldn't find the scheduler.
ivysettings.xml
<ibiblio name="jboss-java.net" m2compatible="true"
root="http://download.java.net/maven/2/"/>

How does ivy:publish use the [classifier] attribute

in ivy:publisher the default deliverivypattern is ${ivy.distrib.dir}/[type]s/[artifact]-[revision](-[classifier]).[ext]
I try to set classifier in my ivy.xml under by adding attribute e:classifier="" to the element.
But the [classifier] does not get set?
When ivy:publish runs in my build.xml file it appears to be empty and thereby not included in the file name pattern.
I think I've figured out your problem.
Just to be clear it is the configured resolver that determines the repository filename and not the publish task. Here's my example, which utilises two extra attributes greeting and author in the artifact and ivy filename patterns:
<ivysettings>
<property name="repo.dir" value="${ivy.basedir}/build/repo"/>
<property name="ivy.checksums" value=""/> <!-- Suppress the generation of checksums -->
<settings defaultResolver="internal"/>
<resolvers>
<filesystem name="internal">
<ivy pattern="${repo.dir}/[module]/[author]-ivy(-[greeting])-[revision].xml" />
<artifact pattern="${repo.dir}/[module]/[author]-[artifact]-[greeting]-[revision].[ext]" />
</filesystem>
</resolvers>
</ivysettings>
The values of the extra attributes are determined by the ivy.xml file:
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="myorg" module="hello" e:author="Mark"/>
<publications>
<artifact name="English" ext="txt" type="doc" e:greeting="hello"/>
<artifact name="Irish" ext="txt" type="doc" e:greeting="dia_dhuit"/>
<artifact name="Spanish" ext="txt" type="doc" e:greeting="Hola"/>
</publications>
</ivy-module>
Sure enough when I published the files the values of the greeting and author tags were present:
$ find build -type f
build/repo/hello/Mark-English-hello-1.0.txt
build/repo/hello/Mark-Irish-dia_dhuit-1.0.txt
build/repo/hello/Mark-Spanish-Hola-1.0.txt
build/repo/hello/Mark-ivy-1.0.xml
I had a problem with
Attribute classifier is not allowed to appear in element 'artifact'
I simply added the "extra" namespace in my declaration and was able to use the classifier.
<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:e="http://ant.apache.org/ivy/extra">
<dependency org="orphans" name="vaadin-timeline-cval" rev="2.0">
<artifact name="vaadin-timeline-cval" e:classifier="1.3.1" ext="jar"/>
</dependency>
I believe you want the pattern like so. If the greeting isn't defined it will be left out.
[author]-[artifact](-[greeting])-[revision].[ext]
I faced the same issue and we found a way to get the extra attribute in.
my example in the ivysettings.xml look something like...
<resolvers>
<filesystem name="internal">
<ivy pattern="${repo.dir}/[module]/[author]-ivy(-[greeting])-[revision].xml" />
<artifact pattern="${repo.dir}/[module]/[author]-[artifact]-[greeting]-[revision].[ext]" />
</filesystem>
and in your ivy.xml file i put the following: please note that i wanted the greeting value to be dynamic value everytime i publish something (${someValue})
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="myorg" module="hello" e:author="Mark"/>
<publications>
<artifact name="English" ext="txt" type="doc" e:greeting="${someValue}"/>
</publications>
Here is where the trick come in -> In my build file where i call the ivy:publish function, the following attribute have to be set to true (forcedeliver)
<ivy:publish resolver="#{ivy.resolver}"
pubrevision="#{publish.revision}"
status="#{status}"
forcedeliver="true"
overwrite="#{overwrite}"
update="true" />
That's it

Resources