How to set classpath when I use javax.tools.JavaCompiler compile the source?
Asked Answered
A

3

44

I use the class javax.tools.JavaCompiler (jdk6) to compile a source file, but the source file depends on some jar file. How to set the classpath of the javax.tools.JavaCompiler?

Anne answered 14/10, 2009 at 2:4 Comment(0)
F
42

The javax.tools.JavaCompiler#getTask() method takes an options parameter that allows to set compiler options. The following message describes an easy way to set them in order to access the calling program's classpath:

You need to configure the standard java file manager to know about the jar files(s) - you use the compiler options argument to do that.

By default the java compiler object only seems to know about the default locations for bootclasspath, extdirs and endorseddirs directories in terms of its classpath.

You need to add the calling program's current classpath to the java compiler instance's which gets passed on the the standard file manager, which will then find classes in the jar files.

Here's how I do it in the compiler wrapper I wrote

List<String> optionList = new ArrayList<String>();
// set compiler's classpath to be same as the runtime's
optionList.addAll(Arrays.asList("-classpath",System.getProperty("java.class.path")));

// any other options you want
optionList.addAll(Arrays.asList(options));

JavaCompiler.CompilationTask task = compiler.getTask(out,jfm,diagnostics,optionList,null,jfos);

All you'll need then is to get the proper classpath set when running the calling program.

Forester answered 14/10, 2009 at 2:57 Comment(5)
Satheesh posted this as an answer, "Would you be able to share your compiler wrapper( link does not work) thanks in advance."Parrakeet
thanks a mill for this post, ive been struggling with this for ages and this was the answer... cheers :)Afoot
BTW, classpath option of JavaCompiler doesn't "understand" wildcards. So each jar you have to add directly in this string.Halflight
The solution provided in this blog post helped me a lot. It doesn't work with setting the classpath via an option property. It implements a custom file manager to load classes from an existing classloader (e.g. a web application classloader).Cariecaries
This also helped me a lot. I'm setting up a complicated JUnit in my Maven project, where I'm creating .java files on the fly. Wanted a way to inherit the current classpath, and then add a bit. The answer is obvious really ;), but I wasn't sure it'd work inside Maven, inside Eclipse.Navarrette
N
5

The same problem occurred to me recently, finally I found two workarounds. You can set the class path either by invoke StandardJavaFileManager.setLocation(StandardLocation.CLASS_PATH, "YOUR_CLASS_PATH") or Compiler.getTask(ARG_0, ARG_1, ARG_2, CLASS_PATH_OPTIONS, just as the first answer posted here says.

Nickola answered 10/12, 2011 at 8:4 Comment(1)
To get this to work I needed to do StandardJavaFileManager.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File(classpath)));Idolla
H
0

I needed something simpler than the examples above.

The following is a self-contained example of using the built-in Java compiler, and setting the classpath for the compiler to use.

It is equivalent to creating a source file called HelloPrinter.java and then compiling it as follows:

javac -classpath C:\Users\dab\Testing\a.jar;c:\path\etc org\abc\another\HelloPrinter.java

Note how the classpath can be set using a String[] of options. This should be familiar if you're already used to running javac on the command line (as above).

This code is compatible with Java 6. You will need a JDK, not a JRE, for this to run. This example doesn't actually use the classpath. It all does is print "Hello". You can add an import statement to the generated source and call a method in an external Jar file to test this properly.

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class JavaCompilerExample {
    
    public static void main(String[] args) throws Exception {

        String className = "HelloPrinter";
        String directoryName = "org/abc/another";
        new File(directoryName).mkdirs();

        FileOutputStream fos = new FileOutputStream(directoryName+"/"+className+".java");
        PrintStream ps = new PrintStream(fos);
        ps.println(
                "package "+directoryName.replace("/", ".")  + " ; "
                + "public class " +className + 
                "{ public static void main(String[] args){System.out.println(\"Hello\");} }");
        ps.close();
        
        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
        String javacOpts[] = {"-classpath", 
                             "C:\\Users\\dab\\Testing\\a.jar;c:\\path\\etc;",
                              directoryName+"/"+className + ".java"};
        
        if ( javac.run(null, null, null,  javacOpts)!=0 ) {
            System.err.println("Error");
            System.exit(1);
        }
        
        
    }

}
Humbert answered 12/3, 2022 at 11:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.