0

I am new to Ant scripts.

below is description of requirement

in my workspace, there are various projects and I have to have my project work on RAD and eclipse IDE as well as Websphere , tomcat and jboss environment.. i have made project specific settings to make the project work on RAD and websphere and eclipse and tomcat n jboss..

but there are changes in several files like classpath n few config files.

this leaves me with three versions of workspace.

but my idea is to have one workspace with multiple version of classpath for eg. classpath_eclipse, classpath_rad etc.. and have an ant script that will choose between the right files during build depending on which ide.

So guys please suggest some approach how can i implement this approach. totally new to ant. .:/

Mukul Goel
  • 8,387
  • 6
  • 37
  • 77
  • Want to manage the IDE environment or target build environments? Details: Classpaths are managed differently in Eclipse and ANT.... Do you want ANT to generate the ".classpath" files for you? Alternatively is the requirement to manage different classpaths associated with different target environments? For example Tomcat may not have all the jars packaged with websphere? – Mark O'Connor May 29 '12 at 17:54
  • I have to have my workspace work on two IDE`s Eclipse as well as RAD. so I want ANT to generate the ".classpath" files. Yes the requirement for different classpaths is associated with different target environments as well as IDE. the dependency on environment is as u said. on IDE it occurs because i have some project related plugins that are RAD compatible but not eclipse. those plugin provide me with a set of library in RAD. whereas in eclipse i have to create a "User Library". so requirement to manage different classpaths is associated with different target environments as well as IDE`s – Mukul Goel May 30 '12 at 09:13

2 Answers2

1

I'd suggest using Apache ivy for managing complex classpaths. It externalizes your build dependencies into a separate ivy.xml file.

Secondly, ivy can automatically download such dependencies, reducing the size of your project under source control.

Finally, this solution at first glance might appear horribly complex. It's advantage is that it's compatible with other build technologies such as Maven.

Example

ivy.xml

Ivy uses "configurations" to manage logical groupings of jars.

In this example the code compiles against the SLF4J api jars, but at run-time use different logging implementations:

<ivy-module version="2.0">
    <info organisation="com.myspotontheweb" module="demo"/>

    <configurations>
        <conf name="compile" description="Required to compile application"/>
        <conf name="runtime.simple"  description="Runtime environment with minimal logging" extends="compile"/>
        <conf name="runtime.complex" description="Runtime environment with logback enabled" extends="compile"/>
        <conf name="test"    description="Required for test only" extends="runtime.simple"/>
        <conf name="build"   description="ANT tasks used by build"/>
    </configurations>

    <dependencies>
        <!-- compile dependencies -->
        <dependency org="org.slf4j" name="slf4j-api" rev="1.6.4" conf="compile->default"/>

        <!-- simple runtime dependencies -->
        <dependency org="org.slf4j" name="slf4j-simple" rev="1.6.4" conf="runtime.simple->default"/>

        <!-- complex runtime dependencies -->
        <dependency org="ch.qos.logback" name="logback-classic" rev="1.0.3" conf="runtime.complex->default"/>

        <!-- test dependencies -->
        <dependency org="junit" name="junit" rev="4.10" conf="test->default"/>

        <!-- Build dependencies -->
        <dependency org="org.codehaus.groovy" name="groovy-all" rev="1.8.6" conf="build->default"/>
    </dependencies>

</ivy-module>

Notes:

  • The extends attribute enables the creation of jar union sets
  • By default ivy will download from Maven Central (an open repository that now hosts approx 90% of Java open source software).
  • Using the conf attribute you can associated a depedency against one or more of your locally defined configurations.
  • Ivy can also be used to manage 3rd party ANT task dependencies

build.xml

The ivy ANT tasks are imported as an antlib. The ivy cachepath task is used to turn an ivy managed configuration into normal ANT paths and the ivy report task produces a dependency report.

<project name="demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">

    <target name="init">
        <ivy:resolve/>

        <ivy:report todir='${ivy.reports.dir}' graph='false' xml='false'/>

        <ivy:cachepath pathid="compile.path" conf="compile"/>
        <ivy:cachepath pathid="runtime.simple.path" conf="runtime.simple"/>
        <ivy:cachepath pathid="runtime.complex.path" conf="runtime.complex"/>
        <ivy:cachepath pathid="test.path"    conf="test"/>
        <ivy:cachepath pathid="build.path"   conf="build"/>
    </target>
    ..
    ..

The ivy retrieve task is used to populate a directory during your application's packaging phase:

<target name="war">
    <ivy:retrieve pattern="${build.dir}/libs/[artifact].[ext]" conf="runtime.complex"/>

    <war destfile="myapp.war" webxml="src/metadata/myapp.xml">
        <fileset dir="${src.dir}/html/myapp"/>
        <fileset dir="${src.dir}/jsp/myapp"/>
        <lib dir="${build.dir}/libs"/>
        <classes dir="${build.dir}/classes"/>
    </war>
</target>

IDE configuration files

An Eclipse plugin for ivy is available.

It's also possible to generate IDE configuration files using an embedded groovy task. Following is an Eclipse example:

<target name="eclipse">
    <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>

    <ivy:cachefileset setid="libfiles" conf="compile"/>

    <groovy>
    <arg value="${src.dir}"/>
    <arg value="${build.dir}/classes"/>

    import groovy.xml.MarkupBuilder

    //
    // Generate the project file
    //
    project.log("Creating .project")

    new File(".project").withWriter { writer ->
        def xml = new MarkupBuilder(writer)

        xml.projectDescription() {
            name(project.name)
            comment()
            projects()
            buildSpec() {
                buildCommand() {
                    name("org.eclipse.jdt.core.javabuilder")
                    arguments()
                }
            }
            natures() {
                nature("org.eclipse.jdt.core.javanature")
            }
        }
    }

    //
    // Generate the classpath file
    //
    // The "lib" classpathentry fields are populated using the ivy artifact report
    //
    project.log("Creating .classpath")

    new File(".classpath").withWriter { writer ->
        def xml = new MarkupBuilder(writer)

        xml.classpath() {
            classpathentry(kind:"src",    path:args[0])
            classpathentry(kind:"output", path:args[1])
            classpathentry(kind:"con",    path:"org.eclipse.jdt.launching.JRE_CONTAINER")

            project.references.libfiles.each {
                classpathentry(kind:"lib", path:it)
            }
        }
    }
    </groovy>        
</target>
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • hey Mark , i dint knew about asking the same question again , new to this forum.. appologies. – Mukul Goel Jun 28 '12 at 08:52
  • using the ivy and groovy looks quite complex and i`ll have to redo all current implementation.. could u suggest some approach to implement what i asked in that second question ? because thats how the architect has suggested and the approach has been approved.. i`ll have to go really a long way to propose a new approach .. :( – Mukul Goel Jun 28 '12 at 08:54
  • 1
    The problem you're trying to solve is not trivial. First of all you're trying to support multiple instances of two different build tools. Each has a different file format. Secondly, in effect you're creating your own dependency management system.... I've seen very large ANT projects using property files to manage module classpaths.... It ultimately becomes a bespoke solution that one or two build engineers will understand...... Consider again using ivy. Finally there is also an ivy plugin for interfacing with eclipse. This might avoid the need for the groovy stuff. – Mark O'Connor Jun 28 '12 at 19:11
  • hey mark.. i got what you were saying. prepared a draft and proposed the changes to my team and architect. what i was suggested( and TOLD :/ ) that we are not looking to modify the build process. we just need some script that the user runs for the first time that sets the classpaths and runtime and other settings etc.. and after that we could use our usual build process.. i did a dig in to ivy and it looks cool. But cant do anything about using it. Thanks for introducing me to this technology. -Regards Mukul – Mukul Goel Jul 03 '12 at 07:04
  • Hi Mark, As i intimated that i am bound to use the previous approach. These are the things i need to handle : classpath and runtime configs. Could you please give some guidelines. Thanks -Mukul – Mukul Goel Jul 10 '12 at 04:42
  • @MukulGoel keep reading stackoverflow :-) For example: http://stackoverflow.com/questions/11417304/ivy-what-is-the-master-configuration-and-why-is-it-not-pulling-jvyaml/11420292#11420292 – Mark O'Connor Jul 10 '12 at 19:20
  • though my proposal to use ivy was rejected. But i put my hands in learning this framework and it is a good approach to my solution. – Mukul Goel Sep 29 '12 at 17:10
  • I would like to share the approach that I implemented. There were classpath, settings and some project config xmls that were dependent on runtime. In each project we created a runtime_classpah & runtime_settings and configxml_runtime version of each file. Created a target in ant that takes in runtime as param ,itrates over each project & copies contents of classpath_runtime to classpath ,setting_runtime to settings. And a target that overrites configxml with contents of configxml_runtime – Mukul Goel Sep 29 '12 at 17:18
0

I would like to share the approach that I finally implemented.

There were classpath, settings and some project config xmls that were dependent on runtime.

In each project we created a runtime_classpah & runtime_settings and configxml_runtime version of each file.

Created a target in ant that takes in runtime as param ,itrates over each project & copies contents of classpath_runtime to classpath ,setting_runtime to settings.

And a target that overrites configxml with contents of configxml_runtime

Mukul Goel
  • 8,387
  • 6
  • 37
  • 77
  • This is a problem that dependency management frameworks are designed to solve for you. – Mark O'Connor Oct 26 '12 at 15:22
  • @MarkO'Connor you are right sir, and as i mentioned i did read about `ivy` , n i liked it. but the decision of choice was not in my hands and above is the approach I was suggested to use, considering efforts that ivy required and time delivery constraints. – Mukul Goel Oct 26 '12 at 15:49