首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

EJB 客戶端 JNDI 查找 Home 接口完全指南

     編輯:Java 相關知識

痛點:本地跑通,遠程掛掉

同一份客戶端代碼,在應用服務器本地運行完美;部署到獨立客戶機卻拋出 NoClassDefFoundError、NamingException、ClassCastException。根因在於:本地環境自動注入 JNDI 屬性、Stub/Tie 類、安全上下文;遠程環境一切靠手工配置。

核心概念速查

術語比喻技術含義
命名空間城鎮EJB Home 發布的邏輯容器
上下文城鎮位置命名空間中的某個節點
初始上下文進城大道客戶端連接命名服務的入口
子上下文街道名從初始上下文到目標的相對路徑
Home 接口店鋪招牌定義 create/find 方法,JNDI 發布點
Remote 接口店員技能業務方法集合,create() 後獲得
JNDI城鎮模板統一命名/目錄訪問 API
CosNaming/LDAP具體城鎮JNDI 兩大服務提供者實現

三種屬性配置方式(優先級遞增)

  1. jndi.properties(類路徑首個)
  2. JVM 參數 -Djava.naming.factory.initial=... -Djava.naming.provider.url=...
  3. 代碼中 new InitialContext(props) 顯式傳遞

最佳實踐:採用方式 3,將屬性外部化到配置文件/命令行,避免硬編碼,支援多環境部署。

CosNaming 實戰

啟動命名服務

# JDK 自帶
tnameserv -ORBInitialPort 900  # Windows: tnameserv.exe

發布測試對象

Properties props = new Properties();
props.put("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");
props.put("java.naming.provider.url", "iiop://localhost:900");
InitialContext ic = new InitialContext(props);
ic.createSubcontext("Test");  // 驗證命名空間可寫

查找 EJB Home

String lookupName = "ejb/HelloWorldHome";  // 相對初始上下文路徑
Object ref = ic.lookup(lookupName);
HelloWorldHome home = (HelloWorldHome) PortableRemoteObject.narrow(ref, HelloWorldHome.class);
HelloWorld ejb = home.create();
ejb.hello();

關鍵:lookupName 必須與部署工具綁定的 JNDI 名一致。WebSphere 預設綁定在 ejb/ 子上下文,若用非 WebSphere 初始上下文工廠,需傳完整路徑 ejb/HelloWorldHome。

LDAP 實戰

路徑語法差異

  • CosNaming:/ 分隔,如 ejb/HelloWorldHome
  • LDAP:, 分隔,且須反序:cn=HelloWorldHome,cn=MyServer,o=myldap

連接屬性

props.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
props.put("java.naming.provider.url", "ldap://localhost:1389/o=myldap");  // BaseDN 在 URL 中
// 查找名:反序 DN
ic.lookup("cn=HelloWorldHome,cn=MyServer");

WebSphere / WebLogic 產品級配置對照

項目WebLogicWebSphere
InitialContextFactoryweblogic.jndi.WLInitialContextFactorycom.ibm.websphere.naming.WsnInitialContextFactory
Provider URLt3://host:7001iiop://host:2809
UserTransaction JNDIjavax.transaction.UserTransactionjta/usertransaction
客戶端 JDK任意 JDK必須 IBM JDK(IIOP Stub 依賴)

四大生存法則

  1. Stub/Tie 全備:下一階段所需類必須在類路徑,否則 narrow 失敗
  2. 通用 JAR 必帶:j2ee.jar 等每階段必備
  3. 屬性外部化:工廠類、URL、查找名作參數傳遞,支援多環境
  4. 知曉起點:用 JNDI 瀏覽器查看命名空間,確認初始上下文位置與目標相對路徑

進階:通用查找助手類

public class EJBLookupHelper {
    public static Object lookup(String factory, String url, String name) throws Exception {
        Properties p = new Properties();
        p.put(Context.INITIAL_CONTEXT_FACTORY, factory);
        p.put(Context.PROVIDER_URL, url);
        return new InitialContext(p).lookup(name);
    }
}
// 使用
Object ref = EJBLookupHelper.lookup(
    "com.ibm.websphere.naming.WsnInitialContextFactory",
    "iiop://was-host:2809",
    "ejb/MyEJBHome");
MyHome home = (MyHome) PortableRemoteObject.narrow(ref, MyHome.class);

結語

JNDI 查找看似枯燥,實則是分佈式 Java 應用的「導航系統」。掌握命名空間拓撲、初始上下文語義、Stub/Tie 部署、產品差異四大維度,才能從「本地跑通」走向「生產穩健」。下次遇到 NameNotFoundException,請先打開 JNDI 瀏覽器——真相往往在樹結構裡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved