/** * Override parent's behavior to return all interfaces * * @param impl The remote object to use, must not be null * @return Array of classes that can be used for remote invocations. In this case, all interfaces * {@link Class#getInterfaces()} are returned * @throws ExportException */ @Override protected Class[] getRemoteInterfaces(Remote impl) throws ExportException { if (impl == null) { throw new IllegalArgumentException("impl is null"); } return (impl.getClass().getInterfaces()); }
@SuppressWarnings("UseOfSystemOutOrSystemErr") protected static void start(Remote remote) throws Exception { setupRMI(); banJNDI(); if (ourRemote != null) throw new AssertionError("Already started"); ourRemote = remote; Registry registry; int port; for (Random random = new Random(); ; ) { port = random.nextInt(0xffff); if (port < 4000) continue; try { registry = LocateRegistry.createRegistry(port); break; } catch (ExportException ignored) { } } try { Remote stub = UnicastRemoteObject.exportObject(ourRemote, 0); final String name = remote.getClass().getSimpleName() + Integer.toHexString(stub.hashCode()); registry.bind(name, stub); String id = port + "/" + name; System.out.println("Port/ID: " + id); long waitTime = 2 * 60 * 1000L; Object lock = new Object(); //noinspection InfiniteLoopStatement while (true) { //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (lock) { lock.wait(waitTime); } RemoteDeadHand deadHand = (RemoteDeadHand) registry.lookup(RemoteDeadHand.BINDING_NAME); waitTime = deadHand.ping(id); } } catch (Throwable e) { e.printStackTrace(System.err); System.exit(1); } }
public static void registryObject(String name, Remote remoteObj) throws AccessException, RemoteException, AlreadyBoundException { // Đăng ký đối tượng vào bộ đăng ký // Nó được gắn với tên nào đó // Client sẽ tìm kiếm trong bộ đăng ký với tên này để có thể gọi đối // tượng registry.bind(name, remoteObj); System.out.println( "Registered: " + name + " -> " + remoteObj.getClass().getName() + "[" + remoteObj + "]"); }
protected Object invoke( Remote server, ObjectName name, String method, Object[] args, String[] sig) throws Exception { // This should work, too, but I couldn't test it yet. // ((org.jboss.jmx.adaptor.rmi.RMIAdaptor) server). // invoke(name, method, args, sig); Class<?>[] argTypes = new Class[] {ObjectName.class, String.class, Object[].class, String[].class}; Method m = server.getClass().getMethod("invoke", argTypes); return m.invoke(server, new Object[] {name, method, args, sig}); }
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!"); } }
/** * Registers an activation descriptor (with the specified location, data, and restart mode) for * the specified object, and exports that object with the specified port, and the specified client * and server socket factories. * * <p><strong>Note:</strong> Using this method (as well as the <code>Activatable</code> * constructors that both register and export an activatable remote object) is strongly * discouraged because the actions of registering and exporting the remote object are <i>not</i> * guaranteed to be atomic. Instead, an application should register an activation descriptor and * export a remote object separately, so that exceptions can be handled properly. * * <p>This method first registers an activation descriptor for the specified object as follows. It * obtains the activation system by invoking the method {@link ActivationGroup#getSystem * ActivationGroup.getSystem}. This method then obtains an {@link ActivationID} for the object by * invoking the activation system's {@link ActivationSystem#registerObject registerObject} method * with an {@link ActivationDesc} constructed with the specified object's class name, and the * specified location, data, and restart mode. If an exception occurs obtaining the activation * system or registering the activation descriptor, that exception is thrown to the caller. * * <p>Next, this method exports the object by invoking the {@link * #exportObject(Remote,ActivationID,int,RMIClientSocketFactory,RMIServerSocketFactory) * exportObject} method with the specified remote object, the activation identifier obtained from * registration, the specified port, and the specified client and server socket factories. If an * exception occurs exporting the object, this method attempts to unregister the activation * identifier (obtained from registration) by invoking the activation system's {@link * ActivationSystem#unregisterObject unregisterObject} method with the activation identifier. If * an exception occurs unregistering the identifier, that exception is ignored, and the original * exception that occurred exporting the object is thrown to the caller. * * <p>Finally, this method invokes the {@link ActivationGroup#activeObject activeObject} method on * the activation group in this VM with the activation identifier and the specified remote object, * and returns the activation identifier to the caller. * * @param obj the object being exported * @param location the object's code location * @param data the object's bootstrapping data * @param restart if true, the object is restarted (reactivated) when either the activator is * restarted or the object's activation group is restarted after an unexpected crash; if * false, the object is only activated on demand. Specifying <code>restart</code> to be <code> * true</code> does not force an initial immediate activation of a newly registered object; * initial activation is lazy. * @param port the port on which the object is exported (an anonymous port is used if port=0) * @param csf the client-side socket factory for making calls to the remote object * @param ssf the server-side socket factory for receiving remote calls * @return the activation identifier obtained from registering the descriptor with the activation * system * @exception ActivationException if activation group is not active * @exception RemoteException if object registration or export fails * @exception UnsupportedOperationException if and only if activation is not supported by this * implementation * @since 1.2 */ public static ActivationID exportObject( Remote obj, String location, MarshalledObject<?> data, boolean restart, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws ActivationException, RemoteException { ActivationDesc desc = new ActivationDesc(obj.getClass().getName(), location, data, restart); /* * Register descriptor. */ ActivationSystem system = ActivationGroup.getSystem(); ActivationID id = system.registerObject(desc); /* * Export object. */ try { exportObject(obj, id, port, csf, ssf); } catch (RemoteException e) { /* * Attempt to unregister activation descriptor because export * failed and register/export should be atomic (see 4323621). */ try { system.unregisterObject(id); } catch (Exception ex) { } /* * Report original exception. */ throw e; } /* * This call can't fail (it is a local call, and the only possible * exception, thrown if the group is inactive, will not be thrown * because the group is not inactive). */ ActivationGroup.currentGroup().activeObject(id, obj); return id; }