3

我最近将我的系统从 Mint12 升级到了 Mint14,并且在让我的旧项目在新系统上很好地工作方面遇到了严重的问题。总结一下:

  • 让 Mint14 运行良好并安装了我所有的基本软件(Eclipse、ANT 等)
  • 从我的备份磁盘恢复我的文件
  • 将 Oracle JDK 设置为默认 java 版本
  • 从 SVN 签出我的项目的新副本
  • 更新了构建文件中的所有路径以反映新的 user_id

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

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

2 回答 2

2

我看到了第一个问题:

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

这告诉我您<taskdef>在文件中的某个位置有一个任务build.xml,并且它无法再找到丢失的可选 Ant jar。

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

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

我始终建议您始终将这些可选任务 jar 放入您的项目中。这样,由于它们已经在项目中,因此没有人必须安装这些 jars 才能使它们工作:

  • 创建一个目录/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 安装页面上进行了解释。


现在另一个错误:

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 进行检出,并且 Ant 使用的 Subversion jar 需要旧的 1.2 到 1.6.x 版本的工作目录。如果您确实看到这些.svn目录分散在您的工作目录中,那么您的初始签出使用的是旧的工作目录版本,而 Ant 使用的是新版本。

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

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

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

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

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

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

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

希望这可以帮助。

于 2013-01-10T15:45:13.673 回答
0

David 提到使用ivy来管理 3rd 方依赖项。

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

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

例子

演示使用 ivy 来管理 subversion 和 ant-contrib 依赖项。使用cachepath任务以内联方式声明依赖项。如果您管理多个类路径,请使用单独的ivy.xml文件

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

构建.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>
于 2013-01-10T22:36:39.880 回答