操作系统升级后让我的ANT构建工作的问题

时间:2013-01-10 14:10:14

标签: java svn ant build javahl

我最近将我的系统从Mint12升级到了Mint14,并且让我的旧项目在新系统上运行得很好。总结一下:

  • 让Mint14很好地工作并安装了我所有必需的软件(Eclipse,ANT等)
  • 从我的备份磁盘恢复了我的文件
  • 将Oracle JDK设置为默认的Java版本
  • 从SVN
  • 查看了我的项目的新副本
  • 更新了构建文件中的所有路径以反映新的user_id

这一切都很好,但我的蚂蚁构建似乎已经搞砸了,不知何故,当我尝试构建我的项目时,我收到以下错误:

~/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

我注意到“工作副本太旧了......”但是当我检查svn --version时,我发现它是1.7.5应该没问题。请注意,服务器上的SVN版本没有同时更改。一个理论是项目(通过Eclipse检查,使用Subclipse 1.6)不能与ANT使用命令行的版本一起使用,但在这种情况下,客户端版本不是太旧,而是太新了!?是否值得“降级”Subversion?

否则可能是什么问题,我该如何解决?是否存在其他常见问题(可能在发行版升级/迁移期间发生)我应该检查以确保项目按预期工作? (以下是构建文件的相关位)


此位定义svn绑定

  <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>

“dist”目标中的相关位:

  <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>
    ...

2 个答案:

答案 0 :(得分:2)

我看到第一个问题:

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

这告诉我你的<taskdef>文件中有一个build.xml任务,并且它无法再找到缺少的可选Ant jar。

我的理论:在$ANT_HOME/lib下的旧Ant版本中,您安装了Ant-Contrib jar。由于此目录默认位于Ant $CLASSPATH中,因此您无需在<taskdef>任务行中指定它,因此它看起来像这样:

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

我总是建议您始终将这些可选任务jar放入项目中。这样,没有人必须安装这些罐子才能让它们工作,因为它们已经在项目中了:

  • 创建一个目录/home/my_userid/new_workspace/my_project/antlib/ac,这样您的项目中就会有一个目录antlib/ac
  • 在此目录中,下载并安装ant-contrib-1.03.jar
  • 现在更改您的<taskdef>以将此jar包含在其类路径中。

它应该是这样的:

<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>

antlib/ac/ant-contrib-1.03b.jar添加到您的项目中。这样,如果有人检查了你的项目,即使他们没有下载并将ant-contrib jar安装到他们的机器中,它也会构建。

注意我使用的是ant.xml而不是antcontrib.properties。这使我可以访问<for/>任务而不是旧的<foreach>任务。整个问题在这个Ant-Contrib Installation页面上进行了解释。


现在又出现了另一个错误:

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 !

首先,真正的问题是您的客户端版本的Subversion实际上太新而不是太旧。 Ant内部的Subversion正在使用svnjavahl.jar客户端,它可能需要旧的1.6版Subversion工作目录。同时,您已检出的Subvfersion客户端版本使用 较新的 1.7版本。 Eclipse可以通过安装JavaHL,SVNKit甚至使用命令行客户端来执行Subversion检出。

查看已签出目录的目录结构,看看这些臭名昭着的.svn目录是分散在每个目录中还是只分散在根目录中。如果.svn目录只在工作目录的根目录下,那么你有一个1.7.x版本的Subversion在做结帐,你使用的Subversion jar需要较旧的1.2到1.6.x版本的工作目录。如果您确实看到分散在整个工作目录中的.svn个目录,那么您的初始签出是使用旧的工作目录版本而Ant正在使用新版本。

因此,无论如何,这里都是解决方案:build.xml文件中删除整个Subversion提交内容。首先,它是 构建文件 ,不应该在版本控制系统中进行任何类型的更改。那是不好的形式。只应在用户需要时进行更改,而不是因为他们不假思索地执行build.xml文件。

其次,您不应该在存储库中存储派生的构建输出。只存储源,而不是存储的东西。相反,使用像Jenkins这样的构建系统来为您处理整个构建和分发业务。

在版本控制中保存分发对您没有任何帮助。您无法查看分发历史记录并了解所做的更改。您不能在两个版本的发行版之间进行差异并查看更改。你能说的最好的是它是一个方便的地方找到它。问题是,每次执行新版本时,发行版会占用大量空间,过了一段时间,您不再需要大部分内容。在Subversion中,没有简单的方法可以删除它们,因此它们只是占用了大量的空间。

假设您为每日构建存储了100Mb的适度分布。假设每年200个构建(没有在周末或假期构建),并且您每年向存储库添加2Gb的空间。

使用Jenkins,您可以将您的发行版存储在Jenkins构建中,而Jenkins甚至会自动为您删除较旧的,不重要的发行版。现在,分发与使用它的构建相关联,您可以看到构建之间的差异。

但是,如果这些发行版是其他项目需要的jar文件呢?使用Ivy之类的依赖关系管理系统和NexusArtifactory等本地Maven存储库来管理它。

即使您不想走那么远,您仍然可以直接从Jenkins使用<get/>任务拉出所需的罐子。 Jenkins为您提供了最后一个很好的工件链接,这可以在您的构建系统中使用,以拉动您想要的罐子。

希望这有帮助。

答案 1 :(得分:0)

David提到使用ivy来管理第三方依赖项。

此示例演示了如何通过构建下载和缓存ant-contrib和subversion依赖项。

关于颠覆问题,我总是发现在ANT中启用它有问题。我想要的是纯Java方法会更强大和跨平台。我的解决方案是svnkit,然后创建一个宏来调用命令行客户端。

实施例

演示使用常春藤来管理subversion和ant-contrib依赖关系。使用cachepath任务在线声明依赖关系。如果您正在管理多个类路径

,请使用单独的ivy.xml文件
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>