Pregunta

Mi compilación dinámica en Java 6 está funcionando perfectamente. Sin embargo, me gustaría cambiar la ruta de salida. He probado un montón de cosas (Les ahorraré) fue en vano. De todos modos, aquí está el código de trabajo

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

Sin embargo, la salida va al directorio de origen, que no es lo que quiero.

Sospecho que la respuesta puede estar en la compiler.getTask pero la API no es muy explícito en cuanto a lo que algunos de los parámetros podría significar. O tal vez algo con el administrador de archivos. He intentado

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

pero de nuevo, adivinando probablemente no es una buena idea.

Gracias!

Editar He intentado usar opciones, también, como esto (lo siento si hay una manera más compacta):

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

y luego pasar a las opciones getTask, pero mensaje de error es "bandera no válida."

¿Fue útil?

Solución

Código en el primer post iba a funcionar, pero el siguiente de error que se consiga:

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

Esto se debe a que al pasar "-d folder" hace que el analizador creo que es una de las opciones de análisis. Las opciones deben estar separados como "-d", "folder".

Ejemplo de trabajo sigue:

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

Otros consejos

Yo estaba frente a este mismo problema hoy en día.

La respuesta (utilizando el método getTask regular en lugar de `run) es especificar el dir de salida en el el FileManager:

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

Y eso es todo !! :)

La documentación es un poco engañosa, es decir, una muestra podría ser muy útil. Pero con el tiempo que me llevó allí.

Editar

Esto es una muestra ejecutando:

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

Tengo 0 experiencia con las herramientas de compilación de Java 6 dinámicos. Pero nadie ha contestado:)

La tarea de recopilación obtiene un objeto FileManager. Si utiliza el estándar, a continuación, las clases se generan en el árbol de directorio de origen. Lo que podría hacer es proporcionar su propia subclase Gestión de archivos con un método getFileForOutput reemplazado. La descripción de la API de getFileForOutput indica que esto influirá en los archivos de su salida (= clase) irán.

Actualizar

Cómo conectar los administradores de archivos

  

ForwardingJavaFileManager, ForwardingFileObject y ForwardingJavaFileObject   Subclases no está disponible para anular el comportamiento de un administrador de archivos estándar, ya que se crea llamando a un método en un compilador, no mediante la invocación de un constructor. En lugar de reenvío (o delegación) debe ser utilizado. Estas clases hace que sea fácil que transmita la mayoría de las llamadas a un gestor de archivos o archivos objeto dado al tiempo que permite la personalización de la conducta. Por ejemplo, considere la forma de registrar todas las llamadas 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();

Actualización 2

He leído en la compilación dinámica y construido mi propia aplicación para hacer esto. Este código contiene un poco demasiado ceremonia (es decir, que podría ser simplificado) pero funciona!

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

}

No estoy seguro de cómo obtener este código para trabajar con una lista generada dinámicamente de archivos Java; Probablemente me acabo de hacer compiler.run por separado para cada archivo de origen.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top