我有两个远程对象,我正试图将它们绑定到同一个RMI注册表。下面是我的项目结构:
我的第一个类(RemoteServer1.java)
package com.abc.rmi;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import org.apache.log4j.Logger;
public class RemoteServer1 implements IServer1Interface{
private Logger logger = Logger.getLogger(RemoteServer1.class);
public void init(){
Registry localRegistry = null;
IServer1Interface server1 = null;
try
{
int port = 1099;
logger.info("Service Property rmiRegistryPort: " + port);
server1 = (IServer1Interface)UnicastRemoteObject.exportObject(this, 0);
logger.info("Locating registry");
localRegistry = LocateRegistry.getRegistry();
try
{
localRegistry.list();
}
catch (RemoteException localRemoteException2)
{
logger.info("Creating registry");
try
{
localRegistry = LocateRegistry.createRegistry(port);
}
catch (RemoteException localRemoteException4)
{
logger.error("Server1 RemoteException. " + localRemoteException4);
throw new RuntimeException("Server1 - Registry creation failed. ", localRemoteException4);
}
}
logger.info("Binding");
localRegistry.bind("Server1", server1);
}
catch (AlreadyBoundException localAlreadyBoundException)
{
logger.warn("Server1 - Object already bound." + localAlreadyBoundException);
try
{
logger.info("Re-Binding");
localRegistry.rebind("Server1", server1);
}
catch (AccessException localAccessException)
{
throw new RuntimeException("Server1 - AccessException while re-binding. ", localAccessException);
}
catch (RemoteException localRemoteException3)
{
throw new RuntimeException("Server1 - RemoteException while re-binding. ", localRemoteException3);
}
}
catch (RemoteException localRemoteException1)
{
logger.error("Server1 RemoteException. " + localRemoteException1);
throw new RuntimeException("Server1 - RemoteException. ", localRemoteException1);
}
logger.info("Remote Server1 ready");
}
}这是我的第二个类(RemoteServer2.java)
package com.abc.rmi2;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import org.apache.log4j.Logger;
public class RemoteServer2 implements IServer2Interface{
private Logger logger = Logger.getLogger(RemoteServer2.class);
public void init(){
Registry localRegistry = null;
IServer2Interface server2 = null;
try
{
int port = 1099;
logger.info("Service Property rmiRegistryPort: " + port);
server2 = (IServer2Interface)UnicastRemoteObject.exportObject(this, 0);
logger.info("Locating registry");
localRegistry = LocateRegistry.getRegistry();
try
{
localRegistry.list();
}
catch (RemoteException localRemoteException2)
{
logger.info("Creating registry");
try
{
localRegistry = LocateRegistry.createRegistry(port);
}
catch (RemoteException localRemoteException4)
{
logger.error("Server2 RemoteException. " + localRemoteException4);
throw new RuntimeException("Server2 - Registry creation failed. ", localRemoteException4);
}
}
logger.info("Binding");
localRegistry.bind("Server2", server2);
}
catch (AlreadyBoundException localAlreadyBoundException)
{
logger.warn("Server2 - Object already bound." + localAlreadyBoundException);
try
{
logger.info("Re-Binding");
localRegistry.rebind("Server2", server2);
}
catch (AccessException localAccessException)
{
throw new RuntimeException("Server2 - AccessException while re-binding. ", localAccessException);
}
catch (RemoteException localRemoteException3)
{
throw new RuntimeException("Server2 - RemoteException while re-binding. ", localRemoteException3);
}
}
catch (RemoteException localRemoteException1)
{
logger.error("Server2 RemoteException. " + localRemoteException1);
throw new RuntimeException("Server2 - RemoteException. ", localRemoteException1);
}
logger.info("Remote Server2 ready");
}
}IServer1Interface和IServer2Interface实现java.rmi.remote。类RemoteServer1.java可以注册到RMI注册中心,但是在第二个类(RemoteServer2.java)中调用"localRegistry.rebind("Server2",server2)“行时,我得到了以下异常:
03-06-2014 18:03:43 ERROR RemoteServer2: - Server2 RemoteException. java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: com.abc.rmi2.IServer2Interface (no security manager: RMI class loader disabled)我使用以下代码在Tomcat服务器中运行:
URL url = new URL("file:///C:/temp/rmi/rmi1.jar");
URL[] urls = {url};
URLClassLoader child = new URLClassLoader(urls, this.getClass().getClassLoader());
Class classToLoad = Class.forName ("com.abc.rmi.RemoteServer1", true, child);
Method method = classToLoad.getDeclaredMethod ("init");
Object instance = classToLoad.newInstance();
Object result = method.invoke(instance);
URL url2 = new URL("file:///C:/temp/rmi/rmi2.jar");
URL[] urls2 = {url2};
URLClassLoader child2 = new URLClassLoader(urls2, this.getClass().getClassLoader());
Class classToLoad2 = Class.forName("com.abc.rmi2.RemoteServer2", true, child2);
Method method2 = classToLoad2.getDeclaredMethod("init");
Object instance2 = classToLoad2.newInstance();
Object result2 = method2.invoke(instance2);在启动Tomcat时,我没有定义任何安全管理器,也没有对Tomcat安全策略进行任何更改。我不明白的是,它如何能够很好地绑定第一个远程类,而不是第二个。我在许多地方读到,必须定义一个安全管理器才能使RMI工作,但它能够加载第一个类,而不会出现任何问题。为什么这个问题只发生在我试图绑定第二个类的时候。我还读到了属性'java.rmi.server.codebase',但我不确定第一个属性是如何加载的,即使我没有指定这个属性。有什么建议吗?
发布于 2014-03-06 18:25:46
注册表没有通过其CLASSPATH或代码库功能提供的第二个类。所以其中一个出了问题。
https://stackoverflow.com/questions/22221214
复制相似问题