Possible open file leak in com.sun.tools.javac.file.JavacFileManager (original) (raw)
Andreas Fey fey at apiomat.com
Mon Nov 5 14:24:16 UTC 2018
- Previous message: JDK 12 RFR of JDK-8213256: Clarify runtime vs ,compile time annotations for ,RoundEnvironment.getElementsAnnotatedWith(Class)
- Next message: Possible open file leak in com.sun.tools.javac.file.JavacFileManager
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi all,
we maybe found a bug in the com.sun.tools.javac.file.JavacFileManager; our tool makes heavy use of compiling classes during runtime, and after switching from JDK 8 to 11, we noticed hundreds of open files being created during list() and only closed when JVM exists. The concerning lines of code are:
@Override @DefinedBy(Api.COMPILER) public Iterable list(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) throws IOException { checkNotModuleOrientedLocation(location); // validatePackageName(packageName); nullCheck(packageName); nullCheck(kinds);
Iterable<? extends Path> path = getLocationAsPaths(location);
if (path == null)
return List.nil();
RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName);
ListBuffer<JavaFileObject> results = new ListBuffer<>();
for (Path directory : path) {
Container container = getContainer(directory);
container.list(directory, subdirectory, kinds, recurse, results);
}
return results.toList();
}
We think, a container.close() is missing in the for loop. Without this, a filehandle is created for every container/directiry found here. To test this, the following code snipped can be used, but the location must be set property to find a valid path != null:
@Test public void testFileManager( ) throws IOException { countOpenFiles( );
final Set<javax.tools.JavaFileObject.Kind> kinds = new HashSet<>( ); kinds.add( javax.tools.JavaFileObject.Kind.OTHER ); kinds.add( javax.tools.JavaFileObject.Kind.SOURCE ); kinds.add( javax.tools.JavaFileObject.Kind.CLASS ); kinds.add( javax.tools.JavaFileObject.Kind.HTML );
final StandardJavaFileManager sfm = ToolProvider.getSystemJavaCompiler( ).getStandardFileManager( null, null, null ); sfm.list( new JavaFileManager.Location( ) { @Override public boolean isOutputLocation( ) { return false; }
@Override public String getName( ) { return "CLASS_NAME"; } }, "com", kinds, true );
countOpenFiles( ); }
private void countOpenFiles( ) { final String processName = java.lang.management.ManagementFactory.getRuntimeMXBean( ).getName( ); final long pid = Long.parseLong( processName.split( "@" )[ 0 ] ); try { final Runtime rt = Runtime.getRuntime( ); final Process pr = rt.exec( "lsof -p " + pid );
int ctr = 0; final BufferedReader br = new BufferedReader( new InputStreamReader( pr.getInputStream( ) ) ); while ( ( br.readLine( ) ) != null ) ctr++; pr.waitFor( ); pr.destroy( );
System.out.println( "Open files: " + ctr ); } catch ( final Exception e ) { e.printStackTrace( ); } }
Can anybody confirm this? Best, Andreas -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20181105/f40a972c/attachment.html>
- Previous message: JDK 12 RFR of JDK-8213256: Clarify runtime vs ,compile time annotations for ,RoundEnvironment.getElementsAnnotatedWith(Class)
- Next message: Possible open file leak in com.sun.tools.javac.file.JavacFileManager
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]