📄 rmiconnector.java
字号:
try { Integer[] ids = addListenersWithSubjects(names,mFilters,subjects,false); for (i=0;i<len;i++) { clis[i] = new ClientListenerInfo(ids[i], names[i], listeners[i], filters[i], handbacks[i], subjects[i]); } rmiNotifClient.postReconnection(clis); return; } catch (InstanceNotFoundException infe) { // OK, we will do one by one } int j = 0; for (i=0;i<len;i++) { try { Integer id = addListenerWithSubject(names[i], new MarshalledObject(filters[i]), subjects[i], false); clis[j++] = new ClientListenerInfo(id, names[i], listeners[i], filters[i], handbacks[i], subjects[i]); } catch (InstanceNotFoundException infe) { logger.warning("reconnectNotificationListeners", "Can't reconnect listener for " + names[i]); } } if (j != len) { ClientListenerInfo[] tmp = clis; clis = new ClientListenerInfo[j]; System.arraycopy(tmp, 0, clis, 0, j); } rmiNotifClient.postReconnection(clis); } protected void checkConnection() throws IOException { if (logger.debugOn()) logger.debug("RMIClientCommunicatorAdmin-checkConnection", "Calling the method getDefaultDomain."); connection.getDefaultDomain(null); } protected void doStart() throws IOException { // Get RMIServer stub from directory or URL encoding if needed. RMIServer stub = null; try { stub = (rmiServer!=null)?rmiServer: findRMIServer(jmxServiceURL, env); } catch (NamingException ne) { throw new IOException("Failed to get a RMI stub: "+ne); } // Connect IIOP Stub if needed. stub = connectStub(stub,env); // Calling newClient on the RMIServer stub. Object credentials = env.get(CREDENTIALS); connection = stub.newClient(credentials); // notif issues final ClientListenerInfo[] old = rmiNotifClient.preReconnection(); reconnectNotificationListeners(old); connectionId = getConnectionId(); Notification reconnectedNotif = new JMXConnectionNotification(JMXConnectionNotification.OPENED, this, connectionId, clientNotifSeqNo++, "Reconnected to server", null); sendNotification(reconnectedNotif); } protected void doStop() { try { close(); } catch (IOException ioe) { logger.warning("RMIClientCommunicatorAdmin-doStop", "Failed to call the method close():" + ioe); logger.debug("RMIClientCommunicatorAdmin-doStop",ioe); } } } //-------------------------------------------------------------------- // Private stuff - Serialization //-------------------------------------------------------------------- /** * <p>In order to be usable, an IIOP stub must be connected to an ORB. * The stub is automatically connected to the ORB if: * <ul> * <li> It was returned by the COS naming</li> * <li> Its server counterpart has been registered in COS naming * through JNDI.</li> * </ul> * Otherwise, it is not connected. A stub which is deserialized * from Jini is not connected. A stub which is obtained from a * non registered RMIIIOPServerImpl is not a connected.<br> * A stub which is not connected can't be serialized, and thus * can't be registered in Jini. A stub which is not connected can't * be used to invoke methods on the server. * <p> * In order to palliate this, this method will connect the * given stub if it is not yet connected. If the given * <var>RMIServer</var> is not an instance of * {@link javax.rmi.CORBA.Stub javax.rmi.CORBA.Stub}, then the * method do nothing and simply returns that stub. Otherwise, * this method will attempt to connect the stub to an ORB as * follows: * <ul> * <p>This method looks in the provided <var>environment</var> for * the "java.naming.corba.orb" property. If it is found, the * referenced object (an {@link org.omg.CORBA.ORB ORB}) is used to * connect the stub. Otherwise, a new org.omg.CORBA.ORB is created * by calling {@link * org.omg.CORBA.ORB#init(String[], Properties) * org.omg.CORBA.ORB.init((String[])null,(Properties)null)} * <p>The new created ORB is kept in a static * {@link WeakReference} and can be reused for connecting other * stubs. However, no reference is ever kept on the ORB provided * in the <var>environment</var> map, if any. * </ul> * @param rmiServer A RMI Server Stub. * @param environment An environment map, possibly containing an ORB. * @return the given stub. * @exception IllegalArgumentException if the * <tt>java.naming.corba.orb</tt> property is specified and * does not point to an {@link org.omg.CORBA.ORB ORB}. * @exception IOException if the connection to the ORB failed. **/ static RMIServer connectStub(RMIServer rmiServer, Map environment) throws IOException { if (rmiServer instanceof javax.rmi.CORBA.Stub) { javax.rmi.CORBA.Stub stub = (javax.rmi.CORBA.Stub) rmiServer; try { stub._orb(); } catch (BAD_OPERATION x) { stub.connect(resolveOrb(environment)); } } return rmiServer; } /** * Get the ORB specified by <var>environment</var>, or create a * new one. * <p>This method looks in the provided <var>environment</var> for * the "java.naming.corba.orb" property. If it is found, the * referenced object (an {@link org.omg.CORBA.ORB ORB}) is * returned. Otherwise, a new org.omg.CORBA.ORB is created * by calling {@link * org.omg.CORBA.ORB#init(String[], java.util.Properties) * org.omg.CORBA.ORB.init((String[])null,(Properties)null)} * <p>The new created ORB is kept in a static * {@link WeakReference} and can be reused for connecting other * stubs. However, no reference is ever kept on the ORB provided * in the <var>environment</var> map, if any. * @param environment An environment map, possibly containing an ORB. * @return An ORB. * @exception IllegalArgumentException if the * <tt>java.naming.corba.orb</tt> property is specified and * does not point to an {@link org.omg.CORBA.ORB ORB}. * @exception IOException if the ORB initialization failed. **/ static ORB resolveOrb(Map environment) throws IOException { if (environment != null) { final Object orb = environment.get(EnvHelp.DEFAULT_ORB); if (orb != null && !(orb instanceof ORB)) throw new IllegalArgumentException(EnvHelp.DEFAULT_ORB + " must be an instance of org.omg.CORBA.ORB."); if (orb != null) return (ORB)orb; } final ORB orb = (RMIConnector.orb==null)?null:RMIConnector.orb.get(); if (orb != null) return orb; final ORB newOrb = ORB.init((String[])null, (Properties)null); RMIConnector.orb = new WeakReference(newOrb); return newOrb; } /** * Read RMIConnector fields from an {@link java.io.ObjectInputStream * ObjectInputStream}. * Calls <code>s.defaultReadObject()</code> and then initializes * all transient variables that need initializing. * @param s The ObjectInputStream to read from. * @exception InvalidObjectException if none of <var>rmiServer</var> stub * or <var>jmxServiceURL</var> are set. * @see #RMIConnector(JMXServiceURL,Map) * @see #RMIConnector(RMIServer,Map) **/ private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); if (rmiServer == null && jmxServiceURL == null) throw new InvalidObjectException("rmiServer and jmxServiceURL both null"); initTransients(); } /** * Writes the RMIConnector fields to an {@link java.io.ObjectOutputStream * ObjectOutputStream}. * <p>Connects the underlying RMIServer stub to an ORB, if needed, * before serializing it. This is done using the environment * map that was provided to the constructor, if any, and as documented * in {@link javax.management.remote.rmi}.</p> * <p>This method then calls <code>s.defaultWriteObject()</code>. * Usually, <var>rmiServer</var> is null if this object * was constructed with a JMXServiceURL, and <var>jmxServiceURL</var> * is null if this object is constructed with a RMIServer stub. * <p>Note that the environment Map is not serialized, since the objects * it contains are assumed to be contextual and relevant only * with respect to the local environment (class loader, ORB, etc...).</p> * <p>After an RMIConnector is deserialized, it is assumed that the * user will call {@link #connect(Map)}, providing a new Map that * can contain values which are contextually relevant to the new * local environment.</p> * <p>Since connection to the ORB is needed prior to serializing, and * since the ORB to connect to is one of those contextual parameters, * it is not recommended to re-serialize a just de-serialized object - * as the de-serialized object has no map. Thus, when an RMIConnector * object is needed for serialization or transmission to a remote * application, it is recommended to obtain a new RMIConnector stub * by calling {@link RMIConnectorServer#toJMXConnector(Map)}.</p> * @param s The ObjectOutputStream to write to. * @exception InvalidObjectException if none of <var>rmiServer</var> stub * or <var>jmxServiceURL</var> are set. * @see #RMIConnector(JMXServiceURL,Map) * @see #RMIConnector(RMIServer,Map) **/ private void writeObject(java.io.ObjectOutputStream s) throws IOException { if (rmiServer == null && jmxServiceURL == null) throw new InvalidObjectException("rmiServer and jmxServiceURL both null."); connectStub(this.rmiServer,env); s.defaultWriteObject(); } // Initialization of transient variables. private void initTransients() { rmbscMap = new WeakHashMap(); connected = false; terminated = false; connectionBroadcaster = new NotificationBroadcasterSupport(); } //-------------------------------------------------------------------- // Private stuff - Check if stub can be trusted. //-------------------------------------------------------------------- private static void checkStub(Remote stub, Class<? extends Remote> stubClass) { // Check remote stub is from the expected class. // if (stub.getClass() != stubClass) { if (!Proxy.isProxyClass(stub.getClass())) { throw new SecurityException( "Expecting a " + stubClass.getName() + " stub!"); } else { InvocationHandler handler = Proxy.getInvocationHandler(stub); if (handler.getClass() != RemoteObjectInvocationHandler.class) throw new SecurityException( "Expecting a dynamic proxy instance with a " + RemoteObjectInvocationHandler.class.getName() + " invocation handler!"); else stub = (Remote) handler; } } // Check RemoteRef in stub is from the expected class // "sun.rmi.server.UnicastRef2". // RemoteRef ref = ((RemoteObject)stub).getRef(); if (ref.getClass() != UnicastRef2.class) throw new SecurityException( "Expecting a " + UnicastRef2.class.getName() + " remote reference in stub!"); // Check RMIClientSocketFactory in stub is from the expected class // "javax.rmi.ssl.SslRMIClientSocketFactory". // LiveRef liveRef = ((UnicastRef2)ref).getLiveRef(); RMIClientSocketFactory csf = liveRef.getClientSocketFactory(); if (csf == null || csf.getClass() != SslRMIClientSocketFactory.class) throw new SecurityException( "Expecting a " + SslRMIClientSocketFactory.class.getName() + " RMI client socket factory in stub!"); } //-------------------------------------------------------------------- // Private stuff - RMIServer creation //-------------------------------------------------------------------- private RMIServer findRMIServer(JMXServiceURL directoryURL, Map environment) throws NamingException, IOException { final boolean isIiop = RMIConnectorServer.isIiopURL(directoryURL,true); if (isIiop) { // Make sure java.naming.corba.orb is in the Map. environment.put(EnvHelp.DEFAULT_ORB,resolveOrb(environment)); } String path = directoryURL.getURLPath(); if (path.startsWith("/jndi/")) return findRMIServerJNDI(path.substring(6), environment, isIiop); else if (path.startsWith("/stub/")) return findRMIServerJRMP(path.substring(6), environment, isIiop); else if (path.startsWith("/ior/")) return findRMIServerIIOP(path.substring(5), environment, isIiop); else { final String msg = "URL path must begin with /jndi/ or /stub/ " + "or /ior/: " + path; throw new MalformedURLException(msg); } } /** * Lookup the RMIServer stub in a directory. * @param jndiURL A JNDI URL indicating the location of the Stub * (see {@link javax.management.remote.rmi}), e.g.: * <ul><li><tt>rmi://registry-host:port/rmi-stub-name</tt></li> * <li>or <tt>iiop://cosnaming-host:port/iiop-stub-name</tt></li> * <li>or <tt>ldap://ldap-host:port/java-container-dn</tt></li> * </ul> * @param env the environment Map passed to the connector. * @param isIiop true if the stub is expected to be an IIOP stub. * @return The retrieved RMIServer stub. * @exception NamingException if the stub couldn't be found. **/ private RMIServer findRMIServerJNDI(String jndiURL, Map env, boolean isIiop) throws NamingException { InitialContext ctx = new InitialContext(EnvHelp.mapToHashtable(env)); Object objref = ctx.lookup(jndiURL); ctx.close(); if (isIiop) return narrowIIOPServer(objref); else return narrowJRMPServer(objref); } private static RMIServer narrowJRMPServer(Object objref) { return (RMIServer) objref; } private static RMIServer narrowIIOPServer(Object ob
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -