2011-04-26 17 views
0

私はこれを解決しようとして約5時間を費やしましたが、無駄です。私はRMIを使用するアプリケーションを作成しました。それはうまくコンパイルされますが、実行することはできません。 私のすべてのクラスファイルは、C:\ Users \ Benji \ Desktop \ ass2 \ build(「割り当て」の略で、汚れていない)にあります。すべてのソースファイルはC:\ Users \ Benji \ Desktop \ ass2 \ srcにあります。 私は物事をより分かりやすくするために、すべてを1つのパッケージに入れました(これを反映するようにソース内のimport文を変更しました)。RMI - 実行時にClassNotFoundExceptionを取得する

バッチファイルをC:\ Users \ Benji \ Desktop \ ass2 \に配置しました。その文には実行文が含まれています。

java -classpath ./build -Djava.rmi.server.codebase=file:/C:/Users/Benji/Desktop/ass2/build -Djava.security.policy=broker.policy BrokerReception Broker 16890 

( "broker"と "16890"という2つの引数がプログラムで必要です)。

ファイルbroker.policyもC:\ Users \ Benji \ Desktop \ ass2 \にあります。その内容は以下のとおりです。

grant 
{ 
    permission java.security.AllPermission; 
}; 

(はい、私はこれは良いセキュリティポリシーではありません実現し、私はこの以降で動作します。)。

実際には3つのメインクラスがあります.1つはクライアント用、もう1つはブローカ用(クライアント用のメディエーター用)と1つのサーバー用です。私はブローカーを始めようとしています。次のようにブローカー・インタフェースのためのコードは次のとおりです。

import java.io.FileNotFoundException; 
import java.rmi.Remote; 
import java.rmi.RemoteException; 
import java.util.ArrayList; 

public interface Broker extends Remote 
{ 
    public boolean getAvailability(int startDate, int endDate) throws FileNotFoundException, RemoteException; 

    public ArrayList<CityInfo> getCities() throws FileNotFoundException, RemoteException; 

    public ArrayList<HotelInfo> getCityHotels(int cityNumber) throws FileNotFoundException, RemoteException; 

    public int getHotelRoomRate(int hotelNumber) throws FileNotFoundException, RemoteException; 

    public boolean makeBooking(String firstName, String lastName, String contact, String creditCardNo) throws FileNotFoundException, RemoteException; 
} 

と実装クラス:

import java.io.FileNotFoundException; 
import java.util.ArrayList; 

public class BrokerClientLiaison implements Broker 
{ 
    private BrokerDatabase directory; 
    private BrokerHotelsLiaison liaison; 

    public BrokerClientLiaison(BrokerDatabase directory, int activeHotelNumber) 
    { 
     this.liaison = new BrokerHotelsLiaison(activeHotelNumber); 
     this.directory = directory; 
    } 

    public boolean getAvailability(int startDate, int endDate) throws FileNotFoundException 
    { 
     return liaison.getAvailability(startDate, endDate); 
    } 

    public ArrayList<CityInfo> getCities() throws FileNotFoundException 
    { 
     return directory.getCities(); 
    } 

    public ArrayList<HotelInfo> getCityHotels(int cityNumber) throws FileNotFoundException 
    { 
     return directory.getCityHotels(cityNumber); 
    } 

    public int getHotelRoomRate(int hotelNumber) throws FileNotFoundException 
    { 
     return liaison.getHotelRoomRate(hotelNumber); 
    } 

    public boolean makeBooking(String firstName, String lastName, String contact, String creditCardNo) throws FileNotFoundException 
    { 
     return liaison.makeBooking(firstName, lastName, contact, creditCardNo); 
    } 
} 

と実装クラスを開始する最後に、メインクラス:

import java.io.FileNotFoundException; 
import java.rmi.RemoteException; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 
import java.rmi.server.UnicastRemoteObject; 
import java.sql.SQLException; 

public class BrokerReception 
{ 
    public static void main(String[] args) 
    { 
     System.out.println("Args are:"); 
     for(String arg : args) 
     { 
      System.out.println(arg); 
     } 
     System.out.println(); 

     try 
     { 
      BrokerDatabase directory = new BrokerDatabase(); 
      directory.connect(args[0]); 

      int activeHotelNumber = Integer.parseInt(args[1]); 
      if(directory.checkActiveHotelExists(activeHotelNumber)) 
      { 
       BrokerClientLiaison liaison = new BrokerClientLiaison(directory, activeHotelNumber); 
       Broker liaisonStub = (Broker) UnicastRemoteObject.exportObject(liaison, 0); 
       Registry registry = LocateRegistry.getRegistry(); 
       registry.rebind(Protocol.BROKER_INTERFACE_NAME, liaisonStub); 
      } 
      else 
      { 
       throw new FileNotFoundException(); 
      } 
     } 
     catch(ArrayIndexOutOfBoundsException aioobe) 
     { 
      System.err.println("Args required:"); 
      System.err.println("1. Name of database file"); 
      System.err.println("2. Number of active hotel"); 
      System.exit(1); 
     } 
     catch(ClassNotFoundException cnfe) 
     { 
      System.err.println("Couldn't load database driver"); 
      System.exit(2); 
     } 
     catch(SQLException sqle) 
     { 
      System.err.println("Couldn't establish connection to database"); 
      System.err.println("Check that the database has been properly registerd,"); 
      System.err.println("and that you provided the correct name"); 
      System.exit(3); 
     } 
     catch(NumberFormatException nfe) 
     { 
      System.err.println("Second argument must be an integer"); 
      System.exit(4); 
     } 
     catch(FileNotFoundException fnfe) 
     { 
      System.err.println("The database contains no entries with that hotel number"); 
      System.exit(5); 
     } 
     catch(RemoteException re) 
     { 
      System.err.println("Unable to bind as " + Protocol.BROKER_INTERFACE_NAME); 
      re.printStackTrace(); 
      System.exit(6); 
     } 
    } 
} 

"ディレクトリ"上記のコードでは、データベースにアクセスするクラスです。

私は他にどのような情報が必要かわかりません。誰かが私が間違っていることを教えてもらえますか? ちなみに、私は戻って、http://download.oracle.com/javase/1.5.0/docs/guide/rmi/hello/hello-world.htmlでOracleのRMIチュートリアルを実行して、何が間違っているのか理解できるかどうかを確認しました。このチュートリアルでは、コードベースやセキュリティポリシーについて言及していませんが、すべてのコードとコンパイルと実行のための正確な指示を提供します。私は手紙にこれらの指示に従ったが、それでもうまくいきませんでした!

スタックトレース:

java.rmi.ServerException: RemoteException occurred in server thread; nested exce 
ption is: 
     java.rmi.UnmarshalException: error unmarshalling arguments; nested excep 
tion is: 
     java.lang.ClassNotFoundException: Broker 
     at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:396 
) 
     at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250) 
     at sun.rmi.transport.Transport$1.run(Transport.java:159) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at sun.rmi.transport.Transport.serviceCall(Transport.java:155) 
     at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:5 
35) 
     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTranspor 
t.java:790) 
     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport 
.java:649) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec 
utor.java:886) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor 
.java:908) 
     at java.lang.Thread.run(Thread.java:662) 
     at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Stream 
RemoteCall.java:255) 
     at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java: 
233) 
     at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359) 
     at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) 
     at BrokerReception.main(BrokerReception.java:32) 
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested ex 
ception is: 
     java.lang.ClassNotFoundException: Broker 
     at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) 
     at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:386 
) 
     at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250) 
     at sun.rmi.transport.Transport$1.run(Transport.java:159) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at sun.rmi.transport.Transport.serviceCall(Transport.java:155) 
     at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:5 
35) 
     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTranspor 
t.java:790) 
     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport 
.java:649) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec 
utor.java:886) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor 
.java:908) 
     at java.lang.Thread.run(Thread.java:662) 
Caused by: java.lang.ClassNotFoundException: Broker 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:202) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:307) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:248) 
     at java.lang.Class.forName0(Native Method) 
     at java.lang.Class.forName(Class.java:247) 
     at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:7 
11) 
     at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:655) 
     at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:592) 
     at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:6 
28) 
     at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294 
) 
     at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStrea 
m.java:238) 
     at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1530) 
     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1492) 
     at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1 
731) 
     at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) 
     ... 12 more 
+3

stacktraceが役に立ちます - どのクラスも見つかりません。 try..catchハンドラで 'cnfe'から実際のクラス名をキャッチしてみてください。多分、データベースドライバクラスではありません... –

+0

...また、取得したときに何をしていますか? 3つの異なる場合があります。 – EJP

+0

申し訳ありません、スタックトレースを忘れました。私は数日を離れていた:/。見つからないクラスは、ブローカインタフェースのように見えます。 また、最も奇妙なこと:私は、http://download.oracleにある第2のチュートリアルを行っています。com/javase/tutorial/rmi/index.htmlを参照してください。 – Swiftslide

答えて

1

あなたは第二の方法として、あなたのレジストリを実行している場合、それはあなたのリモートクラスへのアクセスを必要とします。これを行う最も簡単な方法は、レジストリを起動するときに適切なクラスパス引数をコマンドラインに追加することです。

リモートクラスロードを使用しようとしている場合は、コマンドラインまたはメインメソッドのいずれかでアプリケーションにrmiセキュリティマネージャを設定する必要があると思います。 (個人的には、クラスを配布するのは通常、状況の99%で動作し、100倍も簡単に取得できます)。

関連する問題