我正在开发一个客户端服务器应用程序,其中我将.class文件从一个jvm复制到另一个jvm。我需要使用反射在第二台机器(此机器不包含其.java文件)中使用此.class文件创建实例,但我收到以下错误。此外,我的项目包括各种包 - 一个用于服务器,另一个用于客户端。在使用反射时,我尝试只提供类名(复制类),这让我想知道这是否是一个问题。类路径是否存在问题或者是否提供完全限定的类名或其他内容?
java Server/remoteServer
Exception in thread "main" java.lang.NoClassDefFoundError: Server/Registry_stub (wrong name: registry/Registry_stub)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at generics.Naming.bind(Naming.java:34)
at Server.remoteServer.main(remoteServer.java:17)
这是我遇到问题的方法:
public static void bind(String name, myRemoteInterface obj) throws AlreadyBoundException, RemoteException, IOException {
RegistryInterface stub = null;
try{
stub = (RegistryInterface)Class.forName("Server.Registry_stub").newInstance();
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException e) {
e.printStackTrace();
}
stub.bind(name, obj);
}
在另一台机器上编译的Registry_stub和.class文件被复制到调用绑定函数的客户机上(在名为Server的包中)。我的目标是调用Registry_stub类中定义的绑定方法,我在客户端中拥有.class。
感谢您的帮助
答案 0 :(得分:0)
加载类时,总是使用一些类加载器。在您的情况下,我将使用一个新的类加载器,可以访问复制的.class文件,并确保在尝试加载类时使用该类加载器。
要获得更详细的帮助,您必须提供更多上下文。只有您提供的堆栈跟踪很难以更具体的方式帮助您。
答案 1 :(得分:0)
由于您没有发布任何代码,我不确定这是否真的是您的问题,但现在就可以了。
有关包的信息也写在类文件中。我的假设基于这样一个事实,即有一个返回包的反射方法getPackage()
。实施例
System.out.println(String.class.getPackage().getName());
将打印java.laang
。
为了能够加载发送类,你必须使用它的完整包名,换句话说Class.forName("foo.bar.YourClass")
,类ClassLoader将尝试在代表包的目录中搜索YourClass.class
文件,这样这个结构必须放在里面([...]
表示目录)
[foo]
|
+-[bar]
|
+-YourClass.class
结构(foo
目录必须放在classpath中指定的目录中)。
因此,在项目中为这样的包结构创建一些目录,并将其添加到类路径中。另外,请不要忘记发送文件名,而是发送完整包名。