JDK-6305025 : ORB#shutdown does not wait and leaks threads
  • Type: Bug
  • Component: other-libs
  • Sub-Component: corba:orb
  • Affected Version: 5.0,5.0u2
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-08-02
  • Updated: 2022-10-21
  • Resolved: 2006-01-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u7 b01Fixed 6Fixed
Related Reports
Duplicate :  
Description
[Once again, this is an not an RMI but an ORB bug, but there is no category to report it against].

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 ----------

Comments
EVALUATION Yes. ORB shutdown() needs synchronization with _invoke() operations.
22-12-2005