# WebLogic 預設域應用目錄
mkdir -p user_projects/domains/mydomain/applications/web/WEB-INF/lib
# 最小 web.xml
cat > web/WEB-INF/web.xml << 'EOF'
EJB Test Web Module
EOF
// Helloworld.java (Remote Interface)
package com.diegoyun.ejb.slb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Helloworld extends EJBObject {
String getGreeting(String name) throws RemoteException;
}
// HelloworldBean.java (Bean Implementation)
package com.diegoyun.ejb.slb;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import java.rmi.RemoteException;
public class HelloworldBean implements SessionBean {
private SessionContext ctx;
public void setSessionContext(SessionContext ctx) { this.ctx = ctx; }
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public String getGreeting(String name) {
return "Hello, " + name;
}
}
<%@ page import="com.diegoyun.ejb.slb.Helloworld,
com.diegoyun.ejb.slb.HelloworldHome,
javax.ejb.*,
javax.naming.*,
javax.rmi.PortableRemoteObject,
java.rmi.RemoteException" %>
Stateless Session Bean 測試
<%
String name = request.getParameter("myname");
if (name != null && !name.trim().isEmpty()) {
Helloworld hello = null;
try {
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("ejb/session/HelloworldEJB");
HelloworldHome home = (HelloworldHome) PortableRemoteObject.narrow(objRef, HelloworldHome.class);
hello = home.create();
} catch (Exception ex) {
out.println("錯誤: " + ex.getMessage());
ex.printStackTrace();
}
if (hello != null) {
out.println("結果: " + hello.getGreeting(name) + "
");
}
}
%>
WebLogic `upload` 目錄特性:部署時指向此目錄 JAR,後續重新建置只需覆蓋此 JAR,無需重新部署即可生效 (類似 JBoss 農場部署)。
# Ant 腳本 copy-to-path 目標已自動複製到 upload 目錄
# 修改 Bean 程式碼後,只需重跑 ant all,即可熱更新
| 現象 | 可能原因 | 解決方案 |
|---|---|---|
| JNDI 查找失敗 NameNotFoundException | JNDI 名稱不匹配 | 檢查 weblogic-ejb-jar.xml jndi-name、lookup 字串、WebLogic 主控台部署詳情 |
| ClassNotFoundException: HelloworldHome | Web 模組缺少 Client JAR | 確認 EjbSamples.jar 在 web/WEB-INF/lib、包含 Remote/Home 介面 |
| ClassCastException on narrow | Stub 版本不匹配 | 重新建置、確認 weblogic.jar 版本一致、清除暫存 |
| TransactionRolledbackException | 資料庫/交易問題 | 檢查資料源、交易屬性、資料庫鎖定 |
| Ant 建置失敗找不到 weblogic.jar | 路徑配置錯誤 | 修正 build.xml j2eelib 屬性指向正確 weblogic.jar |
| 環節 | 2005 年 (EJB 2.1 + WebLogic) | 現代 (Spring Boot 3 / Jakarta EE 10) |
|---|---|---|
| 遠端介面 | Remote/Home 介面 + RMI-IIOP + PortableRemoteObject.narrow | @Remote 介面 + REST/gRPC / 無介面本地注入 |
| 建置部署 | Ant + 手動複製 JAR + 主控台部署 | Maven/Gradle + 自動化 CI/CD + 容器化 |
| 狀態管理 | @Stateful Session Bean (叢集複雜) | Redis Session / JWT 無狀態 / 數據庫 |
| 依賴注入 | JNDI 查找 + setSessionContext | @Autowired / @Inject / 建構子注入 |
| 熱部署 | Upload 目錄覆蓋技巧 | Spring DevTools / JRebel / 容器滾動更新 |
雖技術棧已迭代多輪,但「介面隔離、依賴倒置、容器管理生命週期、宣告式交易」等核心架構原則始終未變。理解經典 EJB 開發流程,有助於深刻體會現代框架設計哲學的傳承與革新。