我最近升级从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工作通过命令行使用,但在这种情况下,客户端版本是不是太旧,而是太新了!? 难道是值得“向下分级”颠覆?
否则可能什么是问题,我该怎么解决呢? 是否有其他常见的问题,我应该检查,以确保该项目的工作,因为它应该(可能发行版升级/迁移过程中出现)? (下面是构建文件中的相关内容)
该位定义了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>
...
我看到的第一个问题:
[taskdef] Could not load definitions from resource net/sf/antcontrib/antlib.xml. It could not be found.
这是告诉我,你有一个<taskdef>
任务一些地方在你build.xml
文件,它可以不再为寻找失踪的可选蚂蚁罐子。
我的理论 :在你的下旧的Ant版本$ANT_HOME/lib
,你安装了蚂蚁的Contrib罐子。 因为这个目录是在Ant的$CLASSPATH
默认情况下,你没有在你指定它<taskdef>
任务线,所以它看起来是这样的:
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
我总是建议你总是把这些可选任务jar文件到您的项目。 这样一来,没有一个人是为了安装这些罐子他们的工作,因为他们的项目是已:
- 创建一个目录
/home/my_userid/new_workspace/my_project/antlib/ac
,所以你的项目将有一个目录antlib/ac
在里面。 - 在这个目录,下载并安装蚂蚁的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
您poroject。 这样一来,如果有人签出您的项目,它建立即使他们没有下载和安装蚂蚁的contrib罐子到他们的机器。
请注意我使用ant.xml
而不是antcontrib.properties
。 这使我获得了<for/>
任务,而不是旧的<foreach>
任务。 整个事情是这样的解释蚂蚁的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 !
首先,真正的问题是,颠覆您的客户端版本实际上是太新 ,而不是太旧 。 蚂蚁的颠覆内使用svnjavahl.jar
客户端,可能要老1.6版本的Subversion工作dirctory的。 同时,Subvfersion客户端的版本已签出使用较新的1.7版本。 Eclipse可以通过安装JavaHL,SVNKit,甚至使用命令行客户端做颠覆结帐。
看看您的签出目录的目录结构,看看那些臭名昭著.svn
目录分散在每个目录或只是在根目录下。 如果.svn
目录只是你的工作目录的根目录下,你有颠覆的1.7.x版本做结账和你的Subversion罐子蚂蚁正在使用要老1.2到1.6.x的工作目录的版本。 如果你看到这些.svn
遍布你的工作目录的目录,那么你的初始结账时使用旧的工作目录版本和Ant是使用新版本。
所以,这里是在任何情况下,解决办法: 删除整个颠覆您提交的东西build.xml
文件 。 首先,它是一个构建文件 ,并且不应该做任何形式的版本控制系统的变化。 这是不好的形式。 当用户想他们,而不是因为他们执行的build.xml文件不假思索变化时才需要这样做。
其次重要的是,你不应该存储在你的仓库而衍生的输出。 只有存储源,而不是东西,这的。 取而代之的是,使用一个构建系统,如詹金斯处理整个构建和分销业务为您服务。
在版本控制节分布没有做任何好处。 你可以不看历史分布和理解进行了哪些变化。 你不能这样做分布的两个版本之间的差异,看到了变化。 你能说的最好的是,这是一个方便的地方找到它。 问题是,每次分配你做一个新版本时采取了很多的房间,过了一段时间,你没有任何更多大部分。 在Subversion中,有没有简单的方法来删除它们,所以他们刚开始服用一吨的空间。
比方说,你有一个100MB的温和的分布,你保存你的每日构建。 假设每年200构建(没有建立在周末或假期),您要添加的2GB空间,每年你的资料库。
随着詹金斯,则可以将您的分布中的詹金斯建立和詹金斯甚至会删除旧的,不重要的分布自动为您。 分配现在与用它构建有关,你可以看到不同的版本。
但是,如果这些分布是jar文件,其他项目需要什么? 使用依赖关系管理系统,如常春藤和本地的仓库一样的Nexus或Artifactory的来管理它。
即使你不想去那么远,你仍然可以拉使用需要的jar <get/>
直接从任务詹金斯。 詹金斯提供您与上次良好神器链接,这可能在构建系统被用来拉你想要的罐子。
希望这可以帮助。
大卫用提到常春藤来管理第三方的依赖。
此示例演示如何既蚂蚁的contrib和颠覆的依赖性可以下载并生成缓存。
颠覆的问题,我一直觉得有问题的ANT内启用。 我想要的是一个纯Java的办法是更强大的和跨平台的。 我的解决办法svnkit ,然后创建一个宏调用命令行客户端。
例
演示使用常春藤管理的颠覆和蚂蚁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>