Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Ant in netbeans to dynamically fetch latest versions of external libraries during build

I am an Ant newbie really. Here is my problem : I have a project in netbeans which uses several external libraries which are currently present in /lib directory. I want my netbeans to dynamically fetch latest versions of those libraries when it tries to build the project. Is this doable or am I on the completely wrong path? I have URLs for each of the external libraries, where do I need to specify those in order for this experiment to work? Any help on this is appreciated, I am completely clueless about how to do this !

Thanks

Hi All, I have checked out all your answers and searched more on them. Now the problem is that although maven looks incredible, my project already uses Ant and I don't know how to migrate from ant to maven on netbeans and how difficult is it. Any help? Or else I can use Apache Ivy for this purpose. To give you an example of jar I am using : Apache commons jar

So can you guys guide me how to go about this ? This jar is wrapped inside a .zip file so not easy to detect latest version I guess.

like image 415
voidMainReturn Avatar asked Dec 10 '25 23:12

voidMainReturn


1 Answers

The get task is the only way to do this using standard ANT.

The problem with modern open source development is often one jar depends on several more and when one also must keep track of version compatibilities, this can become difficult if not impossible to keep track of.

Maven is a build technology that pre-dates ANT and has a dependency management feature for 3rd party build dependencies. This functionality can be replicated in ANT by using the Apache ivy plugin.

Example

Java project to demonstrate the use of ivy:

├── build.xml
├── ivy.xml
└── src
    ├── main
    │   ├── java
    │   │   └── org
    │   │       └── demo
    │   │           └── App.java
    │   └── resources
    │       └── log4j.properties
    └── test
        └── java
            └── org
                └── demo
                    └── AppTest.java

There is an additional "ivy.xml" file which lists the 3rd party dependencies. These jars will be downloaded by default from the Maven Central repository, the largest repository of open source java jars.

ivy.xml

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

    <configurations>
        <conf name="compile" description="Required to compile application"/>
        <conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
        <conf name="test"    description="Required for test only" extends="runtime"/>
    </configurations>

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

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

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

</ivy-module>

Notes:

  • This example uses the slf4j logging library which enables you to choose the actual implementation at runtime by adding different jars.
  • The ivy file declares 3 "configurations" which are logical groupings of dependencies. Each dependency has a "conf" mapping that tells ivy what the jar will be used for.
  • In this example our code will compile against the slf4j-api jar and will be configured to use log4j at runtime.
  • junit is an example of a 3rd party jar required by ANT. These can also be downloaded and managed by ivy.

build.xml

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

    <!--
    ================
    Build properties
    ================
    -->
    <property name="src.dir"          location="src/main/java"/>
    <property name="resources.dir"    location="src/main/resources"/>
    <property name="test.src.dir"     location="src/test/java"/>
    <property name="build.dir"        location="build"/>
    <property name="classes.dir"      location="${build.dir}/classes"/>
    <property name="test.classes.dir" location="${build.dir}/test-classes"/>
    <property name="ivy.reports.dir"  location="${build.dir}/ivy-reports"/>
    <property name="test.reports.dir" location="${build.dir}/test-reports"/>
    <property name="dist.dir"         location="${build.dir}/dist"/>

    <property name="jar.main.class" value="org.demo.App"/>
    <property name="jar.file"       value="${dist.dir}/${ant.project.name}.jar"/>

    <!--
    ===========
    Build setup
    ===========
    -->
    <target name="bootstrap" description="Install ivy">
        <mkdir dir="${user.home}/.ant/lib"/>
        <get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.3.0/ivy-2.3.0.jar"/>
    </target>

    <target name="resolve" description="Use ivy to resolve classpaths">
        <ivy:resolve/>

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

        <ivy:cachepath pathid="compile.path" conf="compile"/>
        <ivy:cachepath pathid="test.path"    conf="test"/>
    </target>

    <!--
    ===============
    Compile targets
    ===============
    -->
    <target name="resources" description="Copy resources into classpath">
        <copy todir="${classes.dir}">
            <fileset dir="${resources.dir}"/>
        </copy>
    </target>

    <target name="compile" depends="resolve,resources" description="Compile code">
        <mkdir dir="${classes.dir}"/>
        <javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false" debug="true" classpathref="compile.path"/>
    </target>

    <target name="compile-tests" depends="compile" description="Compile tests">
        <mkdir dir="${test.classes.dir}"/>
        <javac srcdir="${test.src.dir}" destdir="${test.classes.dir}" includeantruntime="false" debug="true">
            <classpath>
                <path refid="test.path"/>
                <pathelement path="${classes.dir}"/>
            </classpath>
        </javac>
    </target>

    <!--
    ============
    Test targets
    ============
    -->
    <target name="test" depends="compile-tests" description="Run unit tests">
        <mkdir dir="${test.reports.dir}"/>
        <junit printsummary="yes" haltonfailure="yes">
            <classpath>
                <path refid="test.path"/>
                <pathelement path="${classes.dir}"/>
                <pathelement path="${test.classes.dir}"/>
            </classpath>
            <formatter type="xml"/>
            <batchtest fork="yes" todir="${test.reports.dir}">
                <fileset dir="${test.src.dir}">
                    <include name="**/*Test*.java"/>
                    <exclude name="**/AllTests.java"/>
                </fileset>
            </batchtest>
        </junit>
    </target>

    <!--
    =====================
    Build and run targets
    =====================
    -->
    <target name="build" depends="test" description="Create executable jar archive">
        <ivy:retrieve pattern="${dist.dir}/lib/[artifact]-[revision](-[classifier]).[ext]" conf="runtime"/>

        <manifestclasspath property="jar.classpath" jarfile="${jar.file}">
            <classpath>
                <fileset dir="${dist.dir}/lib" includes="*.jar"/>
            </classpath>
        </manifestclasspath>

        <jar destfile="${jar.file}" basedir="${classes.dir}">
            <manifest>
                <attribute name="Main-Class" value="${jar.main.class}" />
                <attribute name="Class-Path" value="${jar.classpath}" />
            </manifest>
        </jar>
    </target>

    <target name="run" depends="build" description="Run code">
        <java jar="${jar.file}" fork="true"/>
    </target>

    <!--
    =============
    Clean targets
    =============
    -->
    <target name="clean" description="Cleanup build files">
        <delete dir="${build.dir}"/>
    </target>

    <target name="clean-all" depends="clean" description="Additionally purge ivy cache">
        <ivy:cleancache/>
    </target>

</project>

Several items of note:

  • The ivy jar is not shipped by default with ant. The special "bootstrap" target is used to download this into a location which ANT uses for it's plug-ins.
  • The "resolve" target contains ivy tasks for downloading (and caching) dependencies, generating useful reports on these files and creating ANT paths which can be used for compilation and testing.
  • The "build" target contains the ivy "retrieve" task which places the dependencies into a distribution directory. The manifestclasspath can then use these to generate the correct "Class-path" manifest entry for the executable jar file created by this build.
like image 182
Mark O'Connor Avatar answered Dec 14 '25 15:12

Mark O'Connor