Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
File handles are not released when calling the com.sun.tools.javac.Main.compile method in version 6. The handles are com/sun/tools/javac/Main.compile don���t release file handles on return File handles are not released when calling the com.sun.tools.javac.Main.compile method in version 6. The handles are released when the object is finalized. The object is instantiated on line 546 in com.sun.tools.javac.util.DefaultFileManager and should be closed when no longer in use. This results in file handles being kept to files on the class path during compilation. Operations on these files then fail. The following code reproduces the issue. When running this example make sure to specify a large enough java heap the JVM to lower the finalization rate. The code below reproduces the issue. Compile and run with: %JAVA_HOME%\bin\java.exe -Xmx512m -Xms512m -cp bin;%JAVA_HOME%\lib\tools.jar JavacWithJar import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Random; import com.sun.tools.javac.Main; public class JavacWithJar { private static File copyFileTo(File file, File directory) throws IOException { File newFile = new File(directory, file.getName()); FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(file); fos = new FileOutputStream(newFile); byte buff[] = new byte[1024]; for (int val; (val = fis.read(buff)) > 0; fos.write(buff, 0, val)) {} } finally { if (fis != null) fis.close(); if (fos != null) fos.close(); } return newFile; } private static String generateJavaClass(String className) { StringBuffer sb = new StringBuffer(); sb.append("import sun.net.spi.nameservice.dns.DNSNameService;\n"); sb.append("public class "); sb.append(className); sb.append(" {\n"); sb.append(" public void doStuff() {\n"); sb.append(" DNSNameService dns = null;\n"); sb.append(" }\n"); sb.append("}\n"); return sb.toString(); } public static void main(String[] args) throws IOException { File tmpDir = new File(System.getProperty("java.io.tmpdir")); File javaHomeDir = new File(System.getProperty("java.home")); File outputDir = new File(tmpDir, "outputDir" + new Random().nextInt(65536)); outputDir.mkdir(); outputDir.deleteOnExit(); File dnsjarfile = new File(javaHomeDir, "lib" + File.separator + "ext" + File.separator + "dnsns.jar"); File tmpJar = copyFileTo(dnsjarfile, outputDir); String className = "TheJavaFile"; File javaFile = new File(outputDir, className + ".java"); javaFile.deleteOnExit(); FileOutputStream fos = new FileOutputStream(javaFile); fos.write(generateJavaClass(className).getBytes()); fos.close(); int rc = Main.compile(new String[]{"-d", outputDir.getPath(), "-classpath", tmpJar.getPath(), javaFile.getAbsolutePath()}); if (rc != 0) { System.out.println("Couldn't compile the file (exit code=" + rc + ")"); } if (!tmpJar.delete()) { System.out.println("Error deleting file \"" + tmpJar.getPath() + "\""); } } }
|