Apache Geronimo 採用 OpenEJB 作為 EJB 容器,部署描述符與傳統 J2EE 伺服器(WebSphere、JBoss、WebLogic)大同小異,但結合 Maven + XDoclet 可將樣板代碼生成自動化,大幅降低開發負擔。本文以電話簿範例完整演示:JSP/Servlet(Struts)、CMP Entity Bean、Stateless Session Bean、資料源配置、應用打包部署全流程。
java -jar bin/deployer.jar deploy phonebook.ear
org.acme.phonebook.struts。src/webapp/pages。ActionServlet,透過 servlet-mappings.xml、servlets.xml 定義,Maven 建構時合併為 web.xml。<!-- servlet-mappings.xml -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>120</session-timeout>
</session-config>
<!-- servlets.xml -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param><param-name>config</param-name><param-value>/WEB-INF/conf/struts-config.xml</param-value></init-param>
<load-on-startup>2</load-on-startup>
</servlet>
單一 Java 類 + Javadoc 標籤即可生成 Home/Remote/Local 介面、ejb-jar.xml、openejb-jar.xml、數據表映射。
/** @ejb.bean type="CMP" cmp-version="2.x" name="PhoneBookEntry"
* local-jndi-name="org.acme.phonebook.ejb/PhoneBookEntryLocalHome"
* view-type="local" primkey-field="name"
* @ejb.finder signature="Collection findAll()" query="SELECT OBJECT(o) FROM PhoneBookEntry o"
* @ejb.persistence table-name="PhoneBookEntry"
* @ejb.transaction type="Required" @ejb.permission unchecked="true" */
public abstract class PhoneBookEntryBean implements EntityBean {
/** @ejb.pk-field @ejb.persistence column-name="NAME" jdbc-type="VARCHAR" sql-type="VARCHAR(250)"
* @ejb.interface-method view-type="local" */
public abstract String getName(); public abstract void setName(String v);
/** @ejb.persistence column-name="PHONE_NUMBER" jdbc-type="VARCHAR" sql-type="VARCHAR(250)"
* @ejb.interface-method view-type="local" */
public abstract String getPhoneNumber(); public abstract void setPhoneNumber(String v);
// ejbCreate/ejbPostCreate...
}
openejb-jar.xml<openejb-jar xmlns="https://www.openejb.org/xml/ns/openejb-jar"
configId="org/acme/PhonebookEJB" parentId="MysqlDatabase">
<cmp-connection-factory><resource-link>MysqlDataSource</resource-link></cmp-connection-factory>
<enterprise-beans>
<entity>
<ejb-name>PhoneBookEntry</ejb-name>
<jndi-name>PhoneBookEntry</jndi-name>
<local-jndi-name>java:comp/env/ejb/PhoneBookEntryLocal</local-jndi-name>
<table-name>phone</table-name>
<cmp-field-mapping><cmp-field-name>name</cmp-field-name><table-column>name</table-column></cmp-field-mapping>
<cmp-field-mapping><cmp-field-name>phoneNumber</cmp-field-name><table-column>phone</table-column></cmp-field-mapping>
</entity>
<session> ... PhoneBookSession 定義 ... </session>
</enterprise-beans>
</openejb-jar>
關鍵點:cmp-connection-factory 綁定資料源、table-name 指定實體表、cmp-field-mapping 對應 CMP 欄位至資料庫欄位。
同樣以 XDoclet 標籤定義 JNDI 名稱、事務屬性、EJB 參考(@ejb.ejb-ref 指向 PhoneBookEntry)、Web 層引用(@web.ejb-local-ref)。業務邏輯直接呼叫 PhoneBookEntryUtil.getLocalHome() 完成 CRUD,XDoclet 自動生成 Util 工具類,免寫 JNDI Lookup 樣板碼。
application.xml<application version="1.4" xmlns="https://java.sun.com/xml/ns/j2ee">
<module><ejb>phonebook-ejb.jar</ejb></module>
<module>
<web>
<web-uri>phonebook.war</web-uri>
<context-root>/phonebook</context-root>
</web>
</module>
<module><connector>tranql-connector-1.0-SNAPSHOT.rar</connector></module> <!-- JDBC 資源適配器 -->
</application>
maven ear:ear 產出 phonebook.ear。https://localhost:8080/phonebook/ 測試 Struts 流程:新增、查詢、刪除電話簿條目。ibm-ejb-jar.xmi、jboss.xml)為 openejb-jar.xml,並調整資料源 JNDI 名稱。Geronimo + OpenEJB + Maven + XDoclet 形成高生產力 J2EE 開發棧:
openejb-jar.xml、application.xml)。