如何使用通配符将JavaCompiler的类路径设置为多个.jar文件 [英] How to set up classpath of JavaCompiler to multiple .jar files using wildcard
问题描述
我正在使用 JavaCompiler
的 javax.tools
来编译一些java代码,我正在尝试使用通配符我的 classpath
为了包含所有 .jar
文件,但我失败了。
I am using JavaCompiler
of javax.tools
to compile some java code and I am trying to use wildcard in my classpath
in order to include all the .jar
files but I fail.
这是我的代码:
String classpath = "C:\tomcat6\webapps\myapp/WEB-INF/lib/javax.ws.rs-api-2.0-m10.jar;"
+ "C:\\tomcat6\\webapps\\myapp/WEB-INF/lib/javax.persistence-2.1.0.jar";
Iterable<String> options = Arrays.asList("-d", classesBaseDir,
"-classpath", classpath);
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
diagnostics, options, null, file);
boolean result = task.call();
上面的代码运行正常。但是,当我尝试将类路径
更改为
The code above works just fine. But when I am trying to change the classpath
to
String classpath = "C:\\tomcat6\\webapps\\myapp/WEB-INF/lib/*";
它失败并且
compiler.err.doesnt.exist|package javax.ws.rs does not exist
...
symbol: class GET
location: class com.my.oasis.resources.TestClass
09/04/2014 14:27:09:030 | COMPILER_DIAGNOSTIC | compileResource() - compiler.err.cant.resolve.location|cannot find symbol
...
我也尝试了以下更改
String classpath = "\"C:\\tomcat6\\webapps\\myapp/WEB-INF/lib/*\"";
String classpath = "'C:\\tomcat6\\webapps\\myapp/WEB-INF/lib/*'";
但没有一个有效。有什么想法吗?
but none of them worked. Any ideas?
谢谢
注意:路径包含斜杠的原因和反斜杠是因为我的程序在运行时识别环境并自动完成路径。
Note: the reason why the path includes slashes and backslashes is because the my program identifies the environment in runtime and auto completes the path.
编辑:我使用的是tomcat 6和java 1.7.0_21
I am using tomcat 6 and java 1.7.0_21
推荐答案
通配符:由于使用java / javaw / javac时支持Java 1.6通配符,因此需要提供更多信息: Windows / Solaris和Linux
Wildcards: Since Java 1.6 wildcards are supported when using java/javaw/javac, more information: Windows/Solaris and Linux
示例:
javac -cp "lib/*" Test.java
这将lib目录中的所有.jar文件(不是.class!)用作类路径。这不应该与shell的* -expansion混淆。 -cp lib / *
扩展为 -cp lib / a.jar lib / b.jar
这是无效的参数语法。为了避免这种情况,你必须添加引号: -cplib / *
This uses all .jar files (not .class!) in the lib directory as classpath. This should not be confused with the *-expansion of your shell. -cp lib/*
gets expanded to -cp lib/a.jar lib/b.jar
which is not valid argument syntax. In order to avoid this you have to add quotation marks: -cp "lib/*"
问题的原因:您正试图直接使用Java API从源代码调用Java编译器。此源代码不包含通配符扩展。
JDK附带一个包装器二进制文件(javac,javadoc,javah,javap都是相同的二进制文件),它执行一些操作并最终调用编译器任务。此包装器还会扩展类路径中的通配符,因此编译器任务不再需要执行此操作(并且不会这样做)。请参阅编译器自述文件部分构建 - >注意事项 - >启动程序 。 Launcher源代码。
The cause of your Problem: You are trying to call the Java compiler from source directly with its Java API. This source code does not contain the wildcard expansion. The JDK ships with a wrapper binary (javac,javadoc,javah,javap are all the same binary) which does some things and finally calls the compiler task. This wrapper also expands the wildcards in your classpath and therefore the compiler task doesn't have to do this anymore (and it doesn't). See at Compiler Readme section "build -> Notes -> The launcher". Launcher sourcecode.
解决方案:
- 一个非常糟糕的解决方案是致电
javac
通过Processbuilder。 (这是不推荐,因为它是一个简单问题的复杂且容易出错的解决方案) - 自己扩展通配符:
- A very poor solution would be to call
javac
through a Processbuilder. (This is not recommended since it is a complicated and error prone solution for a simple problem) - Expand the wildcards yourself:
示例代码:
String classpath = buildClassPath("lib/", "test/", "lib/*");
System.out.println(classpath);
// output: lib/;test/;lib/a.jar;lib/b.jar;
此函数获取所有类路径条目并构建一个类路径。带有通配符的Classpath条目将被扩展。
This function takes all classpath entries and builds one classpath. Classpath entries with a wildcard in it will get expanded.
/**
* This function builds a classpath from the passed Strings
*
* @param paths classpath elements
* @return returns the complete classpath with wildcards expanded
*/
private static String buildClassPath(String... paths) {
StringBuilder sb = new StringBuilder();
for (String path : paths) {
if (path.endsWith("*")) {
path = path.substring(0, path.length() - 1);
File pathFile = new File(path);
for (File file : pathFile.listFiles()) {
if (file.isFile() && file.getName().endsWith(".jar")) {
sb.append(path);
sb.append(file.getName());
sb.append(System.getProperty("path.separator"));
}
}
} else {
sb.append(path);
sb.append(System.getProperty("path.separator"));
}
}
return sb.toString();
}
这篇关于如何使用通配符将JavaCompiler的类路径设置为多个.jar文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!