1620ba73aSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3620ba73aSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4620ba73aSAndrew Rist * or more contributor license agreements. See the NOTICE file 5620ba73aSAndrew Rist * distributed with this work for additional information 6620ba73aSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7620ba73aSAndrew Rist * to you under the Apache License, Version 2.0 (the 8620ba73aSAndrew Rist * "License"); you may not use this file except in compliance 9620ba73aSAndrew Rist * with the License. You may obtain a copy of the License at 10620ba73aSAndrew Rist * 11620ba73aSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12620ba73aSAndrew Rist * 13620ba73aSAndrew Rist * Unless required by applicable law or agreed to in writing, 14620ba73aSAndrew Rist * software distributed under the License is distributed on an 15620ba73aSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16620ba73aSAndrew Rist * KIND, either express or implied. See the License for the 17620ba73aSAndrew Rist * specific language governing permissions and limitations 18620ba73aSAndrew Rist * under the License. 19620ba73aSAndrew Rist * 20620ba73aSAndrew Rist *************************************************************/ 21620ba73aSAndrew Rist 22620ba73aSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir package com.sun.star.lib.uno.bridges.javaremote; 25cdf0e10cSrcweir 26cdf0e10cSrcweir import com.sun.star.bridge.XInstanceProvider; 27cdf0e10cSrcweir import com.sun.star.lib.TestBed; 28cdf0e10cSrcweir import com.sun.star.lib.uno.typeinfo.MethodTypeInfo; 29cdf0e10cSrcweir import com.sun.star.lib.uno.typeinfo.TypeInfo; 30cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 31cdf0e10cSrcweir import com.sun.star.uno.XComponentContext; 32cdf0e10cSrcweir import com.sun.star.uno.XInterface; 33*9e878ba5SDamjan Jovanovic 34*9e878ba5SDamjan Jovanovic import org.junit.Test; 35*9e878ba5SDamjan Jovanovic import static org.junit.Assert.*; 36*9e878ba5SDamjan Jovanovic 37cdf0e10cSrcweir 38cdf0e10cSrcweir /** 39cdf0e10cSrcweir * Test case for bug #108825#. 40cdf0e10cSrcweir * 41cdf0e10cSrcweir * <p>Bug #108825# "Java UNO Remote Bridge: Mapped-out Objects Not Held" shows 42cdf0e10cSrcweir * that local objects that are mapped out via a remote bridge, but not held 43cdf0e10cSrcweir * locally, might be garbage collected while there are still remote references 44cdf0e10cSrcweir * to them. This test is not guaranteed to always work reliably, see comment in 45cdf0e10cSrcweir * the code.</p> 46cdf0e10cSrcweir */ 47*9e878ba5SDamjan Jovanovic public final class Bug108825_Test { 48*9e878ba5SDamjan Jovanovic @Test test()49cdf0e10cSrcweir public void test() throws Exception { 50cdf0e10cSrcweir TestBed t = new TestBed(); 51*9e878ba5SDamjan Jovanovic assertTrue("test", t.execute(new Provider(t), true, Client.class, 0)); 52cdf0e10cSrcweir } 53cdf0e10cSrcweir 54cdf0e10cSrcweir public static final class Client extends TestBed.Client { main(String[] args)55cdf0e10cSrcweir public static void main(String[] args) { 56cdf0e10cSrcweir new Client().execute(); 57cdf0e10cSrcweir } 58cdf0e10cSrcweir run(XComponentContext context)59cdf0e10cSrcweir protected boolean run(XComponentContext context) throws Throwable { 60cdf0e10cSrcweir XTest test = UnoRuntime.queryInterface( 61cdf0e10cSrcweir XTest.class, getBridge(context).getInstance("Test")); 62cdf0e10cSrcweir // Send the XObject that is held on the server side amidst two 63cdf0e10cSrcweir // dummies that are not held on the server side; then wait for the 64cdf0e10cSrcweir // dummies to be garbage collected, hoping that the XObject, if it 65cdf0e10cSrcweir // is erroneously not held on the client side, will be garbage 66cdf0e10cSrcweir // collected, too. Obviously, this is not guaranteed to always work 67cdf0e10cSrcweir // (the VM might chose not to garbage collect the dummies, hanging 68cdf0e10cSrcweir // the test forever; or the VM might chose to garbage collect the 69cdf0e10cSrcweir // dummies but not the XObject, making the test pass erroneously). 70cdf0e10cSrcweir test.offer(new Dummy(), new XObject() { public void call() {} }, 71cdf0e10cSrcweir new Dummy()); 72cdf0e10cSrcweir System.out.println("Client waiting for garbage collection..."); 73cdf0e10cSrcweir for (;;) { 74cdf0e10cSrcweir synchronized (lock) { 75cdf0e10cSrcweir if (finalizedCount == 2) { 76cdf0e10cSrcweir break; 77cdf0e10cSrcweir } 78cdf0e10cSrcweir } 79cdf0e10cSrcweir test.remoteGc(); 80cdf0e10cSrcweir gc(); 81cdf0e10cSrcweir } 82cdf0e10cSrcweir System.out.println("Client garbage collection done."); 83cdf0e10cSrcweir test.notification(); 84cdf0e10cSrcweir return true; 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir private final class Dummy implements XDummy { finalize()88cdf0e10cSrcweir protected void finalize() { 89cdf0e10cSrcweir synchronized (lock) { 90cdf0e10cSrcweir ++finalizedCount; 91cdf0e10cSrcweir } 92cdf0e10cSrcweir } 93cdf0e10cSrcweir } 94cdf0e10cSrcweir 95cdf0e10cSrcweir private final Object lock = new Object(); 96cdf0e10cSrcweir private int finalizedCount = 0; 97cdf0e10cSrcweir } 98cdf0e10cSrcweir 99cdf0e10cSrcweir // Make it as likely as possible that the VM reclaims all garbage: gc()100cdf0e10cSrcweir private static void gc() { 101cdf0e10cSrcweir System.gc(); 102cdf0e10cSrcweir System.runFinalization(); 103cdf0e10cSrcweir byte[] garbage = new byte[1024 * 1024]; 104cdf0e10cSrcweir } 105cdf0e10cSrcweir 106cdf0e10cSrcweir private static final class Provider implements XInstanceProvider { Provider(TestBed testBed)107cdf0e10cSrcweir public Provider(TestBed testBed) { 108cdf0e10cSrcweir this.testBed = testBed; 109cdf0e10cSrcweir } 110cdf0e10cSrcweir getInstance(String instanceName)111cdf0e10cSrcweir public Object getInstance(String instanceName) { 112cdf0e10cSrcweir return new XTest() { 113cdf0e10cSrcweir public void offer(XDummy dummy1, XObject obj, XDummy dummy2) 114cdf0e10cSrcweir { 115cdf0e10cSrcweir this.obj = obj; 116cdf0e10cSrcweir } 117cdf0e10cSrcweir 118cdf0e10cSrcweir public void remoteGc() { 119cdf0e10cSrcweir gc(); 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir public void notification() { 123cdf0e10cSrcweir obj.call(); 124cdf0e10cSrcweir testBed.serverDone(true); 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir private XObject obj; 128cdf0e10cSrcweir }; 129cdf0e10cSrcweir } 130cdf0e10cSrcweir 131cdf0e10cSrcweir private final TestBed testBed; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir public interface XDummy extends XInterface { 135cdf0e10cSrcweir TypeInfo[] UNOTYPEINFO = null; 136cdf0e10cSrcweir } 137cdf0e10cSrcweir 138cdf0e10cSrcweir public interface XObject extends XInterface { 139cdf0e10cSrcweir void call(); 140cdf0e10cSrcweir 141cdf0e10cSrcweir TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("call", 0, 0) }; 142cdf0e10cSrcweir } 143cdf0e10cSrcweir 144cdf0e10cSrcweir public interface XTest extends XInterface { 145cdf0e10cSrcweir void offer(XDummy dummy1, XObject obj, XDummy dummy2); 146cdf0e10cSrcweir 147cdf0e10cSrcweir void remoteGc(); 148cdf0e10cSrcweir 149cdf0e10cSrcweir void notification(); 150cdf0e10cSrcweir 151cdf0e10cSrcweir TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("offer", 0, 0), 152cdf0e10cSrcweir new MethodTypeInfo("remoteGc", 1, 0), 153cdf0e10cSrcweir new MethodTypeInfo("notification", 2, 0) }; 154cdf0e10cSrcweir } 155cdf0e10cSrcweir } 156