好吧,我相信这应该很容易,但我对Java相当陌生(我更像是一个.NET男孩:p),在遵循了我在这里发现的每一个建议都没有成功之后,我想是时候退一步问了。
我试图用一个客户端、一个服务器和一个定义了公共接口的公共项目来启动一个简单的rmi项目。我刚刚实现了我的服务器代码,当我试图运行它来检查是否一切正常时,我会被java.lang.ClassNotFoundException.击中
在对类似的问题给出了几个答案之后,我确信我的问题来自于在与我的项目不同的位置运行的rmiregistry。
我使用以下代码来设置注册表代码库:
public class Utils {
public static final String CODEBASE = "java.rmi.server.codebase";
public static void setCodeBase(Class<?> c) {
String ruta = c.getProtectionDomain().getCodeSource().getLocation().toString();
String path = System.getProperty(CODEBASE);
if (path != null && !path.isEmpty()) {
ruta = path + " " + ruta;
}
System.setProperty(CODEBASE, ruta);
}
}
然后,我尝试用这个主要类启动我的服务器代码:
public class MainRegulador {
public static void main(String[] args) throws AccessException, RemoteException, NotBoundException {
Utils.setCodeBase(IRegulador.class);
Registry registro = null;
Remote proxy = null;
try {
Regulador myReg = new Regulador();
proxy = UnicastRemoteObject.exportObject(myReg, 36510);
registro = LocateRegistry.getRegistry();
registro.rebind("Distribuidor", proxy); //this is the line where exception is thrown
System.out.println("El Regulador está corriendo. Pulse ENTER para finalizar el proceso.");
System.in.read();
} catch(Exception ex) {
System.out.println("No se ha logrado inicializar el Registrador");
System.out.println(ex.getMessage());
} finally {
if (registro != null && proxy != null) {
registro.unbind("Distribuidor");
UnicastRemoteObject.unexportObject(proxy, true);
}
}
}
}
但当我运行它时,总是在IRegulador接口上得到java.lang.ClassNotFoundException。
现在有趣的部分:
- 我已经打印到控制台java.rmi.server.coreduct值,它指向定义IRegulador接口的项目的bin文件夹。(文件:/F:/Practicas%20y%20dem%c3%a1s/Sistemas%20Distribidos/common/bin/)
- 显然,该项目也设置在服务器项目的类路径中(Regulador)
- Workspace和rmiregistry位于不同的磁盘上
- 尽管如此,它似乎并不是全局类路径问题,因为Utils类与IRegulador接口在同一个项目上,并且它在抛出异常之前运行(因为java.rmi.server.coreduct设置正确)
在调用rmiregistry之前,我曾尝试设置它的类路径(尽管在某些答案中直接不鼓励这样做),但没有任何改变。我也尝试过从Regulador项目bin文件夹启动rmiregistry.exe,但似乎也没有改变任何东西。
来自。NET背景下,我总是发现这些类路径问题令人困惑,而这一问题开始消耗比我认为应该消耗的时间多得多的时间。我急需帮助。
更新:我开始认为问题出在它从IRegulador.class传递到代码库的url中。如果我将它粘贴到windows资源管理器中,SO无法定位它,所以我怀疑它是在构建时遇到了一些结构问题,阻止注册表到达路由:
文件:/F:/Practicas%20y%20dem%c3%a1s/Sistemas%20Distribidos/common/bin/
更新2:我觉得路径路线可能太复杂了,所以我决定简化它,去掉任何非直线字符。现在代码基值是
文件:/F:/Practicas/SD/common/bin/
但是问题仍然存在,我不知道为什么rmiregistry无法访问该文件夹。
然后我决定将整个项目移到执行rmiregistry的同一个磁盘上,看看它是否有任何变化。但一切都没有改变,同样的问题。
好的,我终于开始工作了。。。
我刚刚将rmiregistry.exe复制到common/bin文件夹中,并直接从那里启动它(以前只是从那里调用)。
这似乎解决了路由的问题(实际上,它使注册表可以使用路由,因为它在同一个文件夹中,可能我现在所有的代码库编写代码都非常出色)。