从.class文件创建实例时出现的问题

时间:2014-06-15 11:25:58

标签: java client-server

我正在开发一个客户端服务器应用程序,其中我将.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。

感谢您的帮助

2 个答案:

答案 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中指定的目录中)。

因此,在项目中为这样的包结构创建一些目录,并将其添加到类路径中。另外,请不要忘记发送文件名,而是发送完整包名。