Tomcat's javax.servlet and resolving dependencies with Apache Ivy problem - spring

I'm using Apache Ivy with Spring based project. I use Spring Enterprise Bundle Repository mostly. I run my project on Tomcat 7. The problem is that some dependencies, e.g. TestNG also download javax.servlet.jar and javax.servlet.jsp.jar, which interfere with the Tomcat's original ones. How do I deal with that?

You can either exclude specific dependencies from your dependency declaration or simply tell Ivy not to resolve transitive dependencies at all. Here are two examples:
Explicit exclusion:
<dependencies>
<dependency org="org.testng" name="testng" rev="5.8">
<exclude org="javax.servlet" name="servlet-api" />
<exclude org="javax.servlet" name="jsp-api" />
</dependency>
</dependencies>
Exclude all transitive dependencies:
<dependency org="org.testng" name="testng" rev="5.8" transitive="false" />

Related

Gradle and Ivy configuration

I have a module that was published on my own repository. Its ivy.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0">
<info organisation="myorg" module="mymodule" revision="1.5" status="integration" publication="20161222140109"/>
<configurations>
<conf name="compile" visibility="public"/>
</configurations>
<publications>
<artifact name="myartifact" type="zip" ext="zip" conf="compile"/>
</publications>
<dependencies/>
</ivy-module>
In another gradle project, I use this dependency:
configurations {
compile
}
dependencies {
compile 'myorg:mymodule:1.5'
}
What I expected was, that gradle would use the "compile"-configuration in my gradle script to download the "compile"-configuration of the ivy dependency.
What actually happens is that I get an error because Gradle searches for a "default" ivy-configuration.
I know how I can add the configuration info to the dependency with configuration: 'compile' (see this question) but I would not like to do that manually if there is a more elegant way.
Question: Was I wrong by believing that Gradle uses the configurationName in the dependency declaration to search for the matching ivy-configuration? And do I really have to configure each ivy-configuration manually if I don't use default?

Apache IVY to Maven : MakePom Task

How exactly translate IVY to Maven configurations through the task makepom ?
1.) For example IVY "default" Configuration has no equivalent in its Maven Scope :
  
   I understand ... You could put that in a generation task, makempom would do the following equivalence :
<ivy:makepom ..... conf=”default,compile,runtime”>
<mapping conf="default" scope="compile"/>
<mapping conf="compile " scope="compile"/>
<mapping conf="runtime" scope="runtime"/>
</ivy>
2.) But what happens when you have dynamic configurations in IVY, for example, with this IVY configuration, for example "myConf" :
<configurations defaultconf="default->default">
<conf name="default" description="shortcut to runtime and master dependencies"/>
<conf name="compile" description="Used ONLY at compile time" />
<conf name="myConf" description="Not required at compile time BUT required for execution and so deployed to a server"/>
</configurations>
What possibilities exist in this case of translation from IVY to Mave ??? Especially if un have "n" different configurations  , does not seem very practical to have to configurate "n" confs into the makepom task with his corresponding scope. Also I note that if you do not put anything in the task makepom, the generared pon has no scope and always is put to optional :
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3</version>
<optional>true</optional>
</dependency>
This maven code is resulting from an ivy file where the commons-lang3 libs is put on the "default" setting :
<dependency org="org.apache.commons" name="commons-lang3" rev="3.3" conf="default->default"/>
I answer myself.
It's only possible to use the Maven Scopes. If there is any configurantion in ivy that it has not his equivalent scope on Maven you have to define the equivalence to Maven scope into the makepom task,
For example:

IVY Extends via ivy:resolve

We have recently introduced a common dependency in our build system which uses ivy:extends option within each individual ivy.xml. Common ivy.xml contents are as follows;
common-ivy.xml
<?xml-stylesheet type="text/xsl" href="http://repository.xyz.com/xsl/version-doc.xsl"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="XYZ" branch="MAIN" module="CommonDependencies" revision="1.0.0" />
<configurations defaultconfmapping="test->test(*);compile->compile(*);package->package(*)">
<conf name="test" description="Test Time dependencies"/>
<conf name="compile" description="Build Time dependencies"/>
<conf name="package" description="Distributable dependencies" />
</configurations>
<dependencies>
<dependency org="junit" name="junit" rev="4.8.2" conf="compile,test"/>
<dependency org="apache" name="wss4j" rev="1.5.10" conf="compile,test" />
<dependency org="spring" name="spring" rev="2.5.6" conf="compile" />
<dependency org="apache" name="commons-pool" rev="1.5.5" conf="compile" />
<dependency org="google" name="gtest" rev="1.5.0" conf="test" >
<artifact name="gtest" type="" ext="zip" conf="test" />
</dependency>
<dependency org="NUnit" name="NUnit" rev="2.6" conf="test">
<artifact name="NUnit" type="" ext="zip" conf="test" />
</dependency>
<dependency org="javax" name="javaee-api" rev="6.0" conf="compile,test" />
</dependencies>
</ivy-module>
I have around 120 projects extending the common ivy shown above to get their dependencies as follows;
ivy.xml
<?xml-stylesheet type="text/xsl" href="http://repository.xyz.com/xsl/version-doc.xsl"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info module="Module1" >
<extends extendType="all"
organisation="XYZ"
module="CommonDependencies"
revision="1.0.0" />
</info>
<publications />
<!-- Define Additional Dependencies Below -->
<dependencies />
</ivy-module>
If you observe requirement is not to use location attribute of extends because this requires path resolution which makes all child project to be certain order etc. To achieve that we resolve common dependency once in start which produces resolved-*.xml into our local IVY cache and now want IVY to resolve the same for all child projects where it crashes with following messages;
Override ignored for property "ivy.buildlist.dir"
Overriding previous definition of property "ivy.version"
[ivy:buildlist] WARN: Unable to parse included ivy file ../ivy.xml: D:\Source\RTC-DS\Dev\ivy.xml (The system cannot find the file specified) in fil
e:/D:/Source/RTC-DS/ivy.xml
[ivy:buildlist] main: Checking cache for: dependency: XYZ#CommonDependencies;1.0.0 {}
[ivy:buildlist] don't use cache for XYZ#CommonDependencies;1.0.0: checkModified=true
[ivy:buildlist] don't use cache for XYZ#CommonDependencies;1.0.0: checkModified=true
[ivy:buildlist] tried C:\Users\sjunejo\.ivy2/publish/ivys/XYZ/CommonDependencies-1.0.0.xml
[ivy:buildlist] tried C:\Users\sjunejo\.ivy2/publish/XYZ/CommonDependencies/CommonDependencies-1.0.0-jar.jar
[ivy:buildlist] publisher: no ivy file nor artifact found for XYZ#CommonDependencies;1.0.0
[ivy:buildlist] don't use cache for XYZ#CommonDependencies;1.0.0: checkModified=true
[ivy:buildlist] tried C:\Users\sjunejo/external/XYZ/CommonDependencies/CommonDependencies-1.0.0.jar
[ivy:buildlist] external-local-resolver: no ivy file nor artifact found for XYZ#CommonDependencies;1.0.0
[ivy:buildlist] don't use cache for XYZ#CommonDependencies;1.0.0: checkModified=true
[ivy:buildlist] tried http://repository.XYZ.com/ivyrep/ivys/XYZ//CommonDependencies-1.0.0.xml
[ivy:buildlist] CLIENT ERROR: Not Found url=http://repository.XYZ.com/ivyrep/ivys/XYZ//CommonDependencies-1.0.0.xml
[ivy:buildlist] tried http://repository.XYZ.com/ivyrep/XYZ//CommonDependencies/CommonDependencies-1.0.0-jar.jar
[ivy:buildlist] CLIENT ERROR: Not Found url=http://repository.XYZ.com/ivyrep/XYZ//CommonDependencies/CommonDependencies-1.0.0-jar.j
ar
[ivy:buildlist] XYZ-http-resolver: no ivy file nor artifact found for XYZ#CommonDependencies;1.0.0
[ivy:buildlist] don't use cache for XYZ#CommonDependencies;1.0.0: checkModified=true
[ivy:buildlist] tried http://repository.XYZgroup.com/external/XYZ/CommonDependencies/CommonDependencies-1.0.0.jar
[ivy:buildlist] CLIENT ERROR: Not Found url=http://repository.XYZgroup.com/external/XYZ/CommonDependencies/CommonDependencies-1.0.0.jar
[ivy:buildlist] external-http-resolver: no ivy file nor artifact found for XYZ#CommonDependencies;1.0.0
[ivy:buildlist] WARN: Unable to parse included ivy file for XYZ#CommonDependencies;1.0.0
BUILD FAILED
Where I can clearly see that common dependency is successfully resolved and available in local cache.....how can I make <ivy:resolve /> look in local cache to find this...I have searched everywhere and it seems I have to use location :( attribute instead of relying in IVY cache.
Also when I remove the revision from common-dependency it get resolve as working#... which IVY 2.2.0 seems to resolve somehow and all my projects works OK but IVY 2.3.0 complains because it is trying to resolve revision=1.0.0 as defined in ivy.xml of child project and its mandatory otherwise IVY crashes straight away stating revision is a mandatory attribute for extends.
OK there is no other way to solve this issue but to use the location attribute in extends. I have solved this issue by providing a property like location=${common.ivy.location} and declare this property in my ivy settings and it work like a charm.
This solution works with IVY 2.2, 2.3 and 2.4.
Agree with SJunejo's reply. In my case I was getting this same error after moving from 2.2.0 to 2.3.0 and I was using the location attribute. I was however using a relative path. When I updated to use an absolute path, then the error went away.
EDIT: Dug down to the source level of Ivy. 2.3.0 did not work with a relative path, only an absolute one and 2.2.0 did not do property substitution for this location attribute, so had to stay with relative path for 2.2 since it would not property substitute my root path property. Kind of makes it hard to try back and forth to see if the upgrading would work :-(

"com.springsource" prefix on artifact/module causing conflicts

I have a dependency on my project like this:
<dependency org="org.springframework"
name="org.springframework.web.servlet"
rev="3.1.2.RELEASE" />
And it wants to pull things like this:
org.apache.commons#com.springsource.org.apache.commons.logging;1.1.1
which causes issues with other libraries that use a newer version of commons-logging. So I work around it by excluding it like this:
<exclude org="org.apache.commons"
module="com.springsource.org.apache.commons.logging" />
but having to do that kind of defeats the purpose of the conflict management Ivy has built-in. Is there a better way to handle this, or do I have to track down all the potential conflicts manually?
Disclaimer: I'm pretty new to Ivy and dependency management, so I have no idea if this concept extends into the Maven world as well. If not, I apologize for the false tagging.
I'm assuming you are using the EBR repositories in your ivysettings.xml file.
You get those com.springsource dependencies because all the libraries in EBR are valid OSGi bundles and SpringSource transformed normal jars in bundles by prefixing the bundle names with com.springsource.
Also, I'm assuming your project doesn't make use of an OSGi container and you don't actually need OSGi bundles in your project. To get back to resolving normal jars and not OSGi bundles you need not to use the EBR repositories.
In your ivysettings.xml comment the resolvers that point to EBR repositories, for example:
<!-- <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>
</chain>
</resolvers> -->
And replace those with the ibiblio resolver:
<settings defaultResolver="central"/>
<resolvers>
<ibiblio name="central" m2compatible="true"/>
</resolvers>
Also, you need to change any dependency that, initially, was taken from EBR repositories to the format the usual Maven central repository has. For example, your dependency on org.springframework.web.servlet needs to be changed in ivy.xml to:
<dependency org="org.springframework"
name="spring-web"
rev="3.1.2.RELEASE" />
With the changes above, Ivy will resolve the dependencies from Maven central, as well.

Getting several jars from artifactory as a package

I am trying to understand how to manage this situation, suppose I have a 3rd party library (best-lib) that consists of three jars (a.jar, b.jar, c.jar) and I will be uploading those jars to a personal Artifactory server, the (best-lib) has two versions 1.0 and 2.0.
What I would like to have in my ivy.xml file is one single dependency to retrieve all those jars at once for example:
<dependencies>
<dependency org="mycompany" name="best-lib" rev="1.0" />
</dependencies>
And this dependency should add all three jars (a, b, and c) of version 1.0.
The question is:
Is this possible?
How can I upload the three jars to artifactory to achieve this behaviour?
Is it possible to upload those jars all at once?
Artifactory alternative solutions are also acceptable (e.g. Nexus or Archivia).
Note: I am not building best-lib I just have its jars, and best-lib is not a library that can be downloaded from a public maven2 repository.
Thanks.
When publishing the "best-lib" module, use an ivy.xml file that lists the 3 jars published by the module:
<ivy-module version="2.0">
<info organisation="mycompany" module="best-lib"/>
<publications>
<artifact name="a" type="jar"/>
<artifact name="b" type="jar"/>
<artifact name="c" type="jar"/>
</publications>
..
..
When you create a dependency against this module, ivy will understand that there are 3 jars in this module.
For an example of how to publish an ivy module see:
Issues using ivy:publish task
Update
If the 3 jars are already in your repository you could publish a stand-alone ivy modules that references the other 3 as dependencies:
<ivy-module version="2.0">
<info organisation="mycompany" module="best-lib" rev="1.0"/>
<dependences>
<dependency org="mycompany" name="a" rev="1.0" />
<dependency org="mycompany" name="b" rev="1.0" />
<dependency org="mycompany" name="c" rev="1.0" />
</dependencies>
Finally, you may need to tell us what format your Artifactory repository uses.... I have been assuming it's an ivy repo. If it's Maven then the concepts are the same but obviously server-side we'd be talking about pom.xml files, instead of ivy.xml (Ivy supports Maven repositories).

Resources