java.rmi.ServerException:服务器线程中发生RemoteException

时间:2015-07-12 19:26:17

标签: java rmi

服务器:创建一个可以解决PuzzleUnsolved

的PuzzleSolved
package server; 

import java.rmi.*;
import java.rmi.server.*;
import common.Puzzle;
import server.puzzleObject.PuzzleSolved;
import java.net.MalformedURLException;

class PuzzleSolver {
    private static final String HOST = "localhost";

    public static void main(String args[]) {
        try {
            String serverName = args[0];

            Puzzle puzzle = new PuzzleSolved();
            String rmiObServer = "rmi://" + HOST + "/" + serverName;
            Naming.rebind(rmiObServer, puzzle);
            System.out.println("Server ready");
        }
        catch(ArrayIndexOutOfBoundsException ex) {
            System.out.println("Error! E' necessario specificare il nome del server");
        }
        catch(RemoteException r) {
            System.out.println("Error while rebind object");
            r.printStackTrace();
            System.exit(1);
        }
        catch(MalformedURLException m) {
            System.out.println("Error! Malformed url require");
        }
    }
}

客户端:创建一个PuzzleUnsolved然后需要看一个可解决的对象,然后使用PuzzleUnsolved运行求解

package client;

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

import client.puzzleIO.*;

import common.Solvable;
import common.Puzzle;
import common.PuzzleUnsolved;

class PuzzleSolver {
    private static final String HOST = "localhost";

    public static void main(String args[]) {
        PuzzleWriter writer = null;
        PuzzleReader reader = null;

        try {
            String inputFile = args[0], outputFile = args[1], serverName = args[2];
            writer = new PuzzleWriter();
            reader = new PuzzleReader();
            System.out.println("primo");
            PuzzleUnsolved unsolved = new PuzzleUnsolved();
            reader.read(unsolved, inputFile);
            writer.write(unsolved, outputFile, false);

            System.out.println("secondo");
            Solvable ref = (Solvable) Naming.lookup("rmi://" + HOST + "/" + serverName);
            ref.solve(unsolved);
            writer.write(ref, outputFile, true);
            System.out.println("fine");
        }
        catch(ArrayIndexOutOfBoundsException e) {
            if(args.length == 0)
                System.out.println("E' necessario specificare il file di input e di output");
            if(args.length == 1)
                System.out.println("File di output assente");
            if(args.length == 2)
                System.out.println("E' necessario specificare un nome per il server");
        }
        catch(ConnectException c) {
            System.out.println("Problema di connessione con il server");
        }
        catch(Exception e) {
            System.out.println("Si è verificato un problema nell'esecuzione");  
            e.printStackTrace();
        }
    }
}

拼图:抽象类

package common;

import java.rmi.*;
import java.rmi.server.*;
import java.util.ArrayList;
import java.io.Serializable;
import common.Solvable;
import common.PuzzleTile;
import common.PuzzleUnsolved;

public abstract class Puzzle extends UnicastRemoteObject implements Solvable{

    private int rows = 0, columns = 0;
    protected ArrayList<PuzzleTile> tiles = new ArrayList<PuzzleTile>();

    public Puzzle() throws RemoteException {
    }
    public int rows(){
        return rows;
    }
    public int columns(){
        return columns;
    }
    public void setColumns(int columns) {
        this.columns = columns;
    }
    public void setRows(int rows) {
        this.rows = rows;
    }
    public void addTile(PuzzleTile t) {
        tiles.add(t);
    }
    protected PuzzleTile tile(int row, int column) {
        return tiles.get(row * columns + column);
    }
    public ArrayList<PuzzleTile> tiles() {
        return tiles;
    }
    public abstract String toString();  
    public abstract void solve(PuzzleUnsolved puzzleToSolve)  throws RemoteException;
}

PuzzleUnsolved:解决了难题

package common;

import java.rmi.*;
import java.io.Serializable;
import common.Puzzle;
import common.Solvable;

public class PuzzleUnsolved extends Puzzle implements Serializable {

    public PuzzleUnsolved() throws RemoteException {
    }

    public String toString() {
        StringBuilder aux = new StringBuilder();
      for(int r = 0; r < this.rows(); ++r) {
          for(int c = 0; c < this.columns(); ++c) {
              aux.append(this.tile(r, c).character());
              aux.append(" ");
          }
      }
      aux.append(System.getProperty("line.separator"));
      return aux.toString();
    }
    public void solve(PuzzleUnsolved puzzleToSolve) {
    }
}

PuzzleSolved:解决的难题是解决了包含求解(...)方法的难题,成为一个解决的难题

package server.puzzleObject;

import java.rmi.*;
import java.rmi.server.*;
import java.util.ArrayList;
import java.io.Serializable;
import common.Puzzle;
import common.Solvable;
import common.PuzzleTile;
import common.PuzzleUnsolved;

public class PuzzleSolved extends Puzzle implements Solvable {
    private ArrayList<PuzzleTile> tilesOrdered = new ArrayList<PuzzleTile>();

    public PuzzleSolved() throws RemoteException {
    }
    public class PuzzleThread extends Thread {
        public int row;

        public PuzzleThread(int row) {
            this.row = row;
        }
        public void run() {
            for(int c = 0; c < columns(); ++c) {
                boolean notFound = true;
                for(int tile = 0; tile < tiles.size() && notFound; ++tile) {
                    if(tiles.get(tile).left().equals(tilesOrdered.get(row * columns() + c))) {
                        tilesOrdered.add(row * columns() + c, tiles.get(tile));
                        notFound = false;
                    }
                }
            }   
        }
    }
    public void solve(PuzzleUnsolved puzzle)  throws RemoteException {
        setColumns(puzzle.columns());
        setRows(puzzle.rows()); 
        tiles.addAll(puzzle.tiles());
        tilesOrdered.addAll(puzzle.tiles());

        solveFirstColumn();
        solveRemaining();
    }
    public void solveFirstColumn() {
        String top = "VUOTO";
        for(int r = 0; r < rows(); ++r) {
            boolean notFound = true;
            for(int tile = 0; tile < tiles.size() && notFound; ++tile) {
                if(tiles.get(tile).left().equals("VUOTO")) {
                    if(tiles.get(tile).top().equals(top)) {
                        tilesOrdered.set(r * columns(), tiles.get(tile));
                        top = tiles.get(tile).id();
                        notFound = false;
                    }
                }
            }
        }
    }
    public void solveRemaining() {
        for(int i = 0; i < rows(); ++i)
            new PuzzleThread(i).start();
    }
    public PuzzleTile tile(int row, int column) {
        return tilesOrdered.get(row * columns() + column);
    }
    public String toString() {
        StringBuilder aux = new StringBuilder();
        for(int r = 0; r < rows(); r++) {
          aux.append(System.getProperty("line.separator"));
          for(int c = 0; c < columns(); c++) {
              aux.append(tile(r, c).character());
              aux.append(" ");
          }
      }
      aux.append(System.getProperty("line.separator") + System.getProperty("line.separator"));
      aux.append(rows());
      aux.append(" ");
      aux.append(columns());
      return aux.toString();
    }
}

PuzzleTile:代表一个抽象拼图的瓷砖

package common;

import java.util.Arrays;
import java.io.Serializable;

public class PuzzleTile implements Serializable{
    String id, letter, top, right, bottom, left;

    public PuzzleTile(String id, String c, String t, String r, String b, String l) {
        this.id = id;
        letter = c;
        top = t;
        right = r;
        bottom = b;
        left = l;
    }
    public String id() {
        return id;
    }
    public String top() {
        return top;
    }
    public String right() {
        return right;
    }
    public String bottom() {
        return bottom;
    }
    public String left() {
        return left;
    }
    public String character() {
        return letter;
    }
}

可解决 - 用于投射客户端远程PuzzleSolved的接口

package common;

import java.rmi.*;
import common.Puzzle;
import common.PuzzleUnsolved;

public interface Solvable extends Remote {
        public void solve(PuzzleUnsolved puzzleToSolve) throws RemoteException;

}

当我尝试从客户端解决PuzzleUnsolved我得到这个堆栈错误:(

primo
secondo
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$254(TCPTransport.java:683)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$1/323034826.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at com.sun.proxy.$Proxy0.solve(Unknown Source)
at client.PuzzleSolver.main(PuzzleSolver.java:33)

1 个答案:

答案 0 :(得分:0)

远程接口与实际的远程方法不一致。您已经更改了远程方法的签名,而无需重建和重新部署整个系统。