Search code examples
javajava-moduleworking-directoryjava-compiler-apijavacompiler

How to set the location that JavaCompiler executes from?


I am working with javax.tools.JavaCompiler, using it to programmatically compile Java code from my running Java application. Everything is working great, except that I don't how to execute the compiler from outside the executing directory of my running Java application. More specifically, I am assuming that javac, and by extension, JavaCompiler can only reference paths relative to them, not absolute paths. Thus I don't know how to reference a path in another folder without knowing where that folder is relative to me at runtime.

Imagine my folder structure is as follows.

root
|
|--- f1 <-- my java application is running in this directory
|
|--- f2 <-- I want to compile code that is in here

If I was in the terminal, I would simply cd to the f2 directory and do what I need to there. But I don't see how to accomplish this using JavaCompiler.

I tried to put the path of my source code in the compiler options, but the problem is, they only seem to operate relative to the location of where I am running the application from. Sure, I could do --module-source-path=../f2, but that just makes my solution brittle. I want to be able to tell JavaCompiler to execute in a specific directory, and then have it work from there.

Is this possible?

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.util.List;

public class SOQ_20240225
{


   public static void main(final String[] args) throws Exception
   {
      final JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
   
      final StandardJavaFileManager standardJavaFileManager = javac.getStandardFileManager(null, null, null);

      final List<String> compilerOptions = List.of("ignore, setting module source path here");

      //What do I put here (if here) to get javac to execute in the directory I choose?
      //Or to point to that directory from wherever it is?
      //I assume I can only do relative paths, and not absolute paths.

      final var compilationTask = javac.getTask(null, null, null, compilerOptions, null, null);
   
      compilationTask.call();

   }
   
}

Solution

  • javac supports both relative paths and absolute paths. And thus, so do all of its compiler options too (for example, --module-source-path and the rest).

    So, you could simply provide a Path.toAbsolutePath() to whatever directory you want, and things should work just fine.

    "--module-source-path=" + this.moduleSourcePath.toAbsolutePath()

    Again, you must use the toAbsolutePath(), otherwise, it will not work.