1. /*
  2. * @(#)ORB.java 1.218 04/01/13
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.internal.iiop;
  8. // Import JDK stuff
  9. import java.net.*;
  10. import java.util.*;
  11. import java.security.*;
  12. // Import our stuff
  13. import org.omg.CORBA.Any;
  14. import org.omg.CORBA.SystemException;
  15. import org.omg.CORBA.OBJ_ADAPTER;
  16. import org.omg.CORBA.INTERNAL;
  17. import org.omg.CORBA.NVList;
  18. import org.omg.CORBA.CompletionStatus;
  19. import org.omg.CORBA.TRANSIENT;
  20. import org.omg.CORBA.UNKNOWN;
  21. import org.omg.CORBA.portable.ObjectImpl;
  22. import com.sun.corba.se.internal.core.ClientSubcontract;
  23. import com.sun.corba.se.internal.core.ServerSubcontract;
  24. import com.sun.corba.se.internal.core.SubcontractRegistry;
  25. import com.sun.corba.se.internal.core.ClientGIOP;
  26. import com.sun.corba.se.internal.core.ServerGIOP;
  27. import com.sun.corba.se.internal.core.InternalRuntimeForwardRequest;
  28. import com.sun.corba.se.internal.core.MarshalInputStream;
  29. import com.sun.corba.se.internal.core.MarshalOutputStream;
  30. import com.sun.corba.se.internal.core.RequestHandler;
  31. import com.sun.corba.se.internal.core.ServerResponse;
  32. import com.sun.corba.se.internal.core.ServerRequest;
  33. import com.sun.corba.se.internal.core.ServiceContextRegistry;
  34. import com.sun.corba.se.internal.core.ServiceContexts;
  35. import com.sun.corba.se.internal.core.DuplicateServiceContext;
  36. import com.sun.corba.se.internal.core.NoSuchServiceContext;
  37. import com.sun.corba.se.internal.core.SendingContextServiceContext;
  38. import com.sun.corba.se.internal.core.CodeSetServiceContext;
  39. import com.sun.corba.se.internal.core.UEInfoServiceContext;
  40. import com.sun.corba.se.internal.core.ORBVersionServiceContext;
  41. import com.sun.corba.se.internal.core.EndPoint;
  42. import com.sun.corba.se.internal.core.IOR;
  43. import com.sun.corba.se.internal.iiop.messages.ReplyMessage;
  44. import com.sun.corba.se.internal.orbutil.MinorCodes; //d11638
  45. import com.sun.corba.se.internal.orbutil.SubcontractList;
  46. import com.sun.corba.se.internal.ior.ObjectKey ;
  47. import com.sun.corba.se.internal.ior.ObjectKeyFactory ;
  48. import com.sun.corba.se.internal.ior.ObjectKeyTemplate ;
  49. import com.sun.corba.se.internal.ior.TaggedComponentFactories ;
  50. import com.sun.corba.se.internal.corba.EncapsInputStream;
  51. import com.sun.corba.se.internal.corba.EncapsOutputStream;
  52. import com.sun.corba.se.internal.corba.ClientDelegate;
  53. import com.sun.corba.se.internal.corba.ServerDelegate;
  54. /**
  55. * The JavaIDL IIOP ORB implementation.
  56. */
  57. public class ORB extends com.sun.corba.se.internal.corba.ORB implements RequestHandler {
  58. // The following fields form our special little collection of global state.
  59. // We keep it bottled up here in the ORB class and attach a reference to
  60. // ourselves to every object reference that we create and handle.
  61. protected SubcontractRegistry subcontractRegistry;
  62. protected GIOPImpl giopTransport;
  63. // This is the unique id of this server (JVM). Multiple incarnations
  64. // of this server will get different ids.
  65. protected int transientServerId=0;
  66. // The thread group of the main thread (for applications) or applet.
  67. // We make it package private from a security perspective.
  68. static ThreadGroup threadGroup;
  69. // We intend to create new threads in a reliable thread group.
  70. // This avoids problems if the application/applet
  71. // creates a thread group, makes JavaIDL calls which create a new
  72. // connection and ReaderThread, and then destroys the thread
  73. // group. If our ReaderThreads were to be part of such destroyed thread
  74. // group then it might get killed and cause other invoking threads
  75. // sharing the same connection to get a non-restartable
  76. // CommunicationFailure. We'd like to avoid that.
  77. //
  78. // Our solution is to create all of our threads in the highest thread
  79. // group that we have access to, given our own security clearance.
  80. //
  81. static {
  82. try {
  83. // try to get a thread group that's as high in the threadgroup
  84. // parent-child hierarchy, as we can get to.
  85. // this will prevent an ORB thread created during applet-init from
  86. // being killed when an applet dies.
  87. threadGroup = (ThreadGroup) AccessController.doPrivileged(
  88. new PrivilegedAction() {
  89. public Object run() {
  90. ThreadGroup tg, ptg;
  91. tg = ptg = Thread.currentThread().getThreadGroup();
  92. try {
  93. while (ptg != null) {
  94. tg = ptg;
  95. ptg = tg.getParent();
  96. }
  97. } catch (SecurityException se) {
  98. // Discontinue going higher on a security exception.
  99. }
  100. return new ThreadGroup(tg, "ORB ThreadGroup");
  101. }
  102. }
  103. );
  104. } catch (SecurityException e) {
  105. // something wrong, we go back to the original code
  106. threadGroup = Thread.currentThread().getThreadGroup();
  107. }
  108. }
  109. protected ServiceContextRegistry scr ;
  110. private static final int GENERIC = SubcontractList.Generic ;
  111. /**
  112. * Create a new ORB. Should only be invoked from the
  113. * CORBA ORB superclass. Should be followed by the appropriate
  114. * set_parameters() call.
  115. */
  116. public ORB()
  117. {
  118. // Register the tagged component factories so that
  119. // tagged components can be fully decoded when an IOR
  120. // is unmarshalled.
  121. TaggedComponentFactories.registerFactories() ;
  122. // Compute transientServerId = (milliseconds since Jan 1, 1970)/10.
  123. // Note: transientServerId will wrap in about 2^32 / 8640000 = 497 days.
  124. // If two ORBS are started at the same time then there is a possibility
  125. // of having the same transientServerId. This may result in collision
  126. // and may be a problem in ior.isLocal() check to see if the object
  127. // belongs to the current ORB. This problem is taken care of by checking
  128. // to see if the IOR port matches ORB server port in isLocalServerPort()
  129. // method.
  130. transientServerId = (int)System.currentTimeMillis();
  131. if (ORBInitDebug)
  132. dprint( "Creating service context registry" ) ;
  133. scr = new ServiceContextRegistry( this ) ;
  134. if (ORBInitDebug)
  135. dprint( "Registering service context classes" ) ;
  136. // Register service contexts
  137. try {
  138. scr.register( UEInfoServiceContext.class ) ;
  139. scr.register( CodeSetServiceContext.class ) ;
  140. scr.register( SendingContextServiceContext.class ) ;
  141. // register the service context class to handle ORB versioning
  142. scr.register( ORBVersionServiceContext.class ) ;
  143. } catch (DuplicateServiceContext dsc) {
  144. if (ORBInitDebug)
  145. dprint( "Duplicate service context registration error" ) ;
  146. throw new INTERNAL( "Duplicate Service Context error" ) ;
  147. } catch (NoSuchServiceContext dsc) {
  148. if (ORBInitDebug)
  149. dprint( "No such service context registration error" ) ;
  150. throw new INTERNAL(
  151. "Error in service context class definition" ) ;
  152. }
  153. // Register subcontracts in subcontractRegistry
  154. subcontractRegistry = new SubcontractRegistry( this, GENERIC ) ;
  155. ServerSubcontract ssc = new ServerDelegate( this ) ;
  156. ssc.setId( GENERIC ) ;
  157. subcontractRegistry.registerServer( ssc, GENERIC ) ;
  158. subcontractRegistry.registerBootstrapServer( ssc ) ;
  159. // register the server subcontract *instance*
  160. subcontractRegistry.registerClient( ClientDelegate.class, GENERIC ) ;
  161. // Initialize the GIOP transport
  162. giopTransport = new GIOPImpl(this, this);
  163. }
  164. public ClientGIOP getClientGIOP()
  165. {
  166. return giopTransport;
  167. }
  168. public ServerGIOP getServerGIOP()
  169. {
  170. return giopTransport;
  171. }
  172. public MarshalInputStream newInputStream() {
  173. return new EncapsInputStream(this);
  174. }
  175. public MarshalInputStream newInputStream(byte[] buffer, int size) {
  176. return new EncapsInputStream(this, buffer, size);
  177. }
  178. public MarshalInputStream newInputStream(byte[] buffer, int size, boolean littleEndian) {
  179. return new EncapsInputStream(this, buffer, size, littleEndian);
  180. }
  181. public MarshalOutputStream newOutputStream() {
  182. return new EncapsOutputStream(this);
  183. }
  184. public IIOPOutputStream newOutputStream(Connection c) {
  185. //REVISIT: Unlike Request/Reply based IIOPOutputStreams
  186. //this IIOPOutputStream pickes version from the ORB.
  187. //This should be OK.
  188. return new IIOPOutputStream(getGIOPVersion(), this, c);
  189. }
  190. /**
  191. * Used to determine the listen port assigned to the given type.
  192. * Useful when ports are ephemeral.
  193. */
  194. public int getServerPort (String socketType)
  195. {
  196. return giopTransport.getServerPort(socketType);
  197. }
  198. public int getTransientServerId()
  199. {
  200. return transientServerId;
  201. }
  202. public SubcontractRegistry getSubcontractRegistry()
  203. {
  204. return subcontractRegistry;
  205. }
  206. public ServiceContextRegistry getServiceContextRegistry()
  207. {
  208. return scr ;
  209. }
  210. public ServerResponse process(ServerRequest request) {
  211. checkShutdownState();
  212. if (subcontractDebugFlag) {
  213. ObjectKey okey = request.getObjectKey();
  214. ObjectKeyTemplate oktemp = okey.getTemplate() ;
  215. dprint( "process: dispatching to scid " + oktemp.getSubcontractId() ) ;
  216. }
  217. ServerSubcontract sc =
  218. subcontractRegistry.getServerSubcontract(request.getObjectKey());
  219. if (subcontractDebugFlag)
  220. dprint( "dispatching to sc " + sc ) ;
  221. if (sc == null) {
  222. SystemException ex =
  223. new OBJ_ADAPTER(MinorCodes.NO_SERVER_SC_IN_DISPATCH,
  224. CompletionStatus.COMPLETED_NO);
  225. return request.createSystemExceptionResponse(ex, null);
  226. }
  227. try {
  228. startingDispatch();
  229. try {
  230. return sc.dispatch(request);
  231. } catch (Throwable throwable) {
  232. return handleThrowableDuringServerDispatch(
  233. request,
  234. throwable,
  235. CompletionStatus.COMPLETED_MAYBE);
  236. }
  237. } finally {
  238. finishedDispatch();
  239. }
  240. }
  241. public IOR locate(ObjectKey key) {
  242. ServerSubcontract sc =
  243. subcontractRegistry.getServerSubcontract(key);
  244. if (sc == null)
  245. return null;
  246. return sc.locate(key);
  247. }
  248. public boolean isLocalHost( String hostName ) {
  249. return hostName.equals( getORBServerHost() ) ||
  250. hostName.equals( getLocalHostName() ) ;
  251. }
  252. public boolean isLocalServerId( int subcontractId, int serverId )
  253. {
  254. // If we instantiated this ORB version, we only have a transient subcontract.
  255. return serverId == transientServerId ;
  256. }
  257. // Check to see if the given port is equal to any of the ORB Server Ports.
  258. public boolean isLocalServerPort( int port ) {
  259. Collection serverEndPoints = giopTransport.getServerEndpoints( );
  260. if( serverEndPoints != null ) {
  261. Iterator iterator = serverEndPoints.iterator( );
  262. EndPoint endPoint;
  263. while( iterator.hasNext( ) ) {
  264. endPoint = (EndPoint) iterator.next( );
  265. if( endPoint.getPort() == port ) {
  266. return true;
  267. }
  268. }
  269. }
  270. return false;
  271. }
  272. /* keeping a copy of the getLocalHostName so that it can only be called
  273. * internally and the unauthorized clients cannot have access to the
  274. * localHost information, originally, the above code was calling getLocalHostName
  275. * from Connection.java. If the hostname is cached in Connection.java, then
  276. * it is a security hole, since any unauthorized client has access to
  277. * the host information. With this change it is used internally so the
  278. * security problem is resolved. Also in Connection.java, the getLocalHost()
  279. * implementation has changed to always call the
  280. * InetAddress.getLocalHost().getHostAddress()
  281. * The above mentioned method has been removed from the connection class
  282. */
  283. private static String localHostString = null;
  284. private synchronized String getLocalHostName() {
  285. if (localHostString == null) {
  286. try {
  287. localHostString =
  288. InetAddress.getLocalHost().getHostAddress();
  289. } catch (Exception ex) {
  290. throw new INTERNAL( MinorCodes.GET_LOCAL_HOST_FAILED,
  291. CompletionStatus.COMPLETED_NO );
  292. }
  293. }
  294. return localHostString ;
  295. }
  296. //
  297. // Handle Throwable.
  298. //
  299. public SystemException convertThrowableToSystemException(
  300. Throwable throwable,
  301. CompletionStatus completionStatus)
  302. {
  303. if (throwable instanceof SystemException) {
  304. return (SystemException)throwable;
  305. }
  306. if (throwable instanceof RequestCanceledException) {
  307. return new TRANSIENT("RequestCanceled",
  308. MinorCodes.REQUEST_CANCELED,
  309. CompletionStatus.COMPLETED_NO);
  310. }
  311. // If user code throws a non-SystemException report it generically.
  312. String errorString =
  313. "Unknown Application exception on server: "
  314. + throwable.getClass().getName();
  315. return new UNKNOWN(errorString,
  316. MinorCodes.RUNTIMEEXCEPTION,
  317. completionStatus);
  318. }
  319. public ServerResponse handleThrowableDuringServerDispatch(
  320. ServerRequest serverRequest,
  321. Throwable throwable,
  322. CompletionStatus completionStatus)
  323. {
  324. return handleThrowableDuringServerDispatch(serverRequest,
  325. throwable,
  326. completionStatus,
  327. 1);
  328. }
  329. private ServerResponse handleThrowableDuringServerDispatch(
  330. ServerRequest serverRequest,
  331. Throwable throwable,
  332. CompletionStatus completionStatus,
  333. int iteration)
  334. {
  335. if (iteration > 10) {
  336. throw new RuntimeException(
  337. "handleThrowableDuringServerDispatch: " +
  338. "cannot create response.");
  339. }
  340. try {
  341. if (throwable instanceof InternalRuntimeForwardRequest) {
  342. ObjectImpl objectImpl = (ObjectImpl)
  343. ((InternalRuntimeForwardRequest)throwable).forward;
  344. ClientSubcontract delegate = (ClientSubcontract)
  345. objectImpl._get_delegate();
  346. return serverRequest.createLocationForward(delegate.marshal(),
  347. null);
  348. }
  349. SystemException sex =
  350. convertThrowableToSystemException(throwable, completionStatus);
  351. return serverRequest.createSystemExceptionResponse(sex, null);
  352. } catch (Throwable throwable2) {
  353. // User code (e.g., postinvoke, interceptors) may change
  354. // the exception, so we end up back here.
  355. // Report the changed exception.
  356. return handleThrowableDuringServerDispatch(serverRequest,
  357. throwable2,
  358. completionStatus,
  359. iteration + 1);
  360. }
  361. }
  362. /******************************************************************************
  363. * The following public methods are for ORB shutdown.
  364. ******************************************************************************/
  365. protected void shutdownServants(boolean wait_for_completion) {
  366. if (ShutdownUtilDelegate.instance != null) {
  367. ShutdownUtilDelegate.instance.unregisterTargetsForORB(this);
  368. }
  369. }
  370. protected void destroyConnections() {
  371. giopTransport.destroyConnections();
  372. }
  373. /*
  374. **************************************************************************
  375. * The following methods are hooks for Portable Interceptors.
  376. * They have empty method bodies so that we may ship with or without
  377. * PI support. The actual implementations can be found in
  378. * Interceptors.PIORB. The uppermost implementations can be found
  379. * in corba.ORB. Some are explicitly overridden here in protected
  380. * scope so that we can access them from the classes in the iiop package.
  381. *************************************************************************/
  382. /*
  383. *****************
  384. * Client PI hooks
  385. *
  386. *****************/
  387. /**
  388. * Overridden from corba.ORB.
  389. * See description in corba.ORB.
  390. */
  391. // REVISIT: not sure if this is necessary in this package.
  392. protected void sendCancelRequestIfFinalFragmentNotSent() {
  393. super.sendCancelRequestIfFinalFragmentNotSent();
  394. }
  395. /*
  396. *****************
  397. * Server PI hooks
  398. *****************/
  399. /**
  400. * Overridden from corba.ORB.
  401. * See description in corba.ORB.
  402. */
  403. protected void invokeServerPIStartingPoint()
  404. throws InternalRuntimeForwardRequest
  405. {
  406. super.invokeServerPIStartingPoint();
  407. }
  408. /**
  409. * Overridden from corba.ORB.
  410. * See description in corba.ORB.
  411. */
  412. protected void invokeServerPIIntermediatePoint()
  413. throws InternalRuntimeForwardRequest
  414. {
  415. super.invokeServerPIIntermediatePoint();
  416. }
  417. /**
  418. * Overridden from corba.ORB.
  419. * See description in corba.ORB.
  420. */
  421. protected void invokeServerPIEndingPoint( ReplyMessage replyMessage )
  422. throws InternalRuntimeForwardRequest
  423. {
  424. super.invokeServerPIEndingPoint( replyMessage );
  425. }
  426. /**
  427. * Overridden from corba.ORB.
  428. * See description in corba.ORB.
  429. */
  430. protected void initializeServerPIInfo( ServerRequest request,
  431. java.lang.Object poaimpl, byte[] objectId, byte[] adapterId )
  432. {
  433. super.initializeServerPIInfo( request, poaimpl, objectId, adapterId );
  434. }
  435. /**
  436. * Overridden from corba.ORB.
  437. * See description in corba.ORB.
  438. */
  439. protected void setServerPIInfo( java.lang.Object servant,
  440. String targetMostDerivedInterface )
  441. {
  442. super.setServerPIInfo( servant, targetMostDerivedInterface );
  443. }
  444. /**
  445. * Overridden from corba.ORB.
  446. * See description in corba.ORB.
  447. */
  448. protected void setServerPIInfo( Exception exception ) {
  449. super.setServerPIInfo( exception );
  450. }
  451. /**
  452. * Overridden from corba.ORB.
  453. * See description in corba.ORB.
  454. */
  455. protected void setServerPIInfo( NVList arguments ) {
  456. super.setServerPIInfo( arguments );
  457. }
  458. /**
  459. * Overridden from corba.ORB.
  460. * See description in corba.ORB.
  461. */
  462. protected void setServerPIExceptionInfo( Any exception ) {
  463. super.setServerPIExceptionInfo( exception );
  464. }
  465. /**
  466. * Overridden from corba.ORB.
  467. * See description in corba.ORB.
  468. */
  469. protected void setServerPIInfo( Any result ) {
  470. super.setServerPIInfo( result );
  471. }
  472. /**
  473. * Overridden from corba.ORB.
  474. * See description in corba.ORB.
  475. */
  476. protected void cleanupServerPIRequest() {
  477. super.cleanupServerPIRequest();
  478. }
  479. } // Class ORB