我最近将我的系统从Mint12升级到了Mint14,并且让我的旧项目在新系统上运行得很好。总结一下:
这一切都很好,但我的蚂蚁构建似乎已经搞砸了,不知何故,当我尝试构建我的项目时,我收到以下错误:
~/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>
...
答案 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
。<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之类的依赖关系管理系统和Nexus或Artifactory等本地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
<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>