0

My dependencies.xml contains a lot of packages required for my web application to run

Following are a few notable fragments

<configurations>
    <conf name="test" visibility="public" extends="compile" />
    <conf name="compile" visibility="public" extends="runtime" />
    <conf name="runtime" visibility="public" />
    <conf name="provided" visibility="public" />
    <conf name="junit" visibility="public" extends="test" />
</configurations>


<publications>
    <artifact name="${project.name}" type="jar" ext="jar" conf="compile" />
    <artifact name="${project.name}" type="zip" ext="zip" conf="compile"/>
</publications>


<dependencies>


    <dependency org="org.hibernate"                     name="hibernate-core"                   rev="5.1.3.Final"       transitive="false"          conf="runtime->*"/>
    <dependency org="org.hibernate"                     name="hibernate-ehcache"                rev="5.1.3.Final"       transitive="false"          conf="runtime->*"/>
    <dependency org="org.hibernate.common"              name="hibernate-commons-annotations"    rev="5.0.1.Final"       transitive="false"          conf="runtime->*"/>
    <dependency org="org.hibernate.javax.persistence"   name="hibernate-jpa-2.1-api"            rev="1.0.0.Final"       transitive="false"          conf="runtime->*"/>
    <dependency org="org.javassist"                     name="javassist"                        rev="3.21.0-GA"         transitive="false"          conf="runtime->*"/>
    <dependency org="org.jboss.logging"                 name="jboss-logging"                    rev="3.3.0.Final"       transitive="false"          conf="runtime->*"/>
    <dependency org="javax.transaction"                 name="jta"                              rev="1.1"               transitive="false"          conf="runtime->*"/>
    <dependency org="net.sf.ehcache"                    name="ehcache-core"                     rev="2.6.11"            transitive="false"          conf="runtime->*"/>
    <dependency org="antlr"                             name="antlr"                            rev="2.7.7"             transitive="false"          conf="runtime->*"/>
    <dependency org="org.antlr"                         name="antlr4-runtime"                   rev="4.5.2-1"           transitive="false"          conf="runtime->*"/>

</dependencies>

I have package JTA from javax.transaction that is required for the application to run under Tomcat and forbidden for the application to run under WebSphere.

I need to know how to make two different WAR files depending on the target platform. I don't exactly know how to use configurations, if that is the way.

Ant will do an ivy-retrieve for configuration runtime and build a WAR archive using the jars downloaded from Artifactory.

I could exclude thos jar(s) manually by doing a delete after Ivy has resolved the artifacts, but hey, we are cool developers and we like to do the things the cleaner way.

How would you suggest me to do an ivy-retrieve that targets Tomcat including JTA an another that targets Websphere excluding it?

1 Answer 1

1

build.xml : Building war files

The following fragment builds two war files:

  • ../demo.war
  • ../demo-websphere.war

The magic is that the tomcat retrieve task includes two configurations:

<ivy:retrieve pattern="${lib.dir}/tomcat/[artifact].[ext]" conf="runtime,tomcat_only"/>

<war destfile="${dist.dir}/demo.war" webxml="${resources.dir}/web.xml">
  <fileset dir="${resources.dir}" excludes="web.xml"/>
  <lib dir="${lib.dir}/tomcat"/>
</war>

<ivy:retrieve pattern="${lib.dir}/websphere/[artifact].[ext]" conf="runtime"/>

<war destfile="${dist.dir}/demo-websphere.war" webxml="${resources.dir}/web.xml">
  <fileset dir="${resources.dir}" excludes="web.xml"/>
  <lib dir="${lib.dir}/websphere"/>
</war>

build.xml : Publishing

The following answer contains more details on publishing multiple module artifacts to a Maven repository

So we need a target to generate the POM file:

<target name="prepare" description="Generate POM">
    <!-- Optional: Intermediate file containing resolved version numbers -->
    <ivy:deliver deliverpattern="${build.dir}/ivy.xml" pubrevision="${publish.revision}" status="release"/>

    <!-- Generate the Maven POM -->
    <ivy:makepom ivyfile="${build.dir}/ivy.xml" pomfile="${build.dir}/demo.pom"/>
</target>

And a second target that publish the built files:

<target name="publish" depends="init,prepare" description="Upload to Nexus">
    <ivy:publish resolver="nexus-deploy" pubrevision="${publish.revision}" overwrite="true" publishivy="false" >
        <artifacts pattern="${build.dir}/[artifact](-[classifier]).[ext]"/>
    </ivy:publish>
</target>

Take careful notice of the optional "classifier" attribute and note how the ivy file is structured next

ivy.xml

<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
  <info organisation="com.myspotontheweb" module="demo"/>

  <configurations>
    <conf name="master"/>
    <conf name="default" extends="master,runtime"/>
    <conf name="compile"/>
    <conf name="provided"/>
    <conf name="runtime" extends="compile"/>
    <conf name="test"    extends="runtime"/>
    <conf name="tomcat_only" description="A special configuration for special tomcat only dependencies"/>
  </configurations>

  <publications>
    <artifact name="demo" type="war" conf="master"/>
    <artifact name="demo" type="pom" conf="master"/>
    <artifact name="demo" type="war" conf="master" e:classifier="websphere"/>
  </publications>

  <dependencies>
    <!-- Compile dependencies -->
    <dependency org="org.hibernate" name="hibernate-core" rev="5.1.3.Final" conf="compile->default"/>
    <dependency org="org.api" name="slf4j-api" rev="1.7.22" conf="compile->default"/>

    <!-- Runtime dependencies -->
    <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.22" conf="runtime->default"/>

    <!-- Tomcat dependencies -->
    <dependency org="javax.transaction" name="jta" rev="1.1" conf="tomcat_only->master"/>
  </dependencies>

</ivy-module>

Few things going on here.

1) Make configuration mappings work for you

config1->default   # Remote artifact plus transitive dependencies
config2->master    # Remote artifact only (Same as setting transitive=false)

2) The "extends" attribute is a set operation, meaning a compile dependency is automatically included as a runtime configuration.

An example is the SLF4J libary. The slf4j-api jar is required when compile code, where as the slf4j-log4j12 jar contained bindings and dependencies on log4j, a runtime (and changeable) dependency.

3) The "master" configuration in your module is special and by convention in Maven world corresponds to the files published by this module.

4) The "classifier" attribute is an example of a extra attribute in ivy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.