Skip to content

8204868: java/util/zip/ZipFile/TestCleaner.java still fails with "cleaner failed to clean zipfile." #23742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions test/jdk/java/util/zip/ZipFile/TestCleaner.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,16 +23,24 @@

/* @test
* @bug 8185582 8197989
* @modules java.base/java.util.zip:open java.base/jdk.internal.vm.annotation
* @summary Check the resources of Inflater, Deflater and ZipFile are always
* cleaned/released when the instance is not unreachable
* @modules java.base/java.util.zip:open java.base/jdk.internal.vm.annotation
* @library /test/lib
* @comment The test relies on the Cleaner to invoke the cleaning actions. So
* we use "othervm" to prevent any Cleaner delays that could be contributed by any
* other tests or code that might have executed on the agentvm prior to this test
* execution
* @run main/othervm TestCleaner
*/

import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.zip.*;
import jdk.internal.vm.annotation.DontInline;
import jdk.test.lib.util.ForceGC;
import static java.nio.charset.StandardCharsets.US_ASCII;

public class TestCleaner {
Expand All @@ -59,11 +67,11 @@ private static void testDeInflater() throws Throwable {
Field zsRefDef = Deflater.class.getDeclaredField("zsRef");
Field zsRefInf = Inflater.class.getDeclaredField("zsRef");
if (!zsRefDef.trySetAccessible() || !zsRefInf.trySetAccessible()) {
throw new RuntimeException("'zsRef' is not accesible");
throw new RuntimeException("'zsRef' is not accessible");
}
if (addrOf(zsRefDef.get(new Deflater())) == -1 ||
addrOf(zsRefInf.get(new Inflater())) == -1) {
throw new RuntimeException("'addr' is not accesible");
throw new RuntimeException("'addr' is not accessible");
}
List<Object> list = new ArrayList<>();
byte[] buf1 = new byte[1024];
Expand All @@ -84,16 +92,17 @@ private static void testDeInflater() throws Throwable {
}
}

int n = 10;
long cnt = list.size();
while (n-- > 0 && cnt != 0) {
Thread.sleep(100);
System.gc();
cnt = list.stream().filter(o -> addrOf(o) != 0).count();
final AtomicLong numNotYetCleaned = new AtomicLong();
// trigger GC
final boolean resourcesCleaned = ForceGC.wait(() -> {
final long remaining = list.stream().filter(o -> addrOf(o) != 0).count();
numNotYetCleaned.set(remaining);
return remaining == 0;
});
if (!resourcesCleaned) {
throw new RuntimeException(numNotYetCleaned.get()
+ " resources haven't yet been cleaned");
}
if (cnt != 0)
throw new RuntimeException("cleaner failed to clean : " + cnt);

}

@DontInline
Expand Down Expand Up @@ -139,17 +148,18 @@ private static void testZipFile() throws Throwable {
if (zsrc != null) {
Field zfileField = zsrc.getClass().getDeclaredField("zfile");
if (!zfileField.trySetAccessible()) {
throw new RuntimeException("'ZipFile.Source.zfile' is not accesible");
}
//System.out.println("zffile: " + zfileField.get(zsrc));
int n = 10;
while (n-- > 0 && zfileField.get(zsrc) != null) {
System.out.println("waiting gc ... " + n);
System.gc();
Thread.sleep(100);
throw new RuntimeException("'ZipFile.Source.zfile' is not accessible");
}
if (zfileField.get(zsrc) != null) {
throw new RuntimeException("cleaner failed to clean zipfile.");
final boolean resourceCleaned = ForceGC.wait(() -> {
try {
return zfileField.get(zsrc) == null;
} catch (IllegalAccessException e) {
// shouldn't happen
throw new RuntimeException(e);
}
});
if (!resourceCleaned) {
throw new RuntimeException("cleaner failed to clean zipfile " + zip);
}
}
}
Expand Down