我有一个自定义的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(); } } } } }
为了便于阅读,我编了很多代码。 该类还实现了list(…)方法和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();
如果我在Windows / Mac / Linux上运行eclipse中的junittesting,它的工作方式和我所期望的完全一样。 如果我在玻璃窗上运行我的项目,它也正是我所期望的。 如果我在Mac OS X Mavericks或Centos 6.4的glassfish上运行相同的项目,getJavaFileForOutput(…)根本就不会被调用! 我的文件pipe理器的getClassLoader(…)方法最终被调用,但到那时为时已晚。
什么是独特的关于防止我的getJavaFileForOuput方法被调用的linux + glassfish环境?
我敢肯定,我已经正确设置所有的环境使用相同的jdk版本:jdk1.7.0_45。
任何build议?
我会在这里回答我自己的问题。
我不能相信这事情在我的头上,但事实证明,Windows环境使用的是glassfish3,而其他环境使用的是glassfish4。 一旦我发现了这个,我使用glassfish4在windows上测试了这个项目,我能够复制我在mac / linux上遇到的同样的问题。
虽然这隐约回答了我的问题,但如果我确切地知道上面的代码在glassfish4中无法正常工作,我会在这里添加一个解释。