12 Mart 2020 Perşembe

JavaCompiler Arayüzü

Giriş
Şu satırı dahil ederiz
import javax.tools.JavaCompiler;
getStandardFileManager metodu
İmzası şöyle
StandardJavaFileManager getStandardFileManager(
        DiagnosticListener<? super JavaFileObject> diagnosticListener,
        Locale locale,
        Charset charset);
Şöyle yaparız.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(
            diagnostics, null, null);
getTask metodu
İmzası şöyle
CompilationTask getTask(Writer out,
                        JavaFileManager fileManager,
                        DiagnosticListener<? super JavaFileObject> diagnosticListener,
                        Iterable<String> options,
                        Iterable<String> classes,
                        Iterable<? extends JavaFileObject> compilationUnits);
6 tane parametre alır
4 parametre derleyiciye geçilecek seçenekler dizisidir
6. parametre compilationUnits dizisidir. Derlenecek dosyaları belirtir

Örnek
Şöyle yaparız. Bellekteki bir kodu derler ve çıktıyı temp dizine belirtilen className ile yazar. Çıktı dizini belirtmek içim derleyiciye "-d .." seçeneği geçilir. Daha sonra bu derlenen dosya URLClassLoader ile yüklenir
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public Class<?> compileForJava11(String className, String code) throws Exception {
  Class<?> clazz = null;

  JavaFileObject sourceObject = new JavaSourceFromString(className, code);

  // Get the system Java compiler
  JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

  // Get the standard file manager
  StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null,
                null);

  // Create a temporary directory for the compiled classes
  File outputDir = new File(System.getProperty("java.io.tmpdir"));
  outputDir.mkdirs();

  // Set the compiler options
  List<String> compilerOptions = 
    List.of("-source", "11", "-target", "11", "-d", outputDir.getAbsolutePath());

  Iterable<? extends JavaFileObject> compilationUnits = List.of(sourceObject);
  JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null,
    compilerOptions, null, compilationUnits);
  boolean success = task.call();
  if (success) {
    // Load the dynamically compiled class
    URLClassLoader classLoader = 
      URLClassLoader.newInstance(new URL[]{outputDir.toURI().toURL()});
    clazz = Class.forName(className, true, classLoader);
  }
  return clazz;
}

static class JavaSourceFromString extends SimpleJavaFileObject {
  private final String code;

  public JavaSourceFromString(String name, String code) {
    super(URI.create("string:///" + name.replace('.', '/') 
      + Kind.SOURCE.extension), Kind.SOURCE);
    this.code = code;
  }

  @Override
  public CharSequence getCharContent(boolean ignoreEncodingErrors) {
    return code;
  }
}
Örnek - FileManager + Diagnostics + optionList + compilationUnit
Şöyle yaparız
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null,
  null);

List<String> optionList = new ArrayList<>();
optionList.addAll(Arrays.asList("-classpath", System.getProperty("java.class.path") +
  ";./plugins/Deft-Core.jar"));

Iterable<? extends JavaFileObject> compilationUnit = fileManager
  .getJavaFileObjectsFromFiles(Arrays.asList(script));
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics,
  optionList, null, compilationUnit);
if (task.call()) {
  ...
}
Örnek
Şöyle yaparız.
StandardJavaFileManager fileManager = compiler.getStandardFileManager(
            diagnostics, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager
            .getJavaFileObjectsFromStrings(Arrays.asList("foo.java"));
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
            diagnostics, null, null, compilationUnits);
boolean success = task.call();
Örnek
Şöyle yaparız. temp dizindeki java uzantılı dosyayı derler ve çıktıyı yine temp dizine belirtilen className ile yazar. Bunun için StandardJavaFileManager kullanılıyor. Daha sonra bu derlenen dosya URLClassLoader ile yüklenir
File parent = new File(System.getProperty("java.io.tmpdir"));
File sourceFile = new File(parent, className + ".java");


JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();

StandardJavaFileManager standardJavaFileManager = javaCompiler
  .getStandardFileManager(null, null, null);
File parentDir = sourceFile.getParentFile();
standardJavaFileManager.setLocation(StandardLocation.CLASS_OUTPUT,
  Arrays.asList(parentDir));
Iterable<? extends JavaFileObject> compilationUnits = standardJavaFileManager
  .getJavaFileObjectsFromFiles(Arrays.asList(sourceFile));

javaCompiler.getTask(null, standardJavaFileManager, null, null, null, compilationUnits)
  .call();
standardJavaFileManager.close();

URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[] {parentDir.toURI()
  .toURL()});
Class<?> dynamicClass = urlClassLoader.loadClass(className);

Hiç yorum yok:

Yorum Gönder