首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

RMI 遠程調用:Server 與 Client 必須同一專案?Stub 機制深度解析

     編輯:程式設計綜合問答

初學 Java RMI 時常見困惑:Server 與 Client 是否必須放在同一個 Eclipse/MyEclipse 專案?為何 Client 查詢 Registry 時提示 IHello 找不到?本文從 Stub/Skeleton 架構、類別載入機制、部署最佳實務三個維度徹底釐清。

核心結論:不必同專案,但必須共享介面定義

RMI 設計初衷即為跨 JVM、跨機器、跨專案的遠程呼叫。Client 只需:

  1. 擁有遠程介面(IHello)的 .class 檔案
  2. 能連線到 Registry(預設 1099 埠)
  3. Classpath 包含 stub 類別(Java 1.5+ 動態生成,通常無需手動編譯)

為什麼 MyEclipse 提示「找不到 IHello」?

因為 Client 專案的 Build Path 沒有包含介面類別。編譯期需要知道 IHello 的方法簽名,才能生成呼叫 Stub 的程式碼。

三種共享介面的實務做法

Stub 流程圖解

Client 呼叫 Stub 方法
    ↓ 序列化參數 (Marshalling)
Client Stub → RMI Runtime → Network → Server Skeleton
    ↓ 反序列化參數 (Unmarshalling)
Server Skeleton 呼叫實際遠程物件實現
    ↓ 返回值序列化
Server Skeleton → Network → Client Stub
    ↓ 返回值反序列化
Client 拿到結果

關鍵點:Stub/Skeleton 只負責網路通訊與序列化,業務邏輯完全在 Server 端實現類。Client 從未載入實現類,只依賴介面。

常見坑與解法

  1. ClassNotFoundException: IHello → Client 缺介面 JAR,加入依賴即可。
  2. UnmarshalException → 參數/返回值未實作 Serializable,補上介面。
  3. ConnectException: Connection refused → Registry 未啟動、IP/埠錯誤、防火牆攔截。
  4. ClassCastException: $Proxy0 cannot be cast to IHello → Client 用錯 ClassLoader,確保介面類別由同一 ClassLoader 載入。

現代替代方案提示

新專案建議考慮:

  • gRPC:跨語言、HTTP/2、Protobuf、效能極佳
  • Spring Cloud / Dubbo:微服務生態完整、服務發現、負載均衡內建
  • REST + JSON:通用、防火牆友好、除錯容易

總結

RMI Server/Client 完全可以不同專案、不同機器。核心契約是共享遠程介面定義。採用獨立 API 模組 + Maven/Gradle 依賴管理,是工業級專案的標準做法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方式操作步驟優/缺點
獨立 Module/JAR(推薦)建立 rmi-api 模組,僅含介面與 DTO,Server/Client 皆依賴此 JAR✅ 解耦、版本管理清晰
⚠️ 需多模組建置
複製 .class / 源碼手動將介面檔複製到 Client 專案✅ 簡單快速
❌ 易版本不一致、維護惡夢
共用 Source FolderEclipse 中將介面放在共用 Source Folder,兩專案同時引用✅ 開發期方便
❌ 部署打包易出錯