Суть в том, что, пока загрузчик классов загружает классы, javac вызовет JavaFileManager#list()
, чтобы получить список всех файлов в пакете.
Поэтому, чтобы использовать загрузчик пользовательских классов, вам нужноизменить (или расширить), чтобы переопределить JavaFileManager#list()
.Надеюсь, вы сможете повторно использовать некоторую логику, используемую для загрузки классов.
Возможно, вы захотите использовать свои собственные реализации JavaFileObject
для представления объектов класса.Затем вам нужно будет переопределить JavaFileManager#inferBinaryName()
(в противном случае версия javac потерпит крах).Ваши реализации JavaFileObject
также должны переопределить (по крайней мере) JavaFileObject#openInputStream
.
Вот несколько указателей: http://atamur.blogspot.be/2009/10/using-built-in-javacompiler-with-custom.html
Кроме того, не делайте свою жизнь сложнее, чем должнаи расширить ForwardingJavaFileManager
и SimpleJavaFileObject
.
. Для примера приведу пример реализации:
@Override public Iterable<JavaFileObject> list(Location location,
String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse)
throws IOException
{
Iterable<JavaFileObject> stdResults =
fileManager.list(location, packageName, kinds, recurse);
if (location != StandardLocation.CLASS_PATH
|| !kinds.contains(JavaFileObject.Kind.CLASS))
{
return stdResults;
}
Set<JavaFileObject> additional = pkgObjects.get(packageName);
if (additional == null || additional.isEmpty()) {
return stdResults;
}
List<JavaFileObject> out = new ArrayList<>();
for (JavaFileObject obj : additional) {
out.add(obj);
}
for (JavaFileObject obj : stdResults) {
out.add(obj);
}
return out;
}
, где pkgObjects
- это отображение имен пакетов на JavaFileObject
.То, как вы заполните эту карту, зависит от того, как работает ваш загрузчик классов.