Java 数据库对象未与正在工作的RMI包一起工作
我有两个项目。一个在任何部门都能正常工作。我下载并修改了它,以便更好地理解它。第二个是处于开发阶段的项目 现在,这两个项目都有几乎完全相同的RMI包,它在第一个项目中运行良好,但在第二个项目中不起作用 我在每个包中的测试类也基本相同 主要区别在于试图访问哪些对象,它们都是数据库包中的接口 现在,第二个项目中的数据库包在其他方面工作得非常好,它不能与RMI一起工作 简言之:Java 数据库对象未与正在工作的RMI包一起工作,java,rmi,Java,Rmi,我有两个项目。一个在任何部门都能正常工作。我下载并修改了它,以便更好地理解它。第二个是处于开发阶段的项目 现在,这两个项目都有几乎完全相同的RMI包,它在第一个项目中运行良好,但在第二个项目中不起作用 我在每个包中的测试类也基本相同 主要区别在于试图访问哪些对象,它们都是数据库包中的接口 现在,第二个项目中的数据库包在其他方面工作得非常好,它不能与RMI一起工作 简言之: 数据库包运行良好 RMI软件包运行良好 RMI包和数据库一起工作不正常 这是我的数据库接口 public interfa
- 数据库包运行良好
- RMI软件包运行良好
- RMI包和数据库一起工作不正常
public interface DB extends Remote {
public String[] read(int recNo) throws RecordNotFoundException;
public void update(int recNo, String[] data, long lockCookie)
throws RecordNotFoundException, SecurityException, IOException;
public void delete(int recNo, long lockCookie)
throws RecordNotFoundException, SecurityException, IOException;
public int[] find(String[] criteria);
public int create(String[] data) throws DuplicateKeyException, IOException;
public long lock(int recNo) throws RecordNotFoundException;
public void unlock(int recNo, long cookie)
throws RecordNotFoundException, SecurityException;
}
这是我的界面
public interface RMIInterface extends Remote{
public DB getClient() throws RemoteException;
}
我的RMI实现
public class RMIImplementation extends UnicastRemoteObject
implements RMIInterface {
private static String dbLocation = null;
private DB a;
public RMIImplementation() throws RemoteException{
}
public RMIImplementation(String dbLocation) throws RemoteException{
System.out.println(dbLocation);
this.dbLocation = dbLocation;
}
public static DB getRemote(String hostname, String port)
throws RemoteException {
String url = "rmi://" + hostname + ":" + port + "/DvdMediator";
try {
RMIInterface factory
= (RMIInterface) Naming.lookup(url);
// at this point factory equals Proxy[RMIInterface,................etc
// i want the return to equal Proxy[DB,..............etc
return (DB) factory.getClient();
} catch (NotBoundException e) {
throw new RemoteException("Dvd Mediator not registered: ", e);
}
catch (java.net.MalformedURLException e) {
throw new RemoteException("cannot connect to " + hostname, e);
}
}
public DB getClient() throws RemoteException {
try {
a = new ContractorDatabase(dbLocation);
}
catch(Exception e){
System.out.println("NewClass exception: " + e.toString());
}
return a;
}
我的名字在RMI注册处
public class RegDvdDatabase {
private RegDvdDatabase() {
}
public static void register()
throws RemoteException {
register(".", java.rmi.registry.Registry.REGISTRY_PORT);
}
public static void register(String dbLocation, int rmiPort)
throws RemoteException {
Registry r = java.rmi.registry.LocateRegistry.createRegistry(rmiPort);
r.rebind("DvdMediator", new RMIImplementation(dbLocation));
}
}
让这两个人一起工作会带来很大的麻烦
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to sjdproject.remote.RMIImplementation
你能帮我找到阻止它工作的数据库问题吗。你必须将它转换到远程接口
EDIT服务器代码中的注册表引用
r
必须是静态的。我看不出在实现类中定位客户机查找代码有什么好的理由。该类应该只存在于服务器上,而不存在于客户端。如果没有调试器,我建议对提供的对象使用反射,并查看它实现了哪些接口。它似乎是一个代理对象,因此必须实现一些接口
for(Class clazz : factory.getClass().getInterfaces()) {
System.out.println(clazz.getSimpleName());
}
我对多个部署的怀疑当然是jvm版本和类路径。您能验证它们是否匹配吗?我已经更新了代码。factory返回一个对象,factory.getClient()返回null,(DB)factory.getClient返回一个强制转换异常。这是不可能的。您可以将null强制转换为任何内容。请澄清。首先,您说您得到的对象在您强制转换时变为空。现在你说的正好相反。这两种说法都没有任何意义。请用你现在得到的实际异常以及引发它的当前代码更新你的帖子。是的,对不起。factory.getClient()和(DB)factory.getClient都返回null。我尝试了(DB)工厂,只是想看看会发生什么,这是一个cast异常。到目前为止,我的代码没有生成异常,只是一个空值。因此,您的实现方法返回
null。
因此您在getClient()中捕获了一个异常,
打印了该异常,并返回了null。
我在您的其他线程中预测的所有异常。这是一个接口设计错误和实现问题,更不用说您没有注意到服务器对象抛出异常。您需要重新设计该方法,以便将抛出的任何异常传播到客户端,或者重新编码客户端,以便它测试null。
Ok,很明显,您的意思是我的数据库接口有问题,或者我的数据库中接口的实现有问题。是不是我需要在我的数据库包的某个地方重新编码null的测试?当然它是一个代理对象。这是一个RMI动态存根。他试图将它强制转换到实现类(其实不然),而不是转换到远程接口(它实现了远程接口)。你给我的代码返回了远程和远程接口,所以我想这就是我想要的。我不太明白你所说的匹配jvm版本和类路径的意思。@ragingbull算了,你已经解决了这个问题。