Question

I recently upgraded my system from Mint12 to Mint14 and had severe issues with getting my old projects to work nicely on the new system. To summarize it all:

  • Got Mint14 to work nicely and installed all my essential software (Eclipse, ANT etc)
  • Restored my files from my backup disk
  • Set up Oracle JDK as the default java version
  • Checked out a fresh copy of my project from SVN
  • Updated all paths in the build file to reflect the new user_id

That's all good but my ant build seems to have been messed up, somehow, such that when I try to build my project I get the following error:

~/new_workspace/my_project $ ant dist
Buildfile: /home/my_userid/new_workspace/my_project/build.xml
  [taskdef] Could not load definitions from resource net/sf/antcontrib/antlib.xml. It could not be found.

init:

compile:
    [javac] /home/my_userid/new_workspace/my_project/build.xml:246: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds

static:

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 !

BUILD FAILED
/home/my_userid/new_workspace/my_project/build.xml:104: Can't get status of /home/my_userid/new_workspace/my_project

Total time: 0 seconds

I took notice of the "too old to work with working copy..." but when I check svn --version I see that it's 1.7.5 which should be alright. Note that the SVN version on the server has not changed meanwhile. A theory is that the project (checked out via Eclipse, using Subclipse 1.6) doesn't work with the version ANT uses via command line, but in that case the client version is not too old, but rather too new!? Would it be worth "down-grading" Subversion?

Otherwise what could to be the problem and how can I solve it? Are there other common issues (that might occur during distro upgrade/migration) which I should check in order to make sure the project works as it should? (Below are the relevant bits of the build file)


This bit defines the svn bindings

  <path id="svnant.classpath">
    <fileset dir="/home/my_userid/.ant/lib">
      <include name="svnant.jar" />
      <include name="svnClientAdapter.jar" />
      <include name="svnjavahl.jar" />
      <!-- <include name="svnkit.jar" /> tried this as well but no joy -->
    </fileset>
  </path>

The relevant bit in the "dist" target:

  <target name="dist"
          depends="compile,static" description="Compiles and builds jar files">

    <mkdir dir="${dist}"/>
    <buildnumber file="project-version.properties"/>
    <property name="version.number" value="${major.version}.${minor.version}.${micro.version}"/>
    <svn>
      <status path="."
              lastChangedRevisionProperty="rev.number" />
     <info target="." />
    </svn>
    ...
Était-ce utile?

La solution

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.

Autres conseils

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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top