Domanda

Il mio compilazione dinamica in Java 6 è perfettamente funzionante. Tuttavia, vorrei cambiare il percorso di uscita. Ho provato un sacco di cose (vi risparmio) senza alcun risultato. Comunque, ecco il codice di lavoro

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

Ma l'uscita va alla directory di origine, che non è quello che voglio.

Ho il sospetto che la risposta potrebbe risiedere nel compiler.getTask ma l'API non è molto esplicito su ciò che alcuni dei parametri potrebbe significare. O forse qualcosa con il filemanager. Ho provato

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

, ma ancora una volta, indovinando non è probabilmente una buona idea.

Grazie!

Modifica Ho provato con le opzioni, anche, come questo (scusate se c'è un modo più compatto):

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

e poi passando le opzioni per getTask, ma il messaggio di errore è "Flag non valido".

È stato utile?

Soluzione

Codice nel primo post avrebbe funzionato, ma il successivo errore get gettato:

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

Questo perché passando "-d folder" rende il parser credo che sia l'analisi di un'opzione. Le opzioni devono essere separati come "-d", "folder".

Esempio di applicazione segue:

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

Altri suggerimenti

stavo affrontando lo stesso problema di oggi.

La risposta (utilizzando il metodo getTask regolare invece di `run) è quello di specificare la directory di output nella FileManager:

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

E questo è tutto !! :)

La documentazione è un po 'fuorviante, voglio dire, un campione potrebbe venire molto utile. Ma alla fine mi ha portato lì.

Modifica

Ecco un esempio in esecuzione:

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

Ho 0 esperienza con gli strumenti di compilazione dinamica Java 6. Ma nessun altro ha risposto:)

Il compito compilation ottiene un oggetto FileManager. Se si utilizza quella standard, quindi le classi vengono generate nella struttura di directory di origine. Che cosa si potrebbe fare è fornire la propria sottoclasse FileManager con un metodo getFileForOutput sovrascritto. La descrizione API di getFileForOutput indica che questo influenzerà in cui i file di output tua (= classe) andrà.

Aggiorna

Come collegare file manager

  

ForwardingJavaFileManager, ForwardingFileObject e ForwardingJavaFileObject   Sottoclasse non è disponibile per l'override del comportamento di un manager di file standard in quanto è creato chiamando un metodo su un compilatore, non invocando un costruttore. Invece l'inoltro (o delega) deve essere usato. Queste classi rende facile di trasmettere la maggior parte delle chiamate ad un determinato oggetto file manager o di un file, consentendo la personalizzazione comportamento. Ad esempio, si consideri come accedere tutte le chiamate a JavaFileManager.flush ():

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

Aggiorna 2

Ho letto su compilazione dinamica e costruito la mia app per fare questo. Questo codice contiene un po 'troppo cerimonia (vale a dire che potrebbe essere semplificato), ma funziona!

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

}

Non sono sicuro di come ottenere questo codice per lavorare con un elenco generato dinamicamente dei file Java; Probabilmente sarei solo fare compiler.run separatamente per ogni file sorgente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top