T-B*_*ull 6 java ant classpath
我希望javac任务使用系统类路径中的jar,我指的是在ant启动之前在shell环境中设置的类路径.那个类路径是
CLASSPATH=D:\local\lib\java\*;.;C:\lib\java\*;C:\lib\java\db\*
Run Code Online (Sandbox Code Playgroud)
在我的系统上.我在那里有许多项目使用的流行罐子.我在构建文件中使用的基本代码片段是
<target name="build">
<mkdir dir="${obj}" />
<javac srcdir="${src}" destdir="${obj}"
includes="**/*.java"
excludes="**/package-info.java **/deprecated/*.java"
includeAntRuntime="no" debug="true" debuglevel="source,lines"
>
<compilerarg value="-Xlint"/>
</javac>
</target>
Run Code Online (Sandbox Code Playgroud)
这样,ant只将输出目录作为类路径传递.
[javac] '-classpath'
[javac] 'D:\dev\tbull-projects\jsonc\obj'
Run Code Online (Sandbox Code Playgroud)
(jsonc是我正在研究的项目,并且D:\dev\tbull-projects\jsonc是工作目录.)我浏览了一段时间的文档并提出了两次尝试.第一个是将属性添加classpath="${java.class.path}"到javac标记.这会将一个非常长的类路径传递给编译器,列出来自ant自己的lib目录的每个jar,最后是来自JDK的tools.jar.不是我想要的类路径.
第二枪是设定
<property name="build.sysclasspath" value="first" />
Run Code Online (Sandbox Code Playgroud)
在javac被调用之前,这让我朝着正确的方向前进.现在这些行是输出:
dropping D:\dev\tbull-projects\jsonc\D:\local\lib\java\* from path as it doesn't exist
dropping D:\dev\tbull-projects\jsonc\C:\lib\java\* from path as it doesn't exist
dropping D:\dev\tbull-projects\jsonc\C:\lib\java\db\* from path as it doesn't exist
dropping D:\dev\tbull-projects\jsonc\C:\Program Files\Java\jdk1.6.0_18\jre\lib\sunrsasign.jar from path as it doesn't exist
dropping D:\dev\tbull-projects\jsonc\C:\Program Files\Java\jdk1.6.0_18\jre\classes from path as it doesn't exist
Run Code Online (Sandbox Code Playgroud)
好吧,你可以想象这些路径确实不存在.我只是不明白为什么蚂蚁以这种方式构建它们.它会知道如何在Windows上进行路径算术,不是吗?
也许我的方法基本上有缺陷,所以我会让你知道我实际上在追求什么.所以我正在开发这个项目(一个库),它使用另一个库.该项目会是开源的,所以我希望其他开发人员能够构建它,他们已经下载了依赖库,并把它放在某个地方后,他们的类路径.
从我在其他关于ant + classpath的问题中看到的情况来看,使用源代码分发依赖库是一种自定义方式(因此类路径就像./libs一样).但我肯定不想在我的git repo中放入罐子.那怎么可能呢?
T-B*_*ull -1
苏……看来我必须自己回答这个问题了。将原始类路径传递给 javac 任务可以通过以下方式实现:
<!-- load environment into the env property -->
<property environment="env" />
<javac srcdir="${src}" destdir="${obj}"
includes="**/*.java"
excludes="**/package-info.java **/deprecated/*.java"
includeAntRuntime="no" includeJavaRuntime="no"
debug="true" debuglevel="source,lines"
>
<!-- add -classpath option manually -->
<compilerarg value="-classpath" />
<compilerarg value="${env.CLASSPATH}" />
<compilerarg value="-Xlint"/>
</javac>
Run Code Online (Sandbox Code Playgroud)
至少到目前为止,javac 任务现在已经通过了正确的类路径。然而它仍然不起作用,javac 现在吐出这些抱怨:
[javac] warning: [path] bad path element "D:\local\lib\java\*": no such file or directory
[javac] warning: [path] bad path element "C:\lib\java\*": no such file or directory
[javac] warning: [path] bad path element "C:\lib\java\db\*": no such file or directory
Run Code Online (Sandbox Code Playgroud)
这是一个彻头彻尾的谎言,这些路径确实存在。我一直在使用它们,如果我在 shell 上手动创建一个等效的 javac 调用,它就会像一个魅力一样工作。我怀疑 ant 的 javac 无法解析这些目录中的 jar 文件。我必须检查一下。
更新
确实如我所怀疑的那样,javac 任务并未将通配符解析为各个存在的 jar 文件。我设法手动进行解析,现在它可以正常工作了。事实上,这个解决方案本身就是一场斗争。因此,我将在这里为那些与同样的愚蠢作斗争的可怜的灵魂留下解决方案,希望在他们问那些除了胡说八道之外无事可做的人之前(是的,阿农,正在谈论你)。
事实证明,ant 缺乏构建工具所期望的最基本的功能。事实证明我不是第一个注意到这一点的人。虽然解决方案很少,但有一篇关于使用 JavaScript 让 Apache Ant 不那么痛苦的非常好的文章,这确实拯救了我的日子。是的,ant确实可以脚本化,虽然没有保密,但似乎并不广为人知。您可以放心地假设,如果您在 Java 6 上运行 ant,则 Javascript 已经可用,无需安装其他库。
苏……言归正传。事情是这样的:
<target name="expand_classpath">
<script language="javascript"><![CDATA[
// the original classpath
var ocp = java.lang.System.getenv("CLASSPATH");
// ... split in parts
var ocp_parts = ocp.split(project.getProperty("path.separator"));
// where our individual jar filenames go,
// together with pure directories from ocp_parts
var expanded_parts = [ ];
for each (var part in ocp_parts) {
if (part.endsWith('*')) {
var dir = part.substring(0, part.length() - 1);
var f = new java.io.File(dir);
// don't know how to construct a java.io.FilenameFilter,
// therefore filter the filenames manually
for each (var file in f.listFiles())
if (file.getPath().endsWith('.jar'))
expanded_parts.push(file.getPath());
} else
expanded_parts.push(part);
}
var expanded = expanded_parts.join(project.getProperty("path.separator"));
project.setProperty("classpath.expanded", expanded);
]]></script>
<!-- <echo message="classpath.expanded = ${classpath.expanded}" /> -->
</target>
<target name="build" depends="expand_classpath">
<mkdir dir="${obj}" />
<javac srcdir="${src}" destdir="${obj}"
classpath="${classpath.expanded}"
includes="**/*.java"
excludes="**/package-info.java **/deprecated/*.java"
includeAntRuntime="no" includeJavaRuntime="no"
debug="true" debuglevel="source,lines"
>
<compilerarg value="-Xlint"/>
<compilerarg value="-Xlint:-fallthrough"/>
</javac>
</target>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10305 次 |
| 最近记录: |