Closed iloveeclipse closed 3 weeks ago
On Windows I see that the tests start to misbehave after test test245_jar_ref_in_jar
- the test succeeds, but report this warning at the end and following 6 tests are failing.
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest.test245_jar_ref_in_jar - 1.8
WARNING in test: org.eclipse.jdt.core.tests.compiler.regression.AbstractRegressionTest - tearDown
- problems occured while deleting C:\tmp\comptest\run.1722611893110\lib\lib8.jar
- stack trace:
-> org.eclipse.jdt.core.tests.util.Util.waitUntilFileDeleted(Util.java:1357)
-> org.eclipse.jdt.core.tests.util.Util.delete(Util.java:536)
-> org.eclipse.jdt.core.tests.util.Util.flushDirectoryContent(Util.java:800)
-> org.eclipse.jdt.core.tests.compiler.regression.AbstractRegressionTest.tearDown(AbstractRegressionTest.java:4143)
- lib file info: read, write, exist, dir
+ children:
- lib8.jar file info: read, write, exist, file
- lib9.jar file info: read, write, exist, file
- s file info: read, write, exist, dir
+ children:
- lib6.jar file info: read, write, exist, file
!!! ERROR: C:\tmp\comptest\run.1722611893110\lib\lib8.jar was never deleted even after having waited 10000ms!!!
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest.test246_jar_ref_in_jar - 1.8
I assume org.eclipse.jdt.internal.compiler.batch.Main.performCompilation()
doesn't properly clean up opened nested jars and that seem to happen now after update to 1.8 because we probably run into some code path that was never entered with Java 1.4 compilation mode.
The code is called from org.eclipse.jdt.core.tests.compiler.regression.AbstractBatchCompilerTest.invokeCompiler(PrintWriter, PrintWriter, Object, TestCompilationProgress)
and the failing tests in question have rather complex project libraries setup involving nested jar libraries.
The test failures are actually follow up problems of the test setup/teardown being unable to delete / create required jars.
On Linux, thanks to lsof
, I see that the code in question works as expected, and the opened file descriptor is closed in org.eclipse.jdt.internal.compiler.batch.ClasspathJar.reset()
for the lib/lib8.jar
with this stack:
ClasspathJar.reset() line: 281
FileSystem.cleanup() line: 430
Main.performCompilation() line: 4726
Main.compile(String[]) line: 1711
BatchCompilerTest(AbstractBatchCompilerTest).invokeCompiler(PrintWriter, PrintWriter, Object, AbstractBatchCompilerTest$TestCompilationProgress) line: 672
BatchCompilerTest(AbstractBatchCompilerTest).runTest(boolean, String[], Object, String, String, boolean, AbstractBatchCompilerTest$TestCompilationProgress) line: 589
BatchCompilerTest(AbstractBatchCompilerTest).runConformTest(String[], String, String, String, boolean) line: 475
BatchCompilerTest.test245_jar_ref_in_jar() line: 8902
So at least from Linux point of view, JDT works as expected...
It is an error in JDK that JarFile and its underlying ZIpFile ist never closed when System.getSecurityManager()==null in jdk.internal.loader.URLClassPath.JarLoader.checkJar(JarFile)
stacktrace when it happens (with JDK 21.0.2+13):
Thread [main] (Suspended)
jdk.internal.loader.URLClassPath$JarLoader.checkJar(java.util.jar.JarFile) line: 798
jdk.internal.loader.URLClassPath$JarLoader.getJarFile(java.net.URL) line: 808
jdk.internal.loader.URLClassPath$JarLoader$1.run() line: 774
jdk.internal.loader.URLClassPath$JarLoader$1.run() line: 768
java.security.AccessController.executePrivileged(java.security.PrivilegedExceptionAction<T>, java.security.AccessControlContext, java.lang.Class<?>) line: 809
java.security.AccessController.doPrivileged(java.security.PrivilegedExceptionAction<T>, java.security.AccessControlContext) line: 714
jdk.internal.loader.URLClassPath$JarLoader.ensureOpen() line: 767
jdk.internal.loader.URLClassPath$JarLoader.<init>(java.net.URL, java.net.URLStreamHandler, java.util.HashMap<java.lang.String,jdk.internal.loader.URLClassPath.Loader>, java.security.AccessControlContext) line: 734
jdk.internal.loader.URLClassPath$3.run() line: 497
jdk.internal.loader.URLClassPath$3.run() line: 479
java.security.AccessController.executePrivileged(java.security.PrivilegedExceptionAction<T>, java.security.AccessControlContext, java.lang.Class<?>) line: 809
java.security.AccessController.doPrivileged(java.security.PrivilegedExceptionAction<T>, java.security.AccessControlContext) line: 714
jdk.internal.loader.URLClassPath.getLoader(java.net.URL) line: 478
jdk.internal.loader.URLClassPath.getLoader(int) line: 446
jdk.internal.loader.URLClassPath$1.next() line: 342
jdk.internal.loader.URLClassPath$1.hasMoreElements() line: 353
java.net.URLClassLoader$3$1.run() line: 662
java.net.URLClassLoader$3$1.run() line: 660
java.security.AccessController.executePrivileged(java.security.PrivilegedAction<T>, java.security.AccessControlContext, java.lang.Class<?>) line: 778
java.security.AccessController.doPrivileged(java.security.PrivilegedAction<T>, java.security.AccessControlContext) line: 400
java.net.URLClassLoader$3.next() line: 659
java.net.URLClassLoader$3.hasMoreElements() line: 684
java.lang.CompoundEnumeration<E>.next() line: 2756
java.lang.CompoundEnumeration<E>.hasMoreElements() line: 2765
java.util.ServiceLoader$LazyClassPathLookupIterator<T>.nextProviderClass() line: 1210
java.util.ServiceLoader$LazyClassPathLookupIterator<T>.hasNextService() line: 1228
java.util.ServiceLoader$LazyClassPathLookupIterator<T>.hasNext() line: 1273
java.util.ServiceLoader$2.hasNext() line: 1309
java.util.ServiceLoader$3.hasNext() line: 1393
org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager.discoverNextProcessor() line: 177
org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.round() line: 118
org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager(org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotationProcessorManager).processAnnotations(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration[], org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding[], boolean) line: 172
org.eclipse.jdt.internal.compiler.Compiler.processAnnotations() line: 972
org.eclipse.jdt.internal.compiler.Compiler.compile(org.eclipse.jdt.internal.compiler.env.ICompilationUnit[], boolean) line: 449
org.eclipse.jdt.internal.compiler.Compiler.compile(org.eclipse.jdt.internal.compiler.env.ICompilationUnit[]) line: 425
org.eclipse.jdt.internal.compiler.batch.Main.performCompilation() line: 4710
org.eclipse.jdt.internal.compiler.batch.Main.compile(java.lang.String[]) line: 1711
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest(org.eclipse.jdt.core.tests.compiler.regression.AbstractBatchCompilerTest).invokeCompiler(java.io.PrintWriter, java.io.PrintWriter, java.lang.Object, org.eclipse.jdt.core.tests.compiler.regression.AbstractBatchCompilerTest$TestCompilationProgress) line: 672
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest(org.eclipse.jdt.core.tests.compiler.regression.AbstractBatchCompilerTest).runTest(boolean, java.lang.String[], java.lang.Object, java.lang.String, java.lang.String, boolean, org.eclipse.jdt.core.tests.compiler.regression.AbstractBatchCompilerTest$TestCompilationProgress) line: 589
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest(org.eclipse.jdt.core.tests.compiler.regression.AbstractBatchCompilerTest).runConformTest(java.lang.String[], java.lang.String, java.lang.String, java.lang.String, boolean) line: 475
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest.test245_jar_ref_in_jar() line: 608
java.lang.invoke.LambdaForm$DMH.0x000001d130234000.invokeVirtual(java.lang.Object, java.lang.Object) line: not available
java.lang.invoke.LambdaForm$MH.0x000001d130098800.invoke(java.lang.Object, java.lang.Object) line: not available
java.lang.invoke.Invokers$Holder.invokeExact_MT(java.lang.Object, java.lang.Object, java.lang.Object) line: not available
jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.lang.Object, java.lang.Object[]) line: 153
jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.lang.Object, java.lang.Object[]) line: 103
java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 580
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest(junit.framework.TestCase).runTest() line: 177
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest(org.eclipse.jdt.core.tests.junit.extension.TestCase).runTest() line: 972
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest(junit.framework.TestCase).runBare() line: 142
junit.framework.TestResult$1.protect() line: 122
junit.framework.TestResult.runProtected(junit.framework.Test, junit.framework.Protectable) line: 142
junit.framework.TestResult.run(junit.framework.TestCase) line: 125
org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest(junit.framework.TestCase).run(junit.framework.TestResult) line: 130
org.eclipse.jdt.core.tests.compiler.regression.RegressionTestSetup(junit.framework.TestSuite).runTest(junit.framework.Test, junit.framework.TestResult) line: 241
org.eclipse.jdt.core.tests.compiler.regression.RegressionTestSetup(junit.framework.TestSuite).run(junit.framework.TestResult) line: 236
org.eclipse.jdt.core.tests.compiler.regression.RegressionTestSetup(org.eclipse.jdt.core.tests.util.CompilerTestSetup).run(junit.framework.TestResult) line: 59
junit.framework.TestSuite.runTest(junit.framework.Test, junit.framework.TestResult) line: 241
junit.framework.TestSuite.run(junit.framework.TestResult) line: 236
org.junit.internal.runners.SuiteMethod(org.junit.internal.runners.JUnit38ClassRunner).run(org.junit.runner.notification.RunNotifier) line: 90
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(org.eclipse.jdt.internal.junit.runner.TestExecution) line: 93
org.eclipse.jdt.internal.junit.runner.TestExecution.run(org.eclipse.jdt.internal.junit.runner.ITestReference[]) line: 40
org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner(org.eclipse.jdt.internal.junit.runner.RemoteTestRunner).runTests(java.lang.String[], java.lang.String, org.eclipse.jdt.internal.junit.runner.TestExecution) line: 530
org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner(org.eclipse.jdt.internal.junit.runner.RemoteTestRunner).runTests(org.eclipse.jdt.internal.junit.runner.TestExecution) line: 758
org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner(org.eclipse.jdt.internal.junit.runner.RemoteTestRunner).run() line: 453
org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(java.lang.String[]) line: 83
org.eclipse.pde.internal.junit.runtime.CoreTestApplication.start(org.eclipse.equinox.app.IApplicationContext) line: 28
org.eclipse.equinox.internal.app.EclipseAppHandle.run(java.lang.Object) line: 208
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(java.lang.Object) line: 143
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(java.lang.Object) line: 109
org.eclipse.core.runtime.adaptor.EclipseStarter.run(java.lang.Object) line: 439
org.eclipse.core.runtime.adaptor.EclipseStarter.run(java.lang.String[], java.lang.Runnable) line: 271
java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object) line: not available
java.lang.invoke.LambdaForm$MH.0x000001d130005c00.invoke(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object) line: not available
java.lang.invoke.LambdaForm$MH.0x000001d130006000.invokeExact_MT(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object) line: not available
jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.lang.Object, java.lang.Object[]) line: 155
jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.lang.Object, java.lang.Object[]) line: 103
java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 580
org.eclipse.equinox.launcher.Main.invokeFramework(java.lang.String[], java.net.URL[]) line: 668
org.eclipse.equinox.launcher.Main.basicRun(java.lang.String[]) line: 605
org.eclipse.equinox.launcher.Main.run(java.lang.String[]) line: 1481
org.eclipse.equinox.launcher.Main.main(java.lang.String[]) line: 1454
And even the Cleaner does not automatically close the ZipFile as soon as it become only Phantomrechable (is only referenced by PhantomCleanable) but only if - by chance - a GC happens:
Manually triggering a GC in that state using VisualVM invokes the cleaner. That can be also used as workaround by calling System.gc() when waiting for the File to be deleted.
reported to JDK https://bugs.openjdk.org/browse/JDK-8338445
After merge of https://github.com/eclipse-jdt/eclipse.jdt.core/pull/2551 we see that
BatchCompilerTest.test248_jar_ref_in_jar
fails on Windows.https://download.eclipse.org/eclipse/downloads/drops4/I20240725-1800/testresults/html/org.eclipse.jdt.core.tests.compiler_ep433I-unit-win32-java17_win32.win32.x86_64_17.html