Frage

Meine dynamische Kompilierung in Java 6 arbeitet perfekt. Ich möchte jedoch den Ausgabepfad ändern. Ich habe versucht, jede Menge Dinge (Ich werde dich verschonen) ohne Erfolg. Wie auch immer, hier ist der Arbeits Code

String[] filesToCompile = { "testFiles/Something.java" };
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(filesToCompile);
CompilationTask task = compiler.getTask(null, fileManager, null,null, null, compilationUnits);
System.out.println("Good? " + task.call());

Aber der Ausgang geht auf das Quellverzeichnis, das ist nicht das, was ich will.

Ich vermute, dass die Antwort in dem compiler.getTask liegen kann, aber die API ist nicht sehr explizit, was einige der Parameter bedeuten könnten. Oder vielleicht etwas mit dem Dateimanager. Ich habe versucht,

fileManager.setLocation(StandardLocation.locationFor("testFiles2"), null);

, aber auch hier zu raten ist wahrscheinlich keine gute Idee.

Danke!

Edit: Ich habe versucht, mit Optionen auch so (sorry, wenn es eine kompaktere Art und Weise):

    final List<String> optionsList = new ArrayList<String>();
    optionsList.add("-d what");
    Iterable<String> options = new Iterable<String>() {         
        public Iterator<String> iterator() {
            return optionsList.iterator();
        }
    };

und dann vorbei an den Optionen getTask, aber Fehlermeldung "Invalid Flag."

War es hilfreich?

Lösung

-Code im ersten Post funktionieren würde, aber die folgende Fehlermeldung der geworfen:

java.lang.IllegalArgumentException: invalid flag: -d folder

Das ist, weil durch "-d folder" vorbei der Parser denken macht es eine Option ist das Parsen. Die Optionen müssen wie "-d", "folder" getrennt werden.

Arbeitsbeispiel folgt:

JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sjfm = javaCompiler.getStandardFileManager(null, null, null); 

String[] options = new String[] { "-d", "output" };
File[] javaFiles = new File[] { new File("src/gima/apps/flip/TestClass.java") };

CompilationTask compilationTask = javaCompiler.getTask(null, null, null,
        Arrays.asList(options),
        null,
        sjfm.getJavaFileObjects(javaFiles)
);
compilationTask.call();

Andere Tipps

Ich habe das gleiche Problem heute.

Die Antwort (mit der regulären getTask Methode statt `run) ist die Ausgabe dir im Filemanager angeben:

fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(outputDir));

Und das ist es !! :)

Die Dokumentation ein wenig irreführend ist, ich meine, könnte eine Probe kommt sehr handlich. Aber schließlich brauchte ich es.

Bearbeiten

Hier ist eine Lauf Beispiel:

    // write the test class
    File sourceFile   = new File("First.java");
    FileWriter writer = new FileWriter(sourceFile);

    writer.write(
            "package load.test;\n" +
            "public class First{}"
    );
    writer.close();

    // Get the java compiler for this platform
    JavaCompiler compiler    = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(
            null,
            null,
            null);

    //--           H E R E    --// 
    // Specify where to put the genereted .class files
    fileManager.setLocation(StandardLocation.CLASS_OUTPUT, 
                            Arrays.asList(new File("/tmp")));
    // Compile the file
    compiler
        .getTask(null,
                fileManager,
                null,
                null,
                null,
                fileManager.getJavaFileObjectsFromFiles(Arrays.asList(sourceFile)))
        .call();
    fileManager.close();

    // delete the file
    sourceFile.deleteOnExit();

Ich habe 0 Erfahrung mit den Java 6 dynamischen Compiler-Tools. Aber sonst niemand hat geantwortet:)

Die Kompilation Aufgabe erhält ein FileManager Objekt. Wenn Sie den Standard eines verwenden, werden in der Quellverzeichnisstruktur dann Klassen generiert. Was Sie tun können, ist Ihre eigene Dateimanager Unterklasse mit einem überschriebenen getFileForOutput Verfahren bereitzustellen. Die API-Beschreibung von getFileForOutput zeigt an, dass dies beeinflussen, wo die Ausgabe (= Klasse) Dateien gehen.

Aktualisieren

Wie Datei-Manager anschließen

  

ForwardingJavaFileManager, ForwardingFileObject und ForwardingJavaFileObject   Subclassing ist für das Überschreiben das Verhalten eines Standard-Dateimanager nicht verfügbar, da es durch den Aufruf einer Methode auf einem Compiler erzeugt wird, nicht durch einen Konstruktor aufgerufen wird. Statt Weiterleitung (oder eine Delegation) verwendet werden soll. Diese Klassen machen es einfach, die meisten weiterleiten Anrufe zu einem bestimmten Dateimanager oder Dateiobjekt während Customizing Verhalten ermöglicht. Betrachten Sie zum Beispiel, wie alle Anrufe JavaFileManager.flush einzuloggen ():

   final Logger logger = ...;
   Iterable<? extends JavaFileObject> compilationUnits = ...;
   JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
   StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
   JavaFileManager fileManager = new ForwardingJavaFileManager(stdFileManager) {
       public void flush() {
           logger.entering(StandardJavaFileManager.class.getName(), "flush");
           super.flush();
           logger.exiting(StandardJavaFileManager.class.getName(), "flush");
       }
   };
   compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();

Update 2

las ich auf dynamische Kompilierung und baute meine eigene App, dies zu tun. Dieser Code enthält ein wenig zu viel Zeremonie (das heißt, es vereinfacht werden könnte), aber es funktioniert!

package yar;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class DynamicCompiler {

   JavaCompiler compiler;

   public DynamicCompiler() {
      this.compiler = ToolProvider.getSystemJavaCompiler();
      if (this.compiler == null) {
         throw new NullPointerException("Cannot provide system compiler.");
      }
   }

   public void compile() {
      this.compiler.run(null, System.out, System.err, 
            "-d", "testFiles2", 
            "testFiles/Hello1.java", "testFiles/Hello2.java");
   }

   /**
    * @param args
    */
   public static void main(String[] args) {
      try {
         DynamicCompiler dc = new DynamicCompiler();
         dc.compile();
      } catch (Exception e) {
         System.err.println(e.getMessage());
      }
   }

}

Ich bin mir nicht sicher, wie der Code zu bekommen mit einer dynamisch generierten Liste von Java-Dateien zu arbeiten; Ich würde wahrscheinlich nur separat tun compiler.run für jede Quelldatei.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top