Ja, dies durchaus möglich ist, solange Sie richtig die ForwardingJavaFileManager
implementieren. Die zwei wichtigsten Methoden sind inferBinaryName() und list(). Wenn Sie diese beiden richtig einrichten, kann der Compiler Klassen auflösen, die Sie zuvor kompiliert haben.
inferBinaryName()
muss die Klasse zurückkehren simple name (zum Beispiel die abgeleitete binäre Namen für com.test.Test
wäre nur Test
). Hier ist meine Implementierung (meine Unterklasse von JavaFileObject
genannt wird InAppJavaFileObject
):
@Override
public String inferBinaryName(Location location, JavaFileObject javaFileObject) {
if(location == StandardLocation.CLASS_PATH && javaFileObject instanceof InAppJavaFileObject) {
return StringUtils.substringBeforeLast(javaFileObject.getName(), ".java");
}
return super.inferBinaryName(location, javaFileObject);
}
Bitte beachte, dass ich Abstreifen „.java“ vom Ende. Wenn Sie einen JavaFileObject
erstellen, muss der Dateiname in ".java" enden, aber wenn Sie das Suffix später nicht entfernen, findet der Compiler Ihre Klasse nicht.
list()
ist ein bisschen komplizierter, weil Sie vorsichtig sein müssen, um gut mit Ihrem Delegaten Dateimanager zu spielen. In meiner Implementierung, halte ich eine Karte voll qualifizierten Klassennamen in meine Unterklasse von JavaFileObject
, die ich durchlaufen kann:
@Override
public Iterable<JavaFileObject> list(Location action, String pkg, Set<JavaFileObject.Kind> kind, boolean recurse) throws IOException {
Iterable<JavaFileObject> superFiles = super.list(action, pkg, kind, recurse);
// see if there's anything in our cache that matches the criteria.
if(action == StandardLocation.CLASS_PATH && (kind.contains(JavaFileObject.Kind.CLASS) || kind.contains(JavaFileObject.Kind.SOURCE))) {
List<JavaFileObject> ourFiles = new ArrayList<JavaFileObject>();
for(Map.Entry<String,InAppJavaFileObject> entry : files.entrySet()) {
String className = entry.getKey();
if(className.startsWith(pkg) && ("".equals(pkg) || pkg.equals(className.substring(0, className.lastIndexOf('.'))))) {
ourFiles.add(entry.getValue());
}
}
if(ourFiles.size() > 0) {
for(JavaFileObject javaFileObject : superFiles) {
ourFiles.add(javaFileObject);
}
return ourFiles;
}
}
// nothing found in our hash map that matches the criteria... return
// whatever super came up with.
return superFiles;
}
Sobald Sie diese Methoden ordnungsgemäß umgesetzt haben, funktioniert der Rest nur. Genießen!
Entschuldigung, wenn ich langsam bin, aber ich sehe nicht, wie der Link, den Sie gepostet haben, das Problem löst. Ich bin selbst auf dasselbe Problem gestoßen ... meine API ist viel sauberer und einfacher zu verwalten, wenn ich Klassen separat kompilieren kann. Ich würde es sehr schätzen, wenn Sie die Lösung als Antwort posten könnten. :) – stevevls
eigentlich, ich habe gerade das funktioniert, also habe ich eine Antwort für die Nachwelt geschrieben. Danke für die tolle Frage! – stevevls