Duplicate :
|
FULL PRODUCT VERSION : java version "1.5.0_02" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09) Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode, sharing) ADDITIONAL OS VERSION INFORMATION : XP SP 2 5.1.2600 A DESCRIPTION OF THE PROBLEM : An ORB that is servicing an outgoing call does not block on #shutdown(true). Instead the shutdown call returns immediately. This is against the specification. In addition, when the call returns the client thread does not notice. It remains stuck in CorbaResponseWaitingRoomImpl#waitForResponse. One threadpool thread "p: default-threadpool; w: Idle" is leaked in addition. STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Run the attached test program. It sets up a client and a server orb; the client calls a longer operation on the server (in an own thread) ; shuts down the client orb and the server orb. EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - Shutting down the client should block until the server operation completes. The program should terminate then. ACTUAL - Shutting down the client does not block. The client call never returns; the VM does not terminate. Output: server operation starts Shutting down client Shut down client Shutting down server server operation ends Shut down server Program should terminate now; running threads: [Thread p: default-threadpool; w: Idle (Id = 12) TIMED_WAITING com.sun.corba.se.impl.orbutil.threadpool.WorkQueueImpl@1551f60, Thread Thread-3 (Id = 11) WAITING java.lang.Object@17ee8b8, Thread Monitor Ctrl-Break (Id = 7) RUNNABLE null, Thread Signal Dispatcher (Id = 4) RUNNABLE null, Thread Finalizer (Id = 3) WAITING java.lang.ref.ReferenceQueue$Lock@e0b6f5, Thread Reference Handler (Id = 2) WAITING java.lang.ref.Reference$Lock@10bc49d, Thread main (Id = 1) RUNNABLE null] REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- /* * Copyright (c) 2005 Matthias Ernst, Hamburg. All rights reserved. */ package test; import org.omg.CORBA.ORB; import org.omg.CORBA.ORBPackage.InvalidName; import org.omg.CORBA.Object; import org.omg.CORBA.SystemException; import org.omg.CORBA.portable.*; import org.omg.PortableServer.POA; import org.omg.PortableServer.POAHelper; import org.omg.PortableServer.POAManagerPackage.AdapterInactive; import org.omg.PortableServer.POAPackage.ObjectNotActive; import org.omg.PortableServer.POAPackage.ServantAlreadyActive; import org.omg.PortableServer.POAPackage.WrongPolicy; import org.omg.PortableServer.Servant; import sun.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.util.Arrays; public class TigerORB { public static void main(String[] args) throws InvalidName, ServantAlreadyActive, WrongPolicy, ObjectNotActive, AdapterInactive, InterruptedException { final ORB server = ORB.init(args, System.getProperties()); final POA poa = POAHelper.narrow(server.resolve_initial_references("RootPOA")); poa.the_POAManager().activate(); final MyServant servant = new MyServant(); final byte[] oid = poa.activate_object(servant); final Object object = poa.id_to_reference(oid); final String ior = server.object_to_string(object); final ORB client = ORB.init(args, System.getProperties()); final ObjectImpl stub = (ObjectImpl) client.string_to_object(ior); new Thread() { public void run() { try { final OutputStream request = stub._request("callya", true); stub._invoke(request); System.out.println("Call returned"); } catch (ApplicationException e) { e.printStackTrace(); // throw (e instanceof RuntimeException) ? (RuntimeException)e : new RuntimeException(e); } catch (RemarshalException e) { e.printStackTrace(); // throw (e instanceof RuntimeException) ? (RuntimeException)e : new RuntimeException(e); } } }.start(); Thread.sleep(1000); System.out.println("Shutting down client"); client.shutdown(true); client.destroy(); System.out.println("Shut down client"); System.out.println("Shutting down server"); server.shutdown(true); server.destroy(); System.out.println("Shut down server"); final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); System.out.println("Program should terminate now; running threads: "+Arrays.asList(threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds()))); } static class MyServant extends Servant implements InvokeHandler { private static final String[] INTERFACES = new String[] { "type:body" }; public String[] _all_interfaces(POA poa, byte[] objectId) { return INTERFACES; } public OutputStream _invoke(String method, InputStream input, ResponseHandler handler) throws SystemException { System.out.println("server operation starts"); try { Thread.sleep(5000); } catch (InterruptedException e) { } System.out.println("server operation ends"); return handler.createReply(); } } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : Implement the blocking feature of ORB#shutdown yourself. Make sure no outgoing calls are active when shutting down the ORB.