Problems getting my ANT builds to work after OS upgrade

為{幸葍}努か 提交于 2019-12-01 08:22:28

I see the first problem:

[taskdef] Could not load definitions from resource net/sf/antcontrib/antlib.xml. It could not be found.

This is telling me that you have a <taskdef> task some where in your build.xml file, and that it can no longer find the missing optional Ant jar.

My theory: In your old Ant version under $ANT_HOME/lib, you installed the Ant-Contrib jar. Since this directory is in Ant's $CLASSPATH by default, you didn't have to specify it in your <taskdef> task line, so it looks like this:

<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>

I always recommend that you always put these optional task jars into your project. This way, no one has to install these jars in order for them to work since they're already in the project:

  • Make a directory /home/my_userid/new_workspace/my_project/antlib/ac, so your project will have a directory antlib/ac in it.
  • In this directory, download and install ant-contrib-1.03.jar
  • Now change your <taskdef> to include this jar in its classpath.

It should look like this:

<property name="antlib.dir"       value="${basedir}/antlib"/>
<property name="ant-contrib.lib"  value="${antlib.dir}/ac"/>

<taskdef resource="/net/sf/antcontrib/antlib.xml">
    <classpath>
        <fileset dir="${ant-contrib.lib/>
    </classpath>
</taskdef>

Add antlib/ac/ant-contrib-1.03b.jar to your poroject. This way, if someone checks out your project, it builds even if they didn't download and install the ant-contrib jar into their machine.

Note I'm using ant.xml and not antcontrib.properties. This gives me access to the <for/> task instead of the older <foreach> task. The whole thing is explained on this Ant-Contrib Installation page.


Now the other error:

dist:
      [svn] <Status> started ...
      [svn] svn: This client is too old to work with working copy '/home/my_userid/new_workspace/my_project'; please get a newer Subversion client
      [svn] svn: This client is too old to work with working copy '/home/my_userid/new_workspace/my_project'; please get a newer Subversion client
      [svn] <Status> failed !

First, the real issue is that your client version of Subversion is actually too new and not too old. Subversion inside of Ant is using the svnjavahl.jar client which probably wants the old 1.6 version of the Subversion working dirctory. Meanwhile, the version of the Subvfersion client you have checked out is using the newer 1.7 version. Eclipse can do Subversion checkouts by installing JavaHL, SVNKit, or even using the command line client.

Take a look at the directory structure of your checked out directory and see if those infamous .svn directories are scattered in each directory or just in the root directory. If the .svn directory is only under the root directory of your working directory, you have a 1.7.x version of Subversion doing the checkout and your Subversion jar that Ant is using wants the older 1.2 to 1.6.x version of the working directory. If you do see those .svn directories scattered throughout your working directory, then your initial checkout is using the old working directory version and Ant is using the new version.

So, here is the solution in any case: Remove the whole Subversion commit stuff from your build.xml file. First of all, it's a build file, and should not be doing any sort of changes in your version control system. That's bad form. Changes should only be done when the user wants them to, and not because they executed the build.xml file without thinking.

Second of all, you should not be storing derived build output in your repository. Only store the source, and not stuff that's derived. Instead, use a build system like Jenkins to handle the whole build and distribution business for you.

Saving distributions in version control isn't doing you any good. You can't look at the distribution history and understand what changes were made. You can't do a diff between two versions of the distribution and see the changes. The best you can say is that it's a convenient place to find it. The problem is that distributions take a lot of room every time you do a new version, and after a while, you don't most of them any more. In Subversion, there's no easy way to remove them, so they just start taking up a ton of space.

Let's say you have a modest distribution of 100Mb that you're storing for your daily builds. Assume 200 builds per year (no builds on Weekends or holidays) and you're adding 2Gb of space to your repository per year.

With Jenkins, you can store your distributions inside the Jenkins builds, and Jenkins will even remove older, unimportant distributions automatically for you. The distribution is now associated with the build that used it, and you can see the differences between the builds.

But, what if these distributions are jar files that other projects need? Use a dependency management system like Ivy and a local Maven repository like Nexus or Artifactory to manage it.

Even if you don't want to go that far, you could still pull the required jars using the <get/> task directly from Jenkins. Jenkins supplies you with the last good artifact link, and this could be used in your build system to pull the jars you want.

Hope this helps.

David mentioned using ivy to manage 3rd party dependencies.

This example demonstrates how both the ant-contrib and subversion dependencies can be downloaded and cached by the build.

On the issue of subversion I have always found it problematic to enable within ANT. What I desired was a pure java approach would be more robust and cross platform. My solution was svnkit and then create a macro to call the command-line client.

Example

Demonstrates using ivy to managed subversion and ant-contrib dependencies. Dependencies are declared in-line, using the cachepath task. Use a separate ivy.xml file if you're managing multiple classpaths

Apache Ant(TM) version 1.8.2
Apache Ivy 2.3.0-rc2

build.xml

<project name="build" 
         default="demo-ant-contrib" 
         xmlns:ivy="antlib:org.apache.ivy.ant" 
         xmlns:ac="antlib:net.sf.antcontrib">

    <!--
    ======
    Macros
    ======
    -->
    <macrodef name="svn-checkout">
        <attribute name="src"/>
        <attribute name="dest"/>
        <sequential>
            <mkdir dir="@{dest}"/>
            <java classname="org.tmatesoft.svn.cli.SVN" dir="@{dest}" fork="true" classpathref="build.path">
                <arg value="--non-interactive"/>
                <arg line="--username ${svn.user}"/>
                <arg line="--password ${svn.pass}"/>
                <arg value="checkout"/>
                <arg value="@{src}"/>
            </java>
        </sequential>
    </macrodef>

    <!--
    =======
    Targets
    =======
    -->
    <target name="resolve" description="Resolve 3rd party dependencies">
        <ivy:cachepath pathid="build.path">
            <dependency org="org.tmatesoft.svnkit" name="svnkit-cli" rev="1.7.8" conf="default"/>
            <dependency org="ant-contrib" name="ant-contrib" rev="1.0b3" conf="default"/>
            <exclude org="ant"/>
        </ivy:cachepath>
    </target>

    <target name="checkout" depends="resolve" description="Pull code from SCM repository">
        <svn-checkout src="http://svn.apache.org/repos/asf/subversion/trunk" dest="build/subversion"/>
    </target>

    <target name="demo-ant-contrib" depends="resolve" description="Demonstrate using ant-contrib">
        <taskdef uri="antlib:net.sf.antcontrib" resource="net/sf/antcontrib/antlib.xml" classpathref="build.path"/>

        <ac:for list="a,b,c,d,e" param="letter">
            <sequential>
                <echo>Letter @{letter}</echo>
            </sequential>
        </ac:for>
    </target>

    <target name="clean" description="Cleanup build files">
        <delete dir="build"/>
    </target>

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

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