System.getProperty(“java.class.path”)不显示“WEB-INF / lib”和包含jar文件

时间:2010-11-25 01:30:08

标签: java compilation classpath

String CompilePath = "abc.java";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
String classpath = System.getProperty("java.class.path");
System.setProperty("java.class.path", classpath + ";" + LocalMachine.home + "WebContent/WEB-INF/lib");
int result = compiler.run(null, null, null, CompilePath);

上面运行时作为JUnit测试运行正常,因为编译jars文件需要abc.java。但是当在服务器中运行相同的代码时,它无法找到所需的jar文件。 System.getProperty("java.class.path")的输出是 E:\apache-tomcat-7.0.4\bin\bootstrap.jar;E:\apache-tomcat-7.0.4\bin\tomcat-juli.jar;C:\Program Files\Java\jdk1.6.0_21\lib\tools.jar

所以,我的问题是如何让编译器引用WEB-INF / lib目录中的jar文件?

4 个答案:

答案 0 :(得分:3)

您不能依赖java.class.path将其设置为特定的任何内容。

Java在启动包含servlet容器的整个JVM时建立此变量。因为它为许多不同的目的创建了许多不同的类加载器,所以它不会改变它。这不可以。整个过程只有一个java.class.path值,但是每个webapp中可以有许多不同的webapps,实际上有很多不同的类加载器。

您将需要自己的显式配置机制来传达此类编译内容的类路径,并使用getRealPath构建路径名。

答案 1 :(得分:2)

  

所以,我的问题是如何让编译器引用WEB-INF / lib目录中的jar文件?

假设扩展了webapp的WAR,您应该能够以编程方式创建一个类似于Web容器为您提供的类路径字符串。它“简单地”是重复Web容器使用的有效类搜索路径的问题。

但是,我怀疑将“classpath”参数显式地或通过系统属性传递给编译器是错误的方法。我在this IBM article中找到了以下内容。

  

编译Java源代码需要以下组件:

     
      
  • 一个类路径,编译器从该路径开始   可以解析库类。该   编译器类路径通常是   由有序的文件列表组成   系统目录和存档文件   (JAR或ZIP文件)包含   以前编译的.class文件。该   classpath由a实现   管理多个的JavaFileManager   源和类JavaFileObject   实例和ClassLoader传递   到JavaFileManager构造函数。 ...
  •   

所以看起来正确的方法是获取相关的类加载器对象并将其传递给JavaFileManager构造函数。

答案 2 :(得分:0)

他们设置java.class.path系统属性的方式是要求麻烦 - 最好不要这样做。 更优雅的方法是使用-classpath选项传递自定义类路径。有关详细信息,请参阅How do I use JDK6 ToolProvider and JavaCompiler with the context classloader?

这个问题也很有用:Using javax.tools.ToolProvider from a custom classloader?


关于构建实际的类路径,您可以将上下文类加载器强制转换为URLClassLoader ,并从这些URL中获取文件(如this answer中所述)。

或者您可以使用ServletContextgetRealPath(String)手动构建整个类路径

ServletConfig cfg = ...; //obtained in Servlet.init(ServletConfig) method
ServletContex ctx = cfg.getServletContext();
String realWebInfPath = ctx.getRealPath("WEB-INF/lib");
//TODO use the realWebInfPath to create a File object and iterate over all JAR files

警告:如果展开Web应用程序(不是WAR文件),两种方法都 ONLY 。如果它没有扩展,那你就不走运了。

答案 3 :(得分:-2)

假设您正在使用ANT来构建WAR文件。您需要执行类似下面的操作,在WAR中包含WEB-INF / lib下的jar。修改目录结构,因为它适合您的app目录结构。

<war warfile="yourApp.war" webxml="WEB-INF/web.xml">
            <fileset dir="yourWarDir">
                <include name="**/*.jsp"/>  
                <include name="**/include/**"/>
            </fileset>
            <include name="WEB-INF/lib/*"/>
            <include name="WEB-INF/classes/**"/>

</war>