[英]Using Ant's classpath in Eclipse
I have an Ant build.xml
file that works just fine on the command line: it compiles, builds the JAR, and I am able to execute the main method from the JAR just fine. 我有一个Ant
build.xml
文件在命令行上运行正常:它编译,构建JAR,我能够从JAR执行main方法就好了。 The build.xml
file references several thirdparty libraries that are scattered here and there. build.xml
文件引用了分散在这里和那里的几个第三方库。 When building the JAR, the script doesn't include all the thirdparty libraries into the JAR itself. 构建JAR时,脚本不会将所有第三方库都包含在JAR本身中。 Instead, it puts their path into the JAR's manifest.
相反,它将他们的路径放入JAR的清单中。 This helps to keep my JAR slim and tidy.
这有助于保持我的JAR苗条和整洁。
I'd like to be able to edit and debug my project in Eclipse, but I can't find an easy way to do so. 我希望能够在Eclipse中编辑和调试我的项目,但我找不到一个简单的方法。 I can have my project use the Ant file to build the project, and that seems to work.
我可以让我的项目使用Ant文件来构建项目,这似乎有效。 However, Eclipse is having trouble finding the thirdparty libaries, and thus Eclipse is having two problems:
但是,Eclipse无法找到第三方库,因此Eclipse存在两个问题:
I can solve both of the above problems by specifying by hand, in two difference places (ie, the build path via Properties->Java Build Path->Libraries
, and the execution classpath via Run Configurations->Classpath
), all the third party libraries. 我可以通过手动指定两个不同的地方(即通过
Properties->Java Build Path->Libraries
构建路径,以及通过Run Configurations->Classpath
执行类Run Configurations->Classpath
)来解决上述两个问题,所有第三方库。 But it seems like I shouldn't have to do this manually, since all the third party libraries are already listed in my JAR's manifest. 但似乎我不应该手动执行此操作,因为所有第三方库已经列在我的JAR清单中。 What am I doing wrong?
我究竟做错了什么?
Here's my build.xml
file: 这是我的
build.xml
文件:
<!-- Set global properties for this build -->
<property name="src" location="./src" />
<property name="build" location="./build"/>
<property name="dist" location="./dist"/>
<property name="logs" location="./logs"/>
<property name="docs" location="./docs"/>
<property name="jar" location="${dist}/dynamic_analyzer.jar"/>
<property name="lib" location="../../thirdparty/lib"/>
<property name="hive-util" location="../../hive-utils/dist"/>
<property name="hpdb" location="../../hive-db/hpdb/dist"/>
<property name="static" location="../../hive-backend/static_analyzer/dist"/>
<property name="mainclass" value="com.datawarellc.main.DynamicMain"/>
<path id="dep.runtime">
<fileset dir="${lib}" includes="**/*.jar"/>
<fileset dir="${hive-util}" includes="**/*.jar"/>
<fileset dir="${hpdb}" includes="**/*.jar"/>
<fileset dir="${static}" includes="**/*.jar"/>
</path>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${dist}"/>
<delete dir="${docs}"/>
<delete dir="${logs}"/>
</target>
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
<mkdir dir="${dist}"/>
<mkdir dir="${logs}"/>
</target>
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" debug="on" includeantruntime="false">
<classpath refid="dep.runtime" />
</javac>
<!-- Debug output of classpath -->
<property name="myclasspath" refid="dep.runtime"/>
<echo message="Classpath = ${myclasspath}"/>
</target>
<target name="jar" depends="compile">
<!-- Put the classpath in the manifest -->
<manifestclasspath property="manifest_cp" jarfile="${jar}" maxParentLevels="10">
<classpath refid="dep.runtime" />
</manifestclasspath>
<jar jarfile="${jar}" basedir="${build}">
<manifest>
<attribute name="Main-Class" value="${mainclass}"/>
<attribute name="Class-Path" value="${manifest_cp}"/>
</manifest>
<zipfileset dir="${src}" includes="**/*.xml" />
</jar>
</target>
You can see that I have third-party libraries in several directories ( ${lib}
, ${hive-util}
, ${hpdb}
, and ${static}
). 您可以看到我在多个目录中有第三方库(
${lib}
, ${hive-util}
, ${hpdb}
和${static}
)。 I use these to create a path
called dep.runtime
. 我使用它们来创建一个名为
dep.runtime
的path
。 I then include dep.runtime
in the manifest when building my jar. 然后我在构建我的jar时在清单中包含
dep.runtime
。 How can I get Eclipse to use the same dep.runtime
for the build path and the classpath when executing? 如何让Eclipse在执行时使用相同的
dep.runtime
作为构建路径和类路径?
An alternative to perl is to use an embedded groovy task : perl的替代方法是使用嵌入式groovy任务 :
<project name="demo" default="eclipse-files">
<property name="src.dir" location="src"/>
<property name="classes.dir" location="build/classes"/>
<path id="dep.runtime">
<fileset dir="${lib}" includes="**/*.jar"/>
<fileset dir="${hive-util}" includes="**/*.jar"/>
<fileset dir="${hpdb}" includes="**/*.jar"/>
<fileset dir="${static}" includes="**/*.jar"/>
</path>
<target name="bootstrap">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.4/groovy-all-2.1.4.jar"/>
</target>
<target name="eclipse-files">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
import groovy.xml.MarkupBuilder
project.log "Creating .classpath"
new File(".classpath").withWriter { writer ->
def xml = new MarkupBuilder(writer)
xml.classpath() {
classpathentry(kind:"src", path:properties["src.dir"])
classpathentry(kind:"output", path:properties["classes.dir"])
classpathentry(kind:"con", path:"org.eclipse.jdt.launching.JRE_CONTAINER")
project.references."dep.runtime".each {
classpathentry(kind:"lib", path:it)
}
}
}
</groovy>
</target>
<target name="clean">
<delete file=".classpath"/>
</target>
</project>
Notes: 笔记:
The following answer is similar and additionally generates the Eclipse .project file. 以下答案类似,另外还生成Eclipse .project文件。
I came up with the following workaround, inspired by the link provided by @leeand00. 我想出了以下解决方法,灵感来自@ leeand00提供的链接。
First, I wrote a simple Perl script (called genClasspath.pl
) that generates the .classpath
file that Eclipse uses. 首先,我编写了一个简单的Perl脚本(称为
genClasspath.pl
),它生成Eclipse使用的.classpath
文件。
#!/usr/bin/perl
use strict;
if (@ARGV != 2) {
print STDERR "Usage: $0 OUTFILE CLASSPATHSTRING\n";
print STDERR "e.g., $0 .classpath path1:path2:path3\n";
exit 1;
}
my $OUTFILE = $ARGV[0];
my $CLASSPATHSTRING = $ARGV[1];
open my $out_fh, '>', $OUTFILE or die "Couldn't open output file: $!";
print $out_fh q{<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="build"/>
};
my @libs = split(":", $CLASSPATHSTRING);
foreach my $thisLib (@libs){
print $out_fh " <classpathentry kind=\"lib\" path=\"$thisLib\"/>\n";
}
print $out_fh "</classpath>\n";
Then, I have my build.xml
file call this script with the content of dep.runtime
: 然后,我让我的
build.xml
文件使用dep.runtime
的内容调用此脚本:
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" debug="on" includeantruntime="false">
<classpath refid="dep.runtime" />
</javac>
<property name="myclasspath" refid="dep.runtime"/>
<exec dir="." executable="../../scripts/genClasspath.pl" os="Linux">
<arg value=".classpath"/>
<arg value="${myclasspath}"/>
</exec>
</target>
The only catch is that I need to run Ant on the command line at least once before I open the project in Eclipse. 唯一的问题是我需要在Eclipse中打开项目之前至少在命令行上运行一次Ant。 But when I do, Eclipse is able to compile and execute my project just fine, since the classpath is exactly the same as Ant's.
但是当我这样做时,Eclipse能够很好地编译和执行我的项目,因为类路径与Ant完全相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.