J2EE 1.2.1 SDK (2000 年發布) 是早期企業級 Java 開發標準參考實現,包含 EJB 容器、Servlet/JSP 容器、JMS、JNDI、RMI-IIOP 等完整服務。本文記錄 Windows 2000 環境下的安裝、環境變量、啟動驗證、Deployment Tool 圖形化部署、Converter 無狀態 Session Bean 完整範例構建與客戶端調用全流程,**僅供歷史技術考古與存量系統維護參考**。
| 組件 | 版本/來源 | 安裝路徑建議 |
|---|---|---|
| OS | Windows 2000 Server / NT 4.0 SP6+ | - |
| JDK | 1.2.2 / 1.3.1 (必須先裝) | C:\JDK |
| J2EE SDK | j2sdkee-1_2_1-win.exe | C:\J2EE (非預設 C:\j2sdkee1.2.1,便於配置) |
| 文檔 | j2sdkee-1_2_1-doc-win.exe | C:\J2EE\DOC |
JAVA_HOME=C:\JDK
J2EE_HOME=C:\J2EE
CLASSPATH=.;%J2EE_HOME%\lib\j2ee.jar
重新打開 CMD 生效。
C:\J2EE\binj2ee -verboseJ2EE server Listen Port: 1049 # RMI/Naming
Naming service started: 1050
Web service started: 9191 # HTTPS?
Web service started: 8000 # HTTP 默認
Web service started: 7000 # 管理/其他
J2EE server startup complete.
https://localhost:8000 見默認首頁即成功建立目錄 C:\MYEJB\converter\ 存放源碼:
package converter;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Converter extends EJBObject {
double dollarToYen(double dollars) throws RemoteException;
double yenToEuro(double yen) throws RemoteException;
}
package converter;
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface ConverterHome extends EJBHome {
Converter create() throws RemoteException, CreateException;
}
package converter;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class ConverterEJB implements SessionBean {
public double dollarToYen(double dollars) { return dollars * 121.6000; }
public double yenToEuro(double yen) { return yen * 0.0077; }
// SessionBean 生命週期方法 (空實現)
public void ejbCreate() {} public void ejbRemove() {}
public void ejbActivate() {} public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
}
package converter;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
public class ConverterClient {
public static void main(String[] args) {
try {
Context initial = new InitialContext();
Object objref = initial.lookup("MyConverter"); // JNDI 名稱
ConverterHome home = (ConverterHome) PortableRemoteObject.narrow(objref, ConverterHome.class);
Converter currencyConverter = home.create();
System.out.println(currencyConverter.dollarToYen(100.00)); // 12160.0
System.out.println(currencyConverter.yenToEuro(100.00)); // 0.77
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
C:\MYEJB\converter> javac *.java
# 產生 Converter.class, ConverterHome.class, ConverterEJB.class, ConverterClient.class
C:\J2EE\bin\deploytool 啟動 GUIFile → New Application → Application File Name: C:\MYEJB\converter\test.ear, Display Name: testFile → New Enterprise Bean → 選擇 C:\MYEJB\converter 為根目錄 → 添加三個 .class (ConverterEJB, ConverterHome, Converter) → NextConverterEJB, Home: ConverterHome, Remote: Converter, Display Name: MyTest, Type: Stateless SessionTools → Deploy Application → 勾選 Return Client Jar → JNDI Name: MyConverter (必須與 Client lookup 一致) → Deploy → 完成部署成功產生 testClient.jar (含 Client 存根)。
C:\MYEJB\converter> java -classpath C:\J2EE\lib\j2ee.jar;.;testClient.jar converter.ConverterClient
# 輸出:
12160.0
0.77
| 端口 | 服務 | 協議 |
|---|---|---|
| 1049 | J2EE Server (RMI/JRMP) | RMI/IIOP |
| 1050 | Naming Service (CosNaming) | IIOP |
| 8000 | Web Container (HTTP) | HTTP/1.1 |
| 7000 | Admin/Management | HTTP/RMI |
| 9191 | Secure Web (HTTPS) | HTTPS |
ClassNotFoundException:CLASSPATH 缺 j2ee.jar 或當前目錄 .NameNotFoundException: MyConverter:JNDI 名稱拼寫不一致、部署未勾選 Return Client JarNoClassDefFoundError: javax/ejb/...:Client 端未包含 j2ee.jar 或版本不匹配\:複製粘貼路徑時全半角混用,必須手工修正為標準 \J2EE 1.2.1 SDK 確立了「標準 API + 參考實現 + 部署描述符 + 圖形化工具」的企業級 Java 開發範式。雖技術棧已歷經 EJB 2.x → 3.x → CDI/Spring → Jakarta EE 多代演進,但 **JNDI 查找、Home/Remote 接口、Session Bean 生命週期、部署單元 等核心概念在現代 Jakarta EE / Spring 中仍有映射**。理解這段歷史,有助於深度掌握當下框架的設計初衷。