У меня есть пользовательский JavaFileManager, который выглядит примерно так:getJavaFileForOutput (...) метод пользовательского JavaFileManager не вызывается компилятором
public class InMemoryForwardingFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
private final Map<String, ByteArrayJavaFileObject> javaFileObjects = new HashMap<>();
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException{
JavaFileObject fileObject = new ByteArrayJavaFileObject(...);
javaFileObjects.put(className, fileObject);
return fileObject;
}
@Override
public ClassLoader getClassLoader(Location location){
return new SecureClassLoader(InMemoryForwardingFileManager.class.getClassLoader()){
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
ByteArrayJavaFileObject fileObject = javaFileObjects.get(name);
if(fileObject != null){
byte[] bytes = fileObject.getBytes();
return defineClass(name, bytes, 0, bytes.length);
} else{
throw new ClassNotFoundException();
}
}
}
}
}
Я отредактированный много кода для целей удобства чтения; класс также реализует метод списка (...) и метод inferBinaryName (...).
В другой области моего проекта я бегу что-то похожее на следующее:
InMemoryForwardingFileManager fileManager = // get singleton instance
... // declare compilation units, options, diagnostic listener, etc
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compilationOptions, null, compilationUnits);
compilerTask.call();
// load and instantiate the compiled class
ClassLoader classLoader = fileManager.getClassLoader(null);
MyGeneratedClass instance = (MyGeneratedClass) classLoader.loadClass(fullClassName).newInstance();
Если я запустить несколько тестов JUnit в затмении на Windows/Mac/Linux он работает именно так, как я бы ожидать. Если я запускаю свой проект в стеклянную рыбку на окнах, он также работает точно так, как я ожидал бы. Если я запускаю тот же проект в стеклянной планете на Mac OS X Mavericks или Centos 6.4, getJavaFileForOutput (...) просто никогда не вызывается! Метод getClassLoader (...) моего файлового менеджера в конечном итоге вызван, но к тому времени уже слишком поздно.
Что уникально в среде linux + glassfish, которая мешает моему методу getJavaFileForOuput быть вызванным?
Я уверен, что у меня есть все окружения, которые правильно настроены для использования одной и той же версии jdk: jdk1.7.0_45.
Любые советы ??
Вы все нашли здесь источник проблемы? Я сталкиваюсь с этой же проблемой при попытке перехода на GF 4.1. Благодарю. – Pete
Не жалко, я этого не делал. Я оставил этот код для радикально другого решения. – mbosecke
В моем случае добавление '-proc: none' к параметрам, переданным в JavaCompiler, было трюком. Почему это работает, по-прежнему остается загадкой для меня. Отладка Я видел несколько загруженных процессоров конкретных GF; возможно, это и вызывало проблему. – Pete