1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package com.sun.star.lib.uno.bridges.javaremote;
25 
26 import com.sun.star.bridge.XInstanceProvider;
27 import com.sun.star.lib.TestBed;
28 import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
29 import com.sun.star.lib.uno.typeinfo.TypeInfo;
30 import com.sun.star.uno.UnoRuntime;
31 import com.sun.star.uno.XComponentContext;
32 import com.sun.star.uno.XInterface;
33 import complexlib.ComplexTestCase;
34 import util.WaitUnreachable;
35 
36 /**
37  * Test case for bug #110892#.
38  *
39  * <p>Bug #110892# "Java URP bridge holds objects indefinitely" applies to cases
40  * where an object is sent from server to client, then recursively back from
41  * client to server.  In such a case, the client should not increment its
42  * internal reference count for the object, as the server will never send back a
43  * corresponding release message.</p>
44  *
45  * <p>This test has to detect whether the spawned client process fails to
46  * garbage-collect an object, which can not be done reliably.  As an
47  * approximation, it waits for 10 sec and considers the process failing if it
48  * has not garbage-collected the object by then.</p>
49  */
50 public final class Bug110892_Test extends ComplexTestCase {
getTestMethodNames()51     public String[] getTestMethodNames() {
52         return new String[] { "test" };
53     }
54 
test()55     public void test() throws Exception {
56         assure("test",
57                new TestBed().execute(new Provider(), false, Client.class,
58                                      10000));
59     }
60 
61     public static final class Client extends TestBed.Client {
main(String[] args)62         public static void main(String[] args) {
63             new Client().execute();
64         }
65 
run(XComponentContext context)66         protected boolean run(XComponentContext context) throws Throwable {
67             XTest test = UnoRuntime.queryInterface(
68                 XTest.class, getBridge(context).getInstance("Test"));
69             test.start(new ClientObject());
70             synchronized (lock) {
71                 unreachable.waitUnreachable();
72             }
73             return true;
74         }
75 
76         private final class ClientObject implements XClientObject {
call(XServerObject server, XInterface object)77             public void call(XServerObject server, XInterface object) {
78                 synchronized (lock) {
79                     unreachable = new WaitUnreachable(object);
80                 }
81                 server.call(object);
82             }
83         }
84 
85         private final Object lock = new Object();
86         private WaitUnreachable unreachable = null;
87     }
88 
89     private static final class Provider implements XInstanceProvider {
getInstance(String instanceName)90         public Object getInstance(String instanceName) {
91             return new XTest() {
92                     public void start(XClientObject client) {
93                         client.call(
94                             new XServerObject() {
95                                 public void call(XInterface object) {}
96                             },
97                             new XInterface() {});
98                     }
99                 };
100         }
101     }
102 
103     public interface XClientObject extends XInterface {
104         void call(XServerObject server, XInterface object);
105 
106         TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("call", 0, 0) };
107     }
108 
109     public interface XServerObject extends XInterface {
110         void call(XInterface object);
111 
112         TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("call", 0, 0) };
113     }
114 
115     public interface XTest extends XInterface {
116         void start(XClientObject client);
117 
118         TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("start", 0, 0) };
119     }
120 }
121