2

何をしても、Serwerクラスの新しいインスタンスを作成できません。助けてください、どういうわけかコンストラクタは見えません。なぜそうなのかわかりません。コンストラクターはパブリックであり、すべてが1つのファイルにコード化されています。

私はこれを手に入れました:

java.rmi.StubNotFoundException: Stub class not found: Serwer_Stub; nested exception is: 
java.lang.ClassNotFoundException: Serwer_Stub
at sun.rmi.server.Util.createStub(Unknown Source)
at sun.rmi.server.Util.createProxy(Unknown Source)
at sun.rmi.server.UnicastServerRef.exportObject(Unknown Source)
at java.rmi.server.UnicastRemoteObject.exportObject(Unknown Source)
at java.rmi.server.UnicastRemoteObject.exportObject(Unknown Source)
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.exportObject(Unknown Source)
at javax.rmi.PortableRemoteObject.exportObject(Unknown Source)
at javax.rmi.PortableRemoteObject.<init>(Unknown Source)
at Serwer.<init>(Serwer.java:13)
at Serwer.main(Serwer.java:35)
Caused by: java.lang.ClassNotFoundException: Serwer_Stub
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
... 10 more

クラス

import java.rmi.RemoteException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.rmi.PortableRemoteObject;

public class Serwer extends PortableRemoteObject implements MyInterface {



public Serwer() throws RemoteException {
    super();
    try{
        Serwer ref =
                new Serwer();
        Context ctx = new InitialContext();
        ctx.rebind("myinterfaceimplementacja", ref);

    }catch(Exception e){e.printStackTrace();}
}

@Override
public String echo(String napis) throws RemoteException {
    return "echo" + napis;
}

@Override
public int dodaj(int wrt1, int wrt2) throws RemoteException {
    return wrt1 + wrt2;
}

public static void main(String[] args){
    try {
        new Serwer();
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}
4

1 に答える 1

2

コードには2つのバグがあります。1つ目は、コンストラクターでの明らかな無限再帰Serwerです。ここでは、コンストラクターを何度も呼び出しています。これは、コンストラクターからその行を削除し、次の行で置き換えることで修正できrefますthis

public class Serwer extends PortableRemoteObject implements MyInterface {

    public Serwer() throws RemoteException {
        super();
    }

    @Override
    public String echo(String napis) throws RemoteException {
        return "echo" + napis;
    }

    @Override
    public int dodaj(int wrt1, int wrt2) throws RemoteException {
        return wrt1 + wrt2;
    }

    public static void main(String[] args){
        try {
            Serwer ref = new Serwer();
            // Context ctx = new InitialContext();
            // ctx.rebind("myinterfaceimplementacja", ref);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

ただし、このバグはあなたが得たものとは無関係ClassNotFoundExceptionです。例外の原因はPortableRemoteObject、リモート実装の基本クラスとして使用することです。通常、Java RMIでは、Serwer_Stubリモートオブジェクトをエクスポート(インスタンス化)すると、スタブクラス()が自動的に生成されます。ただし、PortableRemoteObjectこれは例外です。これは2つの方法で解決できます。

  1. Kumarが提案したように、をに置き換えjavax.rmi.PortableRemoteObjectますjava.rmi.server.UnicastRemoteObject。このようにして、スタブオブジェクトが自動的に作成され、上記のコードが正常に実行されるので、テストしました。

    public class Serwer extends UnicastRemoteObject implements MyInterface {
    
  2. 何らかの理由でを使用する必要がある場合は、JDKに付属PortableRemoteObjectのRMIコンパイラ()ツールを使用してスタブクラスを手動で生成する必要があります。rmic

    まず、Serwerクラスをコンパイルします。

    javac Serwer.java
    

    これにより、ファイルが生成されSerwer.classます。次に、RMICツールを呼び出してスタブクラスを生成します。

    rmic Serwer
    

    これにより、ファイルが生成されSerwer_Stub.classます。これで、サーバーを実行できます。

    java Serwer
    

    私もこれをテストしました、それは例外なく始まります。

Javaネーミングの使用に伴うコードに別のバグがあり、別の例外(NoInitialContextException)が発生することに注意してください。ただし、これも質問とは関係がないため、上記のコードでコメントアウトしました。私は専門家ではないのでjavax.naming、それを手伝ってくれるのは他の誰か次第です。

誤ってネーミングを使用する代わりに、RMIレジストリを使用するつもりだったのかもしれません。RMIレジストリは、JavaRMIでリモートオブジェクトをバインドおよびルックアップするためのネイティブな方法です。この場合、交換する必要があります

Context ctx = new InitialContext();
ctx.rebind("myinterfaceimplementacja", ref);

適切なRMIレジストリコードの行:

Registry reg = LocateRegistry.createRegistry(1099);
reg.rebind("myinterfaceimplementacja", ref);

これにより、標準ポート(1099)にRMIレジストリが作成されます。プログラムを実行すると、レジストリが作成され、リモートオブジェクトがエクスポートされ、指定された名前で登録されます。

他の方法は書くことです

Registry reg = LocateRegistry.getRegistry();

これにより、プログラムはすでに実行されている既存のレジストリを見つけることができます。remiregistryJDKの一部でもあるツールを呼び出して、プログラムを実行する前にRMIレジストリを開始する必要があります。

rmiregistry

これで、コンパイルしてプログラムを開始できます。

javac Serwer.java
java Serwer

リモートオブジェクトの実装が開始されてレジストリに登録され、クライアントが検索できるようになります。

于 2012-05-18T07:42:11.647 に答える