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

馋奶兔 提交于 2019-12-19 04:00:47

问题


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.


回答1:


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.



回答2:


As a first advice, I would say that ant is probably not the best tool to do that. Maven is doing that properly (at least if your external libraries are published in a (public) maven repo as SNAPSHOT). Additionally, maven and netbeans works nicely together.

But, if you need to use ant, you should probably take a look at the ant get task. It allows you to download a file if the remote copy is newer that your local copy (with the usetimestamp attribute). So something like this will do the download when required:

<get src="http://some.url/somelib.jar" 
     dest="lib/somelib.jar"
     usetimestamp="true"/>


来源:https://stackoverflow.com/questions/17079198/use-ant-in-netbeans-to-dynamically-fetch-latest-versions-of-external-libraries-d

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!