14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8164512 8191360
27 * @requires vm.compMode != "Xcomp"
28 * @summary verify if the native library is unloaded when the class loader is GC'ed
29 * @build p.Test
30 * @run main/othervm/native -Xcheck:jni NativeLibraryTest
31 */
32
33 import java.io.IOException;
34 import java.net.MalformedURLException;
35 import java.net.URL;
36 import java.net.URLClassLoader;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40
41 public class NativeLibraryTest {
42 static final Path CLASSES = Paths.get("classes");
43 static int unloadedCount = 0;
44
45 /*
46 * Called by JNI_OnUnload when the native library is unloaded
47 */
48 static void nativeLibraryUnloaded() {
49 unloadedCount++;
50 }
51
52 public static void main(String... args) throws Exception {
53 setup();
54
55 for (int count=1; count <= 5; count++) {
56 // create a class loader and load a native library
57 runTest();
58 // unloading the class loader and native library
59 System.gc();
60 // give Cleaner thread a chance to unload the native library
61 Thread.sleep(100);
62
63 // unloadedCount is incremented when the native library is unloaded
64 if (count != unloadedCount) {
65 throw new RuntimeException("Expected unloaded=" + count +
66 " but got=" + unloadedCount);
67 }
68 }
69 }
70
71 /*
72 * Loads p.Test class with a new class loader and its static initializer
73 * will load a native library.
74 *
75 * The class loader becomes unreachable when this method returns and
76 * the native library should be unloaded at some point after the class
77 * loader is garbage collected.
78 */
79 static void runTest() throws Exception {
80 // invoke p.Test.run() that loads the native library
81 Runnable r = newTestRunnable();
82 r.run();
83
84 // reload the native library by the same class loader
85 r.run();
86
87 // load the native library by another class loader
|
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8164512 8191360
27 * @requires vm.compMode != "Xcomp"
28 * @summary verify if the native library is unloaded when the class loader is GC'ed
29 * @build p.Test
30 * @run main/othervm/native -Xcheck:jni NativeLibraryTest
31 */
32
33 import java.io.IOException;
34 import java.lang.ref.WeakReference;
35 import java.net.MalformedURLException;
36 import java.net.URL;
37 import java.net.URLClassLoader;
38 import java.nio.file.Files;
39 import java.nio.file.Path;
40 import java.nio.file.Paths;
41 import java.util.concurrent.CountDownLatch;
42 import java.util.concurrent.TimeUnit;
43 import java.util.function.BooleanSupplier;
44
45 public class NativeLibraryTest {
46 static final Path CLASSES = Paths.get("classes");
47 static int unloadedCount = 0;
48
49 /** No guarantees, but effective in practice. */
50 static void forceFullGc() {
51 CountDownLatch finalizeDone = new CountDownLatch(1);
52 WeakReference<?> ref = new WeakReference<Object>(new Object() {
53 protected void finalize() { finalizeDone.countDown(); }});
54 try {
55 for (int i = 0; i < 10; i++) {
56 System.gc();
57 if (finalizeDone.await(1L, TimeUnit.SECONDS) && ref.get() == null) {
58 System.runFinalization(); // try to pick up stragglers
59 return;
60 }
61 }
62 } catch (InterruptedException unexpected) {
63 throw new AssertionError("unexpected InterruptedException");
64 }
65 throw new AssertionError("failed to do a \"full\" gc");
66 }
67
68 static void gcAwait(BooleanSupplier s) {
69 for (int i = 0; i < 10; i++) {
70 if (s.getAsBoolean())
71 return;
72 forceFullGc();
73 }
74 throw new AssertionError("failed to satisfy condition");
75 }
76
77 /*
78 * Called by JNI_OnUnload when the native library is unloaded
79 */
80 static void nativeLibraryUnloaded() {
81 unloadedCount++;
82 }
83
84 public static void main(String... args) throws Exception {
85 setup();
86
87 for (int count = 1; count <= 5; count++) {
88 // create a class loader and load a native library
89 runTest();
90
91 final int finalCount = count;
92 gcAwait(() -> unloadedCount == finalCount);
93 }
94 }
95
96 /*
97 * Loads p.Test class with a new class loader and its static initializer
98 * will load a native library.
99 *
100 * The class loader becomes unreachable when this method returns and
101 * the native library should be unloaded at some point after the class
102 * loader is garbage collected.
103 */
104 static void runTest() throws Exception {
105 // invoke p.Test.run() that loads the native library
106 Runnable r = newTestRunnable();
107 r.run();
108
109 // reload the native library by the same class loader
110 r.run();
111
112 // load the native library by another class loader
|