EVALUATION
Fixed by providing a list of class loaders to try:
1) allow user to specify classloader class via a hidden option
2) check if URLClassLoader implements Closeable, and if so, use it
3) use a private subtype of URLClassLoader that implements Closeable using reflection to access the (private) fields pointing at the jar files that need to be closed
4) fall back to standard URLClassLoader
|
|
|
EVALUATION
The problem appears to be in sun.misc.URLClassPath, which is used by java.net.URLClassLoader.
One might reasonably presume that javac could clone URLClassPath (to have a close() method, to free resources) and URLClassLoader (to have a close method to call URLClassPath.close()).
|
|
|
EVALUATION
BEA is interested in any update on this issue.
Can a finalizer help?
|
|
|
WORK AROUND
Ignore my prior comments -
One possible workaround/answer is to call close() or an appropriate "closer" right after flush() in JavaCompiler around if this is the issue, and make sure that it takes care of the URLClassLoader,
try {
fileManager.flush();
} catch (IOException e) {
I have not tried it on XP and it does not reproduce on larger machines possibly.
|
|
|
WORK AROUND
If you don't need the compiler to perform annotation processing, you can use -proc:none to disable the compiler's support for annotation processing.
|
|
|
EVALUATION
The problem is nothing to do with the file manager, which is working as expected.
The problem appears to be in java.net.URLClassLoader. The compiler creates a URLCLassLoader so that it can load any necessary annotation processors. It would appear that the URLClassLoader is holding on to the jar files, until it is garbage-collected. There is no API that javac can use to "close" a URLClassLoader.
|
|
|
EVALUATION
The test program provided works fine for me, on Windows 2000.
|
|
|
EVALUATION
I've instrumented the test program to verify that it is working as expected, and it is.
This corresponds to manual examination of the code, which indicates that the file manager should be closed in main/Main.java at round about line 300.
Closing the bug as Not Reproducible.
|
|
|
EVALUATION
JavaCompiler.close() calls DefaultFileManager.flush() not DefaultFileManager.close(). This is probably deliberate because of JSR 199 -- we don't want to unnecessarily close a JavaFileManager passed in by a client.
However, the JavaFileManager used by the compile method in question *is* supposed to be closed, by the code in main.Main.compile, round about line 301, and closing the file manager should close any archives opened by the file manager.
Needs more investigation.
|
|
|