good ivy tutorial for local repository? [closed] - ant

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
Can anyone point me at a good tutorial for making & using a local repository with Ivy? (Please don't point me at the Ivy docs, the tutorials are rather confusing)
I need to make a local repository to include .jar files that aren't necessarily available through the public maven repositories.

Creating a local ivy repository is straight forward, maven is not required. Here's an example of publishing some text files using ivy as a standalone program.
I have 3 files I want to publish:
src/English.txt
src/Spanish.txt
src/Irish.txt
The ivy file src/ivy.xml details the name of the module and a list of the artifacts being published. (Release index)
<ivy-module version="2.0">
<info organisation="myorg" module="hello"/>
<publications>
<artifact name="English" ext="txt" type="doc"/>
<artifact name="Irish" ext="txt" type="doc"/>
<artifact name="Spanish" ext="txt" type="doc"/>
</publications>
</ivy-module>
You'll also need an ivy settings file to tell ivy where the repository is located
<ivysettings>
<property name="repo.dir" value=".../repo"/>
<settings defaultResolver="internal"/>
<resolvers>
<filesystem name="internal">
<ivy pattern="${repo.dir}/[module]/ivy-[revision].xml" />
<artifact pattern="${repo.dir}/[module]/[artifact]-[revision].[ext]" />
</filesystem>
</resolvers>
</ivysettings>
Finally run ivy to publish the released version 1.0:
java -jar $IVY -settings config/ivysettings.xml \
-ivy src/ivy.xml \
-publish internal \
-publishpattern "src/[artifact].[ext]" \
-revision 1.0 \
-status release \
-overwrite
Note the publish pattern. It tells ivy where the files to be published are located.
Added: Publishing from within ANT
<target name="publish" depends="clean,package" description="Publish this build into repository">
<ivy:publish pubrevision="${pub.version}" status="${pub.status}" resolver="${pub.resolver}" >
<artifacts pattern="${build.dir}/dist/[artifact].[ext]"/>
</ivy:publish>
</target>

don't know if you're using SVN, if this is the case this may help:
http://code.google.com/p/ivysvn/

What you may want to look at doing is creating a private maven repository, either on your local machine, or in your intranet. Then deploy these non-public resources to that repository using maven. Ivy integrates with maven repositories, so you will be able to then pull these resources in during compile time.

Related

optimal chain for resolve in ivy

I have some project's that integrates ivy, i publish my artifact in two possible repositories, local, that respond to a folder, and beta, that respond to a server where archiva is installed and where i share my jars with my colleague.
Now the problem: i need to find a way to build a resolution chains that do this things:
search between the various repository the latest.integration.
retrieve that jar.
if that jar is already in my cache do not have to download it.
if the artifact in the cache has the same version of the artifact in one of the repository take the latest in chronology's order.
now i have try everything that's the setting
Ivy setting
<chain name="resolvechain">
<ibiblio name="b1" root="archivaURLforbeta" m2compatible="true" checkmodified="true" latest="latest-time"/>
<filesystem name="b2" checkmodified="true" >
<artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}" />
</filesystem>
<ibiblio name="b3" root="archivaURLforrelease" m2compatible="true" latest="latest-time"/>
<ibiblio name="b4" m2compatible="true"/>
</chain>
that's the target of resolve in the Build.xml file:
<ivy:settings file="${archiva.set}" />
<ivy:resolve refresh="true" resolveMode="dynamic" changing="true"/>
<ivy:retrieve sync="true" overwritemode="newer" pattern="./lib/[artifact]-[type]-[revision](.[ext])" />
and that's an example on how the dependency are written in ivy.xml file
<dependency org="organization" name="module-name" rev="latest.integration" transitive="false" conf="default" />
the questions are two:
First of all is there any error according to my needs?
Second, what i'm trying to do, is possible?
i asked these two questions because it seems to me that setting checkmodified true and changing true let my application skip entirely my cache, and my projects continuing to download the artifacts every time.
I have found the solution searching between different questions here in stackoverflow and in some issues solution in the ivy comunity with my colleagues.
The FileSystem need it's own latest-time strategy, every resolve take note of their own modules last date revision.
Here the mod in the code:
<filesystem name="b2" checkmodified="true" latest="latest-time">
<artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}" />
</filesystem>

how to use the [ext] variable in ivy?

I want to use the url resolver to download depends. The depends are JS, or XML files. So, I used:
<url name="urlresolver">
<artifact pattern="http://[organisation]/[module]-[revision].[ext]" />
</url>
And
<ivy:retrieve pattern="${build}/[module]-[revision].[ext]"/>
the file is saved in .jar extension.
It's worth digging around the following ivy docs:
Terminology
Main Concepts
Best Practices
The first problem is that your url resolver is not configured to read ivy files for the remote modules (ignoring the first recommendation, in the ivy best practices, to use an ivy file with each module). Without module meta-data ivy will assume you're attempting to download JAR files.
A second problem is that you don't appear to be using an ivy repository to store your files. The following dependency declaration:
<dependency org="yourorg" name="module1" rev="9.1"/>
would be translated into the following URL, using your current settings:
http://yourorg/module1-9.1.jar
The "org" field is designed to specify the organisational unit publishing the module, not the server hostname.
I suspect that you're not really interested in building a repository of files and just want to persuade ivy to download and cache the files? In that case I'd recommend reading the following answer which is using extra attributes on the dependency artifacts to do something similar:
Resolving XSD's using Ivy
Example
ivy.xml
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
..
..
<dependency org="yourorg" name="yourmodule1" rev="9.1">
<artifact name="file1" e:hostname="www.server1.com" type="xml"/>
<artifact name="file2" e:hostname="www.server1.com" type="xml"/>
</dependency>
<dependency org="yourorg" name="yourmodule2" rev="9.1">
<artifact name="file3" e:hostname="www.server2.com" type="xml"/>
<artifact name="file4" e:hostname="www.server2.com" type="xml"/>
</dependency>
..
Note:
Each dependency declares the type of each artifact, plus the additional "hostname" attribute.
If the remote modules had ivy.xml, the publications section would alternatively store this artifact information.
Extra artifacts demonstrate ivy's power in enabling any sort of custom attribute meta-data.
ivysettings.xml
..
<url name="urlresolver">
<artifact pattern="http://[hostname]/files/[organisation]/[module]-[revision].[ext]" />
</url>
..
Demonstrates how the resolver makes use of both the standard attributes and the custom "hostname".

How do you use nested artifact elements for the ivy publish ant task

Can anybody give me a hint on how to use nested artifact (and artifacts) elements for publishing modules use the ivy ant task. Unfortunately the official documentation does not specify how to use the attributes.
http://ant.apache.org/ivy/history/latest-milestone/use/publish.html
Maybe there is some documentation or some examples that I could not find?
I am aware of the artifact element in ivy.xml files. this is NOT what this question is about.
Does this answer to this question help?
Issues using ivy:publish task
The nested "artifact" elements in the publish task are used to identify the location(s) of the artifacts you've specified as to be published by your module.
So, for example, let's say your module publishes two files:
<ivy-module version="2.0">
<info organisation="someorganisation" module="myapp"/>
<publications>
<artifact name="myapp" type="jar"/>
<artifact name="license" type="txt"/>
</publications>
..
Your publish task might need to source these files from two different locations within the build workspace:
<ivy:publish resolver="${publish.resolver}" pubrevision="${publish.revision}" status="${publish.status}">
<artifacts pattern="${build.dir}/[artifact].[ext]"/>
<artifacts pattern="${src.dir}/licenses/[organisation]/[artifact].[ext]"/>
</ivy:publish>

Apache Ivy: resolving dependencies embedded in an installer

I have a problem with a build where I have to resolve non-standard artifacts through Apache Ivy.
Problem:
I have dependencies on two artifacts (a.jar and a-lib.jar).
The two dependencies come only as part of a single installer (a_installer.jar).
The installer can be downloaded, the embedded artifacts themselves not.
It's possible to manipulate the installer to unpack the needed dependencies.
Requirements:
I have to resolve/download the artifacts during the build (I cannot keep the installer or the extracted artifacts with my code).
I cannot use a repository to store the extracted artifacts.
Subclassing/Extending Ivy/whatever is perfectly fine.
Has anyone solved a similar problem, or some helpful information to share?
Or maybe I'm approaching the problem in the wrong way? From what I found so far on the web, people seem to use Ivy just to download files and post-process them manually (with Ant/whatever) after the fact, and not actually resolving more complicated dependencies within Ivy.
Thanks
PS: I don't care whether the installer is also put into the ivy download cache, but I would like to download the installer only one time (and not for both dependencies).
The problem with a call to "ivy:retrieve" is that you need to also add an "artifact" tag in your ivy.xml (complete with URL) in order to retrieve a dependency not found in a Maven respository...
I don't like this for two reasons
The ivy.xml should just declare your dependencies, not their locations.
Need additonal custom logic in the build.xml to handle the 3rd party package
Ideally it should be your repository settings that decide how to download the various jars, that is why I like the packager resolver. Even if the library I want is not in Maven, I can configure ivy to handle it.
The following is an example of turning the jreleaseinfo project into an ivy dependency (hosted in sourceforge, I couldn't find it in Maven)
ivy.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="ivy_packager"/>
<dependencies>
<dependency org="ch.oscg" name="jreleaseinfo" rev="1.3.0"/>
</dependencies>
</ivy-module>
Declare two resolvers. Default is Maven2, the other is a packager configured to look locally for instructions. (See also the Ivy Roundup project)
ivysettings.xml
<ivysettings>
<settings defaultResolver="maven2"/>
<resolvers>
<ibiblio name="maven2" m2compatible="true"/>
<packager name="repackage" buildRoot="${user.home}/.ivy2/packager/build" resourceCache="${user.home}/.ivy2/packager/cache">
<ivy pattern="file:///${basedir}/repository/[organisation]/[module]/[revision]/ivy.xml"/>
<artifact pattern="file:///${basedir}/repository/[organisation]/[module]/[revision]/packager.xml"/>
</packager>
</resolvers>
<modules>
<module organisation="ch.oscg" name="jreleaseinfo" resolver="repackage"/>
</modules>
</ivysettings>
The magic is containing in the "packager" file. At resolve time this will be used to generate an ANT script that both downloads and extracts the required jars.
(No need to put this logic into your build.xml)
repository/ch.oscg/jreleaseinfo/1.3.0/packager.xml
<packager-module version="1.0">
<property name="name" value="${ivy.packager.module}"/>
<property name="version" value="${ivy.packager.revision}"/>
<property name="zipname" value="${name}-${version}"/>
<resource dest="archive" url="http://sourceforge.net/projects/jreleaseinfo/files/jreleaseinfo/jreleaseinfo%201.3.0/jreleaseinfo-1.3.0.zip/download" sha1="9386d92758e627d04c2480b820731fd538b13a3f" type="zip"/>
<build>
<move file="archive/${zipname}/${zipname}.jar" tofile="artifacts/jars/${name}.jar"/>
</build>
</packager-module>
To reduce the number of files I omitted the module's ivy.xml. This appears to be optional unless you want to declare it's licence and other attributes that should be present in a public repository.
I think this is very straightforward: 'ivy:retrieve' a_installer and then unzip a.j and a-lib into your lib directory (or wherever you want it). This should be easily to do with ant?
I have to wonder if there is some complication you haven't mentioned that prevents you from doing this.

Ivy: how do I remove transitive dependencies?

I'm using Ivy to manage the dependencies on my project.
So far, I've specified a dependency on Hibernate and servlet-api. However, the hibernate jar itself has a lot of dependencies that aren't really needed, such as jaas and jacc.
This becomes a show-stopper because jaas and jaac are Sun libraries and therefore their licenses forbid to place them in the Maven repos, so Ivy can't find them there.
How do I make Ivy download Hibernate but not these two ?
As a bonus, if I actually needed those and downloaded their Jars from Sun, in which folder in my machine would Ivy look for them ?
Another option for not downloading any dependencies is to disable them with the transitive attribute. So if you wanted hibernate-core, but none of its dependencies, you could do this:
<dependencies>
<dependency org="org.hibernate" name="hibernate-core"
rev="3.3.1.GA" conf='..'
transitive="false" />
</dependencies>
How do I make Ivy download Hibernate but not these two?
Ivy does this using what it calls "configurations." Your ivy.xml that represents Hibernate will need to provide different configurations to represent different use-cases for hibernate. (There is obviously some use of hibernate that does require jaas and jacc, but apparently you don't make use of that case.)
Here is the documentation on configurations. If you want to provide the ivy.xml you are using for hibernate, I can provide pointers on building configurations that will remove the specific libraries you want removed.
If I actually needed those and downloaded their Jars from Sun, in which folder in my machine would Ivy look for them?
The "directories" that ivy looks in for ivy files and artifacts are specified by the list of resolvers you are using. The list of resolvers is specified in the ivy settings file (usually named ivysettings.xml.) Typically, these aren't local directories, but remote URLs. There is; however, a local-file resolver type that will work for this.
If you do this, you will need to provide both ivy files and the artifacts (jars), each with file-names that match the resolvers patterns. Details on that are in the documentation.
Here is an example local-file resolver from an ivy settings file:
<filesystem name="myfiles" checkconsistency="false" checksums="" transactional="false">
<ivy pattern="/data/repo/[organisation]/[module]-[revision].ivy.xml"/>
<artifact pattern="/data/repo/[organisation]/[module]-[revision].[ext]"/>
</filesystem>
Also note that you will need to point your ivy tasks to the correct resolver. You can do this with the resolver attribute on the ant tasks, or with the defaultResolver attribute on the settings element in the ivy settings file.
Here is the documentation on resolvers.
EDIT: The OP found a less-time intensive workaround for his specific original problem. The "exclude" child-tag of the dependency tag did the job for him:
<dependencies>
<dependency org="org.hibernate" name="hibernate-core" rev="3.3.1.GA" conf='..'>
<exclude name='jaas' />
<exclude name='jacc' />
</dependency>
</dependencies>
Browsing the web and blogs, I found the following ivy-settings to work at grabbing jaas/jacc and hibernate
<ivysettings>
<settings defaultResolver="chained" checkUpToDate="true" />
<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>
<ibiblio name="ibiblio" m2compatible="true"/>
<ibiblio name="jboss" root="http://repository.jboss.org/maven2/" m2compatible="true"/>
<ibiblio name="java-net-maven1" root="http://download.java.net/maven/1" pattern="${java.net.maven.pattern}" m2compatible="false"/>
<ibiblio name="java-net-maven2" root="http://download.java.net/maven/2/" m2compatible="true"/>
<ibiblio name="compass" m2compatible="true" root="http://repo.compass-project.org" />
</chain>
</resolvers>
The jboss ibibilio resolver is what did the trick at grabbing JAAS/JAAC
My ivy.xml then can then pull it in with
<ivy-module version="2.0">
<info organisation="foo" module="Bar"/>
<dependencies>
<dependency org="com.h2database" name="h2" rev="1.2+"/>
<dependency org="org.hibernate" name="hibernate-annotations" rev="3.4.0.GA"/>
</dependencies>
To answer your second sub-question literally, which nobody has done so far, "in which folder in my machine would Ivy look for JARs?" That depends. Assuming you haven't changed the location in ivysettings.xml or another configuration file: for JAAS,
this would be: (user home)/.ivy2/cache/javax.security/jaas/jars. If Ivy already unsuccessfully tried to find JAAS in the Maven Central or other repo's, that directory tree should already exist for the most part, and all you need to do is create the "jars" directory and place jaas-1.0.01.jar in it. Ivy will no longer complain about the missing dependency in its next invocation.
EDIT: Then again, see the discussion below to see considerations to not do it like this.
((user home) is C:/Users/(username) on Windows 7).

Resources