2016-02-17 76 views
1

我剛剛開始學習RMI和JFrame,並且我一直被困在一個異常上。我正在寫一個客戶端/服務器交互,從雅虎的數據庫訪問股票信息。Java RMI異常錯誤

這裏是我的代碼:

package stockquote; 

public class StockQuote{ 

    public double currentPrice, priceChange, dailyLow, dailyHigh; 

    public StockQuote(double price, double change, double low, double high){ 
     currentPrice = price; 
     priceChange = change; 
     dailyLow = low; 
     dailyHigh = high; 
    } 

    public StockQuote(){ 
     currentPrice = 0; 
     priceChange = 0; 
     dailyLow = 0; 
     dailyHigh = 0; 
    } 
} 



package stockquote; 

import java.rmi.Remote; 
import java.rmi.RemoteException; 

public interface StockQuoteInterface extends Remote{ 
    public StockQuote getQuote(String symbol) throws RemoteException; 
} 



package stockquote; 

import java.rmi.*; 
import java.rmi.registry.*; 
import java.rmi.server.UnicastRemoteObject; 

import java.io.*; 
import java.util.Properties; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.net.URL; 
import java.net.URLConnection; 
import java.rmi.RemoteException; 
import java.util.*; 

public class StockQuoteServer implements StockQuoteInterface{ 

    public StockQuote getQuote(String symbol) throws RemoteException{ 

     StockQuote information = new StockQuote(); 

     try{ 
      URL url = new URL("http://download.finance.yahoo.com/d/quotes.csv?s=" + symbol + "&f=l1c1hg"); 
      URLConnection conn = url.openConnection(); 
      BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
      String quoteString = in.readLine(); 
      in.close(); 

      String[] data = quoteString.split(","); 

      information.currentPrice = Double.parseDouble(data[0]); 
      information.priceChange = Double.parseDouble(data[1]); 
      information.dailyHigh = Double.parseDouble(data[2]); 
      information.dailyLow = Double.parseDouble(data[3]); 

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

     return information; 
    } 

    public static void main(String[] args) throws Exception { 
     try { 
      StockQuoteServer obj = new StockQuoteServer(); 
      StockQuoteInterface stub = (StockQuoteInterface) UnicastRemoteObject.exportObject(obj, 0); 

      Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT); 

      registry.rebind("StockQuoteServer", stub); 
      System.err.println("StockQuote Server is running."); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

} 



package stockquote; 

import javax.swing.*; 

import java.awt.*; 
import java.awt.event.*; 
import java.rmi.*; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 
import java.util.*; 

public class StockQuoteClient extends JFrame implements ActionListener{ 
    private static final long serialVersionUID = 1L; 

    private static StockQuoteInterface stockQuote; 

    private JTextField symbolField = new JTextField(10); 
    private JTextField currentPriceField = new JTextField(10); 
    private JTextField priceChangeField = new JTextField(10); 
    private JTextField dailyHighField = new JTextField(10); 
    private JTextField dailyLowField = new JTextField(10); 
    private JButton lookup = new JButton("Lookup"); 

    public StockQuoteClient() throws RemoteException{ 

     try { 
      Registry registry = LocateRegistry.getRegistry("localhost"); 
      stockQuote = (StockQuoteInterface) registry.lookup("StockQuoteServer"); 

     } catch (Exception e) { 
      e.printStackTrace(); 
      System.exit(0); 
     } 

     this.setLayout(new GridLayout(0,1)); 
     JPanel symbolPanel = new JPanel(); 
     symbolPanel.add(new JLabel("Stock Symbol: ")); 
     symbolPanel.add(symbolField); 
     this.add(symbolPanel); 

     this.setLayout(new GridLayout(0,1)); 
     JPanel fieldsPanel = new JPanel(); 
     fieldsPanel.add(new JLabel("Current Price: ")); 
     fieldsPanel.add(currentPriceField); 
     fieldsPanel.add(new JLabel("Price Change: ")); 
     fieldsPanel.add(priceChangeField); 
     fieldsPanel.add(new JLabel("Daily High: ")); 
     fieldsPanel.add(dailyHighField); 
     fieldsPanel.add(new JLabel("Daily Low: ")); 
     fieldsPanel.add(dailyLowField); 
     this.add(fieldsPanel); 

     JPanel lookupButtonPanel = new JPanel(); 
     lookupButtonPanel.add(lookup); 
     this.add(lookupButtonPanel); 

     lookup.addActionListener(this); 

     this.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     this.setSize(240, 350); 
     this.setVisible(true); 

    } 

    public void actionPerformed(ActionEvent e){ 
     StockQuote quoteInfo = new StockQuote(); 

     Object source = e.getSource(); 

     try{ 
      if(source == lookup){ 
       String symbol = symbolField.getText().trim(); 
       quoteInfo = stockQuote.getQuote(symbol); 
       if(quoteInfo.currentPrice == 0.0){ 
        currentPriceField.setText("Error"); 
        priceChangeField.setText("Error"); 
        dailyHighField.setText("Error"); 
        dailyLowField.setText("Error"); 
       }else{ 
        currentPriceField.setText(Double.toString(quoteInfo.currentPrice)); 
        priceChangeField.setText(Double.toString(quoteInfo.priceChange)); 
        dailyHighField.setText(Double.toString(quoteInfo.dailyHigh)); 
        dailyLowField.setText(Double.toString(quoteInfo.dailyLow)); 
       } 
      } 
     }catch(RemoteException ex){ 
      ex.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) throws RemoteException{ 
     /*StockQuote ggg = new StockQuote(); 

     Scanner keyboard = new Scanner(System.in); 
     System.out.println("Enter a symbol: "); 
     String symbol = keyboard.nextLine(); 

     ggg = stockQuote.getQuote(symbol); 

     System.out.println(ggg.currentPrice);*/ 
     new StockQuoteClient(); 
    } 

} 

這裏是我收到的例外。

Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: stockquote.StockQuote 
at sun.rmi.server.UnicastRef.invoke(Unknown Source) 
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) 
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) 
at com.sun.proxy.$Proxy0.getQuote(Unknown Source) 
at stockquote.StockQuoteClient.main(StockQuoteClient.java:101) 
Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: stockquote.StockQuote 
at java.io.ObjectInputStream.readObject0(Unknown Source) 
at java.io.ObjectInputStream.readObject(Unknown Source) 
at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source) 
... 5 more 
Caused by: java.io.NotSerializableException: stockquote.StockQuote 
at java.io.ObjectOutputStream.writeObject0(Unknown Source) 
at java.io.ObjectOutputStream.writeObject(Unknown Source) 
at sun.rmi.server.UnicastRef.marshalValue(Unknown Source) 
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) 
at sun.rmi.transport.Transport$1.run(Unknown Source) 
at sun.rmi.transport.Transport$1.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at sun.rmi.transport.Transport.serviceCall(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

回答

1

在堆棧跟蹤報道的根本原因是

java.io.NotSerializableException:stockquote.StockQuote

顯然你有一個在對象命名爲stockquote.StockQuote類的一個實例您嘗試序列化的對象的圖形,但該類不可序列化。

從堆棧跟蹤的其他部分看來,序列化嘗試與嘗試調用遠程方法有關--RMI依賴於Java序列化將參數傳遞給遠程方法並從它們接收返回值。

當然,如果您希望能夠通過RMI傳遞或返回實例,那麼stockquote.StockQuote必須實現java.io.Serializable。然而,這可能或可能不足以實際序列化實例,具體取決於類的成員。

+0

非常感謝您的幫助,現在工作正常。我不知道爲什麼我沒有看到。 –

1

stacktrace準確告訴你錯誤是什麼。您需要製作StockQuote阻止Serializable,因爲RMI使用Java的序列化機制通過線路傳輸數據(例如方法參數和返回值)。

+0

非常感謝您的幫助,現在工作正常。我不知道爲什麼我沒有看到。 –