rmi java.lang.ClassNotFoundException:testrmi2.fileserverimpl_Stub

时间:2013-10-10 14:39:33

标签: java rmi

大家好我正在编写一个简单的rmi应用程序,但我遇到了问题。 如果我在同一目录中运行注册表,它的工作原理;但如果我改变我运行注册表的目录不会。 我认为这种情况不可能发生。 注册表通常会从另一台主机上运行,​​但只有目录的更改才会停止其功能。 我正在解决这个问题3天没有解决方案,我也改变了codebase参数的每个可能的配置,但没有。 我用目录描述了情况和代码:

fileserver.java:

`package testrmi2;
import java.rmi.*;

public interface fileserver extends Remote  {
 public void scrivifile(String nomefile, String arg) throws  RemoteException;
}

` fileserverimpl.java:

    package testrmi2;

import java.io.*;
import java.rmi.*;
import java.rmi.server.*;

public class fileserverimpl extends UnicastRemoteObject implements fileserver{
  public fileserverimpl() throws RemoteException {
    super();
  }
  public void scrivifile(String nomefile, String arg) throws RemoteException {
    try {
      FileWriter myfile = new FileWriter(nomefile);
      myfile.write(arg);
      myfile.close(); }
    catch (Exception e) {System.out.println(e);}
  }
  public static void main (String arg[]) {
    try {
       fileserverimpl s = new fileserverimpl();
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
        }
        String codebase = System.getProperty("classpath");
        System.out.println("Trying to access code base: " + codebase+"\n\nuse is "+System.getProperty("useCodebaseOnly"));
       Naming.rebind("//127.0.0.1:2005/fileserverimpl", s);
       System.out.println("Server attivato.");
} catch (Exception e) {System.out.println("errore inizializzazione server\n\n"+e.getMessage()+"\n\n\n");

}}}

client.java:

    package testrmi2;

import java.rmi.*;
import java.io.*;

public class client {
  public static void main (String arg[]) {
    fileserver myserver;
    String nomefile=" ";
    String testo=" ";
    System.out.println("Scrivi il nome del file");
    nomefile=ReadString();
    System.out.println("Scrivi il testo");
    testo=ReadString();
    try {
       myserver = (fileserver)   Naming.lookup("//127.0.0.1:2005/fileserverimpl");
        myserver.scrivifile(nomefile, testo);
      } catch (Exception e) {System.out.println(e);}
    }

   public static String ReadString() {
      BufferedReader stdIn =new BufferedReader(new InputStreamReader(System.in));
      String s=" ";
     try{
       s=stdIn.readLine();
      }
       catch(IOException e) {System.out.println(e.getMessage()); }
    return s;
   }
}

,政策文件是:

grant {
        // Allow everything for now
        permission java.security.AllPermission;
}; 

所有这些文件都在目录中:

/用户/弗朗/桌面/ PROVA

编译它我进入/ Users / franco / Desktop / prova目录并在终端进行:

javac -cp . -d . *.java
rmic rmic testrmi2.fileserverimpl
jar cvf testrmi2.jar testrmi2/fileserver.class testrmi2/fileserverimpl_Stub.class

我使用以下命令在另一个终端中运行注册表但在另一个目录中:

export classpath=""
rmiregistry 2005 &

最后我要运行filesereveimpl.class与/ Users / franco / Desktop / prova目录中的终端一起运行并写:

java -classpath /Users/franco/Desktop/prova/ -Djava.rmi.server.codebase=file:/Users/franco/Desktop/prova/testrmi2.jar  -Djava.security.policy=testrmi2/policy testrmi2.fileserverimpl &

但结果是:

    Trying to access code base: null

use is null
errore inizializzazione server

RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: testrmi2.fileserverimpl_Stub

我也尝试在本地网络服务器xampp上公开他的jar并尝试运行以下内容:

java -classpath .  -Djava.rmi.server.codebase=http://127.0.0.1/testrmi2/  -Djava.security.policy=testrmi2/policy  testrmi2.fileserverimpl &

或与:

java -classpath .  -Djava.rmi.server.codebase=http://127.0.0.1/testrmi2.jar  -Djava.security.policy=testrmi2/policy  testrmi2.fileserverimpl &

但我的结果相同。

请帮帮我!!!我疯了!!!

2 个答案:

答案 0 :(得分:1)

尝试在执行rmregistry之前设置classpath var:

export classpath="/Users/franco/Desktop/prova/"
rmiregistry 2005 &

答案 1 :(得分:1)

有三种情况。

  1. 导出/构建远程对象时,服务器中出现异常。解决方案:运行 rmic 以生成存根。
  2. 绑定/重新绑定时,您在服务器中获得了它。解决方案:使存根类可用于Registry的CLASSPATH,或通过LocateRegistry.createRegistry()在服务器JVM中运行注册表。
  3. 你在客户端,在lookup()中得到它。解决方案:使存根类可用于客户端的CLASSPATH。
  4. 这些也适用于远程接口本身及其依赖的任何应用程序类,等等,直到关闭为止。

    对所有三个存根的解决方案:采用Javadoc前言中概述的措施到UnicastRemoteObject,因此根本不需要存根。