What is a configurationmapping in ivy? - ivy

I have stuff like this:
<configurations defaultconfmapping="build->default;compile->compile(*),master(*);test,runtime->runtime(*),master(*); statistic->stistic(*)">
in my ivy.xml and I don't understand the concept of a 'configuration mapping'
Who gets mapped to what?
Why?
What does the (*) mean?

I've been trying to understand this myself for the last few days. I think this is how it works:
"build->default" means that if I ask for all of the "build" dependencies of my jar, then Ivy pulls the "default" version of that dependency from the repository. If instead you say "build->build" or equivalently "build" then Ivy looks for a jar tagged "build" in the repository to satisfy that dependency. I think the main purpose of having multiple tagged artifacts in the repo are to have a "default", "source", "javadoc" and maybe "debug" version of your code.
I make heavy use of "provided->default" to specify jars that I need to compile against, but that I don't need to add to my plugin installer because I know that jar will already be present at runtime because it's provided by a different installer.

To my understanding after reading the "dependency" documentation (instead of the "configurations" documentation which IMHO is less clear), a "master configuration" (left side of arrow; i.e. a configuration of the current module) gets mapped to a "dependency configuration" (right side of arrow) in order to determine which configuration(s) of the dependency are required in which configuration(s) of the current module.
Since Ivy 1.3, the dependency configuration may have a fallback listed in parenthesis, and this is allowed to be a wildcard ("*").

Related

What exactly is groovy-sql and are there other modules like it?

It's a .jar available in various versions at Maven Repo.
But what category is it? It is published by org.codehaus.groovy, the same outfit that I get my groovy-all dependency from. I also find that import groovy.sql doesn't work in a script unless I specifically include this dependency. So it would appear not to be part of the core language.
Outside a Gradle context I find that I have to manually put the .jar file under ~/.groovy/lib in order to use it. If I put the wrong version (e.g. 2.5.9 for 3.0.2) under ~/.groovy/lib the script won't run... even if I'm not using groovy.sql at all!
Is this a "dependency"? It seems a typically powerful and hassle-free Groovy way of manipulating databases. Are there any other powerful add-on (non-core) Groovy .jar file modules like this, which have to be manually placed under ~/.groovy/lib, that I should know about?
groovy consists of subprojects:
https://github.com/apache/groovy/tree/master/subprojects
and groovy-sql one of the subprojects
all subprojects are published in maven as separate libraries
prior to version 2.5 there was groovy-all-XX.jar that includes all other groovy libraries
https://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.4.19/
however starting from v 2.5 groovy-all represented by groovy-all-XX.pom that depends on all other groovy libraries
https://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.5.0/
so, to include all groovy features you have to specify groovy-all in your maven/gradle/... dependency
and finally useful site to dig dependencies:
https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all/3.0.2

In Ivy, how to choose the latest version of transitive dependencies?

Is there a way to tell Ivy to prefer the latest version of a particular library among the transitive dependencies, without turning the transitive dependency into a direct dependency?
After retrieving the artifacts required for a build I end up with two versions of the same library, both as transitive dependencies. I've run a report so I know where the libraries are coming from but I'd prefer not to end up with references to transitive libraries in my ivy.xml file.
The Ivy manual states "If no specific conflict manager is defined, a default conflict manager is used for all modules. The current default conflict manager is the 'latest-revision' conflict manager". Apparently that doesn't apply to transitive dependencies.
Is there a way achieve what I want without directly referencing transitive libraries?
Transitive dependencies are dependencies of your dependencies, so conflicts can occur when one or more versions of the same library are referenced. This is where the conflict manager functionality kicks in. By default, ivy will choose the most recent version, working on the assumption that most libraries are backwardly compatible. If you review the report generated by the report task you'll see the other version(s) marked as "evicted".
Your question appears to put forward an alternative mode of operation? Perhaps an example would help.

Apache Ivy Config Standard

I'm trying to set up my first Ivy-powered build and am running into implementation problems, and I feel like I don't fully understand Ivy terminologies & best practices, even though I've spent a great deal of time reading the official docs and countless articles.
I have a SVN server that I want to use as the central repository for all of my projects. I do not want to use any public repositories! When I need a JAR, I'll pull it down from one of those public repos, run a checksum for security, and then push it to my SVN server (wherebyit will be deemed to be a "certified" version of the JAR; by certified, I really mean "safe").
(1) I want all of my projects to share the same ivy-settings.xml file. Do I put this in my SVN root, or somewhere inside SVN that makes sense? Here was my tentative thinking:
svn://MyRepoRoot/
ivy/
ivy-settings.xml
artifacts/
Project1/
trunk/
ivy.xml
...
branches/
tags/
Project2/
...
...
The ivy/ directory would contain a master copy of my ivy-settings.xml file. It would also contain an artifacts subdirectory where all of my "certified" JARs/WARs would go (as well as any publications my projects produce for downstream modules). Can I request for commentary?
(2) Also, something that I'm just not getting, is if each of my projects (modules) have their own ivy.xml file, and I want that file to reference the "global ivy-settings.xml file, which should by all means fall under its own, non-module-related versioning scheme, how do I pull down, say, Project1's trunk as my working copy, but configure it with the settings file which is not even a part of the same SVN project?!?
Thanks to anyone who can help give me a little practical advice and better clarity!
The ivysettings.xml is not referenced in the ivy.xml. You need the ivysettings.xml in your ant tasks to find the defined resolver, which resolve the artifacts defined in the ivy.xml.
ivy.xml defines the dependencies and ivysettings.xml the (local) runtime environment for ivy. You can change the ivysettings.xml anytime without need to edit the ivy.xml files.
The ivysettings.xml needs to be referenced in yout (ant) build.xml in ivys <settings /> task.
As for the layout. I use the same approach and it works fine for me.
I wrote my antfiles, so that I need to have the ivy folder checked out parallel to my project(s).
Another approach could be svns externals. But I never tried that.
If your svn has access over http you could also use the url parameter of the task to access ivysettings.xml.

Setting up a standard directory layout using Maven

I'm new to Maven and have skimmed over the documentation as I am following the Hibernate tutorial at http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#tutorial-firstapp-mvn.
I have installed Maven and successfully setup a web-app but this does not contain all of the standard directories mentioned in the tutorial. Am I going mad?
When building my Maven project I am using the maven-archetype-webapp. This gives me the arh-webapp\src\main\resources and arh-webapp\src\main\webapp directories but I'm missing quite a few directories mentioned on the link http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html.
Surely I don't have to manually add these? If not then the Hibernate documentation does not mention what archetype to use in order to achieve the directory structure used in their tutorial. Please can someone enlighten me.
What archetype do I need to use in order to have the above directory plus the src/main/java directory? If there is no such archetype then can easily append these using Maven? and how?
Surely you'll have to manually add these.
Just create those directories that according to the Maven convention are missing. Remember, a Maven Archetype is just a starting point to save you time configuring your workspace. After encountering many problems in some Archetypes myself I've been accustomed to just use a basic-web-app-archetype and then customize it myself, as a beginner with Maven you'll be better off doing that, and will learn a lot.
Regards.
Not all the directories mentioned are required for your standard web application. In fact, the reason behind the presence of the src/main/java, src/main/resources and the src/main/webapp directories is due to the archetype that you've used.
IMHO, the book titled "Better Builds with Maven" will serve you better; the Sonatype books on Maven might also help. The complete Maven documentation is also available as a PDF file, for future reference.
But just in case, you need some clarity on the terms used, here's some:
Archetype: A pattern for projects. Simple web applications (with no dependencies on other frameworks/libraries) have their own archetypes, so do applications using Spring, Hibernate, Seam, etc. Some archetypes will result in creation of different directories, as they are coded that way. You might be able to change the directory structures in most cases, although I cannot vouch for every archetype. For instance, it is quite possible to place your sources in 'src' instead of 'src/main/java', although this requires additional configuration in the POM.
Lifecycles, Phases and Goals: A Maven build lifecycle is a series of phases, with each phase executing a set of goals. Maven can be commanded to execute a build phase, which results in execution of all phases until and including the specified phase.
Maven plugins: Maven plugins contain one or more goals. Goals need not be bound to phases, but usually you would bind them to particular phases. Plugins are the basis for everything operational in Maven; you're using plugins even though you are just compiling the application (the Maven compiler plugin is a core plugin that is present in the Maven distribution).
I hope the above helps, but I would suggest that the reference books be followed.

A layout for maven project with a patched dependency

Suppose, I have an opensource project that depends on some library, that must be patched in order to fix some issues. How do I do that? My ideas are:
Have that library sources set up as a module, keep them in my vcs. Pros: simple. Cons: some third party sources in my repo, might slow down build process, hard to find a patched place (though can be fixed in README)
Have a module, like in 1, but keep patched source files only, compile them with orignal library jar in classpath and somehow replace *.class files in library jar on build. Pros: builds faster, easy to find patched places. Cons: hard to configure, that jar hackery is non-obvious (library jar in repository and in my project assembly would be different)
Keep patched *.class files in main/resources, and replace on packaging like in 2). Pros: almost none. Cons: binaries in vcs, hard to recompile a patched class as patch compilation is not automated.
One nice solution is to create a distinct project with patched library sources, and deploy it on local/enterprise repository with -patched qualifier. But that would not fit for an opensourced project that is meant to be easily buildable by anyone who checks out its sources. Or should I just say "and also, before you build my project, please check out that stuff and run mvn install".
One nice solution is to create a distinct project with patched library sources, and deploy it on local/enterprise repository with -patched qualifier. But that would not fit for an opensourced project that is meant to be easily buildable by anyone who checks out its sources. Or should I just say "and also, before you build my project, please check out that stuff and run mvn install".
This is what I would do (and actually what I do) for both a corporate and an opensource project. Get the sources, put them under version control in a distinct project, patch them, rebuild the patched library (and include this information in the version, something like X.Y.Z-patched), deploy it to a repository (you could use SVN for this, a la Google Code1), declare the repository in your POM and update the dependency to point on your patched version.
With this approach, you can say to your users: check out my code and run mvn install and they will just get the patched version without any extra action. This is IMHO the cleanest way (not error prone, no class path order mess, no increase of the build time, etc).
1 Lots of people are deploying their code to their hosted subversion repository (how-to in this post).
One nice solution is to create a distinct project with patched library sources, and deploy it on local/enterprise repository with -patched qualifier. But that would not fit for an opensourced project that is meant to be easily buildable by anyone who checks out its sources. Or should I just say "and also, before you build my project, please check out that stuff and run mvn install".
I'd agree with this and Pascal's answer. Some additional notes:
you may use dependency:unpack on the original artifact and then combine that with your compiled classes if you don't want to rebuild the whole dependant project
in either case, your pom.xml will need to correctly represent the dependencies of that library
you can still integrate this as part of your project's build to avoid the 'deploy to a repository' step
make sure you honour the constraints of the project's license when doing all this!