System.getProperty ("java.class.path") does not show "WEB-INF / lib" and included banks

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); 

The above works fine when executed as a JUnit test, since all jars needed to compile the abc.java file. But when the same code runs as a server, it cannot find the required jar files. The output of System.getProperty("java.class.path") is 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

So my question is how to get the compiler to reference jar files from the WEB-INF / lib directory?

+1
source share
4 answers

They, as you set the java.class.path system property, pose problems - better not do this. A more elegant approach would be to use the -classpath parameter to navigate to the user class path. See How to use JDK6 ToolProvider and JavaCompiler with class loader? for more details.

Also this question may be a useful link: Using javax.tools.ToolProvider from a custom classloader?


As for creating the actual classpath, you can pass the URLClassLoader classloader URLClassLoader and get the files from these URLs (as done in this answer ).

Or you can use ServletContext . getRealPath(String) and build the entire classpath manually :

 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 

Warning : both approaches ONLY work if the extension is a web application (not a WAR file). If it is not expanded, you are out of luck.

0
source

You cannot depend on java.class.path to be configured for anything in particular.

Java sets this variable when it starts the entire JVM containing your servlet container. Since it creates many different class loaders for many other purposes, it does not change it. It can't. There is only one java.class.path value for the whole process, but each web application can have many different web applications and really many different class loaders.

You will need your own explicit configuration mechanism to pass the class path for this kind of compilation material and use getRealPath to create the paths.

+3
source

So my question is how to get the compiler to reference jar files from the WEB-INF / lib directory?

Ensure that the webapp WAR extension is expanded, you should be able to programmatically create a path class string that matches what the web container gives you. This is a β€œsimple” matter of duplicating an effective class path that uses a web container.

However, I suspect that passing the "classpath" argument to the compiler, explicitly or through System properties, is the wrong approach. I found the following in this IBM article .

The following components are required to compile a Java source:

  • The class path from which the compiler can resolve library classes. The compiler path usually consists of an ordered list of files system directories and archive files (JAR or ZIP files) that contain previously compiled .class files. The classpath is implemented by the JavaFileManager, which manages multiple source and class JavaFileObject instances and ClassLoader to the JavaFileManager constructor ....

So it seems like the right approach is to just grab the appropriate classloader object and pass it to the JavaFileManager constructor.

+2
source

Assuming you are using ANT to create your WAR file. You need to do something like below to enable banks in WEB-INF / lib in your WAR. Change the directory structure as it matches the structure of your application directory.

 <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> 
-2
source

Source: https://habr.com/ru/post/1484090/


All Articles