1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.tests.java.lang.ref; 19 20 import java.lang.ref.PhantomReference; 21 import java.lang.ref.Reference; 22 import java.lang.ref.ReferenceQueue; 23 import libcore.java.lang.ref.FinalizationTester; 24 25 //TODO: write a test to verify that the referent's finalize() happens 26 // before the PhantomReference is enqueued. 27 28 public class PhantomReferenceTest extends junit.framework.TestCase { 29 static Boolean bool; 30 public boolean isCalled = false; 31 protected void doneSuite() { 32 bool = null; 33 } 34 35 /** 36 * java.lang.ref.PhantomReference#get() 37 */ 38 public void test_get() { 39 ReferenceQueue rq = new ReferenceQueue(); 40 bool = new Boolean(false); 41 PhantomReference pr = new PhantomReference(bool, rq); 42 assertNull("get() should return null.", pr.get()); 43 pr.enqueue(); 44 assertNull("get() should return null.", pr.get()); 45 pr.clear(); 46 assertNull("get() should return null.", pr.get()); 47 } 48 49 /** 50 * java.lang.Runtime#gc() 51 */ 52 public void test_gcInteraction() { 53 class TestPhantomReference<T> extends PhantomReference<T> { 54 public TestPhantomReference(T referent, 55 ReferenceQueue<? super T> q) { 56 super(referent, q); 57 } 58 public boolean enqueue() { 59 // Initiate another GC from inside enqueue() to 60 // see if it causes any problems inside the VM. 61 Runtime.getRuntime().gc(); 62 return super.enqueue(); 63 } 64 } 65 66 final ReferenceQueue rq = new ReferenceQueue(); 67 final PhantomReference[] tprs = new PhantomReference[4]; 68 69 class TestThread extends Thread { 70 public void run() { 71 // Create the object in a separate thread to ensure 72 // it will be gc'ed. 73 Object obj = new Object(); 74 tprs[0] = new TestPhantomReference(obj, rq); 75 tprs[1] = new TestPhantomReference(obj, rq); 76 tprs[2] = new TestPhantomReference(obj, rq); 77 tprs[3] = new TestPhantomReference(obj, rq); 78 } 79 } 80 81 try { 82 Thread t = new TestThread(); 83 t.start(); 84 t.join(); 85 86 FinalizationTester.induceFinalization(); 87 88 assertNull("get() should return null.", tprs[0].get()); 89 assertNull("get() should return null.", tprs[1].get()); 90 assertNull("get() should return null.", tprs[2].get()); 91 assertNull("get() should return null.", tprs[3].get()); 92 93 for (int i = 0; i < 4; i++) { 94 Reference r = rq.remove(100L); 95 assertNotNull("Reference should have been enqueued.", r); 96 } 97 98 // These are to make sure that tprs and its elements don't get 99 // optimized out. 100 assertNull("get() should return null.", tprs[0].get()); 101 assertNull("get() should return null.", tprs[1].get()); 102 assertNull("get() should return null.", tprs[2].get()); 103 assertNull("get() should return null.", tprs[3].get()); 104 } catch (InterruptedException e) { 105 fail("InterruptedException : " + e.getMessage()); 106 } 107 } 108 109 /** 110 * java.lang.ref.PhantomReference#PhantomReference(java.lang.Object, 111 * java.lang.ref.ReferenceQueue) 112 */ 113 public void test_ConstructorLjava_lang_ObjectLjava_lang_ref_ReferenceQueue() { 114 ReferenceQueue rq = new ReferenceQueue(); 115 bool = new Boolean(true); 116 try { 117 PhantomReference pr = new PhantomReference(bool, rq); 118 // Allow the finalizer to run to potentially enqueue 119 Thread.sleep(1000); 120 assertTrue("Initialization failed.", !pr.isEnqueued()); 121 } catch (Exception e) { 122 fail("Exception during test : " + e.getMessage()); 123 } 124 // need a reference to bool so the jit does not optimize it away 125 assertTrue("should always pass", bool.booleanValue()); 126 127 boolean exception = false; 128 try { 129 new PhantomReference(bool, null); 130 } catch (NullPointerException e) { 131 exception = true; 132 } 133 assertTrue("Should not throw NullPointerException", !exception); 134 } 135 136 protected void setUp() { 137 } 138 139 protected void tearDown() { 140 } 141 } 142