Possible open file leak in com.sun.tools.javac.file.JavacFileManager
Andreas Fey
fey at apiomat.com
Mon Nov 12 07:13:57 UTC 2018
Jon,
is there an<y progress here? I would be a pleasure to me to be your beta tester ;-)
Thanks,
Andreas
On 11/5/18 15:55 AM, Jonathan Gibbons wrote:
> Andreas,
>
> We'll take a look.
>
> -- Jon
>
>
> On 11/5/18 6:24 AM, Andreas Fey wrote:
> 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<JavaFileObject> 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/20181112/2aab28ab/attachment.html>
More information about the compiler-dev
mailing list