JavaCompiler de JDK 1.6: comment écrire des octets de classe tableau directement à l'octet []?
-
22-09-2019 - |
Question
Je viens d'apprendre la nouvelle JavaCompiler API disponible dans JDK 1.6. Cela rend très simple à compiler un String
dans un fichier .class
directement à partir du code en cours d'exécution:
String className = "Foo";
String sourceCode = "...";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<JavaSourceFromString> unitsToCompile = new ArrayList<JavaSourceFromString>()
{{
add(new JavaSourceFromString(className, sourceCode));
}};
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
compiler.getTask(null, fileManager, null, null, null, unitsToCompile).call();
fileManager.close();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(className + ".class");
IOUtils.copyStream(fis, bos);
return bos.toByteArray();
Vous pouvez saisir la source à JavaSourceFromString
de la Javadoc.
compilera très haut la main sourceCode
à Foo.class
dans le répertoire de travail courant.
Ma question est : est-il possible de compiler directement à un tableau de byte[]
et éviter le désordre de traiter File
E / S tout à fait
La solution
Peut-être que vous pouvez créer votre propre classe de mise en œuvre javax.tools.JavaFileManager
où vous reviendriez votre propre implémentation de javax.tools.FileObject
qui serait alors l'écrire à la mémoire à la place sur le disque. Donc, pour votre sous-classe de la méthode javax.tools.FileObject
de Writer openWriter() throws IOException
vous renvoyer un java.io.StringWriter
. Toutes les méthodes doivent être converties à leurs homologues String
.
Autres conseils
La raison pour laquelle il n'y a pas d'API standard pour écrire bytecode à un tableau d'octets est que la compilation d'un fichier source Java unique peut entraîner plusieurs fichiers bytecode. Par exemple, un fichier source avec des classes imbriquées / intérieur / anonymes entraînera plusieurs fichiers bytecode.
Si vous roulez votre propre JavaFileManager, vous aurez besoin de faire face à cette situation.
L'application de démonstration fourni avec l'API JSR 199 avait une en mémoire par exemple la compilation de chaîne (qui est en fait en utilisant un MemoryFileManager
). Peut-être un coup d'oeil ici ou Comment compiler à la volée? article sur Java.net.
PS: Je ne regarde pas tous les détails, mais je suis ne pense pas qu'il gère les cas mentionnés par Stephen C .