Да, это вполне возможно, если вы правильно реализуете ForwardingJavaFileManager
.Два самых важных метода: inferBinaryName () и list () .Если вы правильно установите эти два параметра, компилятор сможет разрешать ранее скомпилированные классы.
inferBinaryName()
должен возвращать класс ' простое имя (например, выведенный двоичный файлимя для com.test.Test
будет просто Test
).Вот моя реализация (мой подкласс JavaFileObject
называется 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);
}
Обратите внимание, что я удаляю ".java" с конца.При создании JavaFileObject
имя файла должно заканчиваться на «.java», но если вы не удалите суффикс позже, компилятор не найдет ваш класс.
list()
немногонемного сложнее, потому что вы должны быть осторожны, чтобы хорошо играть с вашим файловым менеджером делегата.В моей реализации я сохраняю карту полного имени класса в моем подклассе JavaFileObject
, который я могу перебрать:
@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;
}
Как только вы правильно реализовали эти методы, остальные просто работают.Наслаждайтесь!