想要將您的 EJB 代碼遷移到 JBoss 5 嗎?不能使代碼部署和運行嗎?如果是這樣,這個技巧就是為您准備的。或者,您是一個 JBoss 5 新手但是您想感受一下 EJB 3 環境?這個技巧詳細介紹了在 JBoss5 上構建、部署和運行 EJB3 代碼需要的 XML 部署文件。
常用縮略詞
EJB:企業級 Java 組件(Enterprise Java Bean)
JDK:Java 開發工具箱(Java Development Kit)
XML:可擴展標記語言(Extensible Markup Language)
根據我的實踐經驗,構建 Java™ 源代碼時總是會遇到一些問題。事實的確如此,當我試圖在 JBoss5 上運行我的 EJB3 代碼時,我發現了幾個問題,但是我最終解決了這些問題,我將在本文中介紹我是如何解決它們的。如果您想要跟隨本文一起操作,我建議您安裝 JBoss 的兩個版本:版本 4 和版本 5(參見 參考資料 中的鏈接)。而且,您需要安裝 JDK 1.5 版,且 JAVA_HOME 變量指向安裝文件夾 — 例如 JAVA_HOME= C:\Java\jdk1.5.0_06。
升級路徑
開始遷移之前,首先檢查一下 JBoss4 上當前運行的 EJB3 代碼。清單 1 展示了一個簡單的 EJB3 實體類,稱為 GreetingCard。
清單 1. EJB3 GreetingCard 類
@Entity
@Table(name="GREETING_CARD")
public class GreetingCard implements Java.io.Serializable
{
private int id;
private String greeting;
private int colour;
@Id
@Column(name="ID")
public int getId()
{
return id;
}
public void setId(int pk)
{
id = pk;
}
@Column(name="NAME")
public String getGreeting()
{
return greeting;
}
public void setGreeting(String str)
{
greeting = str;
}
@Column(name="COLOUR")
public int getColour()
{
return colour;
}
public void setColour(int colour)
{
this.colour = colour;
}
}
清單 2 展示了一個無狀態 bean 類。
清單 2. 一個無狀態實體 bean
@Stateless
public class CardShopBean implements CardShopRemote
{
@PersistenceContext(unitName="cardshop") private EntityManager manager;
public void createGreetingCard(GreetingCard greetingCard)
{
manager.persist(greetingCard);
}
public GreetingCard findGreetingCard(int pKey)
{
return manager.find(GreetingCard.class, pKey);
}
public void removeGreetingCard(GreetingCard greetingCard)
{
manager.remove(greetingCard);
}
public void flushGreetingCard()
{
manager.flush();
}
public void mergeGreetingCard(GreetingCard greetingCard)
{
manager.merge(greetingCard);
}
}
清單 3 中的這個簡單的 program 類運行代碼。
清單 3. 運行代碼
public static void main(String [] args)
{
try
{
Context jndiContext = getInitialContext();
Object ref = jndiContext.lookup("CardShopBean/remote");
CardShopRemote dao = (CardShopRemote)ref;
GreetingCard oldGreetingCard = dao.findGreetingCard(1);
if (oldGreetingCard != null)
{
dao.mergeGreetingCard(oldGreetingCard);
dao.removeGreetingCard(oldGreetingCard);
dao.flushGreetingCard();
}
GreetingCard greetingCard_1 = new GreetingCard();
greetingCard_1.setId(1);
greetingCard_1.setGreeting("Seasons Greetings from Terry Dactyll");
greetingCard_1.setColour(1);
dao.createGreetingCard(greetingCard_1);
GreetingCard greetingCard_2 = dao.findGreetingCard(1);
System.out.println("Greeting card name: " + greetingCard_2.getGreeting());
System.out.println("Greeting card colour: " + greetingCard_2.getColour());
}
catch (Javax.naming.NamingException ne)
{
ne.printStackTrace();
}
}
當您在 JBoss 版本 4 中運行這段代碼時,您得到的客戶端結果如 清單 4 所示。
清單 4. 在 JBoss 4 中運行 EJB3 代碼
ant run.clIEnt
Buildfile: build.XML
run.clIEnt:
[Java] Greeting card name: Seasons Greetings from Terry Dactyll
[Java] Greeting card colour: 1
BUILD SUCCESSFUL
Total time: 10 seconds
沒有什麼奇怪的事情發生。現在,嘗試在 JBoss 5 下運行同樣的代碼。在這兩個環境之間移動很簡單。第一步就是修改 JBOSS_HOME 環境變量的值。在我的系統上,這意味著我需要將 JBOSS_HOME=C:\java\jboss4\JEMS-jboss-4.0.5.GA 修改為 JBOSS_HOME=C:\Java\jboss5\jboss-5.0.0.GA。
現在,當您運行 ant -p 時,您得到 清單 5 中的結果。
清單 5. JBoss 5 中的路徑問題
build.XML:35: C:\Java\jboss5\jboss-5.0.0.GA\server\default\deploy\ejb3.deployer not found.
對 build.XML 的微小更改(如 清單 6 所示)修復了 清單 5 中的問題。
清單 6. 對 build.XML 的第一次更改
<fileset dir="${jboss.home}/server/default/deployers/ejb3.deployer">
運行 ant -p 又出現了另一個(類似的)錯誤,如 清單 7 所示。
清單 7. 又一個路徑問題
build.XML:35:
C:\Java\jboss5\jboss-5.0.0.GA\server\default\deploy\jboss-aop-jdk50.deployer
not found.
就像上一次更改一樣,這個問題也很容易修復(參見 清單 8)。
清單 8. 對 build.XML 的第二次更改
<fileset dir="${jboss.home}/server/default/deployers/jboss-aop-jboss5.deployer">
這時,運行 ant -p 沒有出現問題。現在可以在 JBoss 5 中構建 EJB3 代碼了。不幸的是,運行 ant compile 導致 清單 9 中顯示的錯誤。(注意,清單 9 是實際輸出的一小部分摘要。)
清單 9. 編譯問題
ant compile
compile:
[javac] Compiling 4 source files to C:\Java\jbossmigration\mycode-jboss5\build\classes
[javac] C:\Java\jbossmigration\mycode-jboss5\src\main\com\cardsrus\cardshop\
CardShopBean.java:3: package Javax.ejb does not exist
[javac] import Javax.ejb.Stateless;
[Javac] ^
[javac] C:\Java\jbossmigration\mycode-jboss5\src\main\com\cardsrus\cardshop\
CardShopBean.java:4: package Javax.persistence does not exist
[javac] import Javax.persistence.EntityManager;
[Javac] ^
清單 9 中的問題是由於缺少一個庫導入而導致的。要修復問題,需要再次修改 build.XML,如 清單 10 所示。將 清單 10 中的代碼添加到類路徑構造目標中的 <fileset> 元素。
清單 10. 添加一個庫導入
<fileset dir="${jboss.home}/common/lib">
<include name="*.jar"/>
</fileset>
進行 清單 10 中的更改後,這個 Java 代碼成功編譯了。它部署到 JBoss 5 之上了嗎?遺憾的是,沒有,正如 清單 11 中的服務器端日志摘要所示。
清單 11. 部署問題
16:44:03,093 ERROR [AbstractKernelController]
Error installing to Parse:
name=vfszip:/C:/Java/jboss5/jboss-5.0.0.GA/server/default/deploy/cardsrus.jar
state=Not Installed mode=Manual requiredState=Parse
org.jboss.deployers.spi.DeploymentException: Error creating managed object for
vfszip:/C:/Java/jboss5/jboss-5.0.0.GA/server/default/deploy/cardsrus.jar at
org.jboss.deployers.spi.DeploymentException.rethrowAsDeploymentException
(DeploymentException.Java:49) at
org.jboss.deployers.spi.deployer.helpers.AbstractParsingDeployerWithOutput.
createMetaData (AbstractParsingDeployerWithOutput.Java:337)
要修復這個部署問題,需要修改 persistence.xml 文件,如 清單 12 所示。在原始 persistence.XML 文件中,需要使用清單 12 中的內容替換 <persistence> 這一行。
清單 12. 修改 persistence.XML
<persistence
XMLns="http://Java.sun.com/XML/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://Java.sun.com/XML/ns/persistence
http://Java.sun.com/XML/ns/persistence/persistence_1_0.xsd"
version="1.0" >
進行了 清單 12 中的更改後,這個代碼在 JBoss 5 下部署和運行,客戶端輸出類似於先前您看到的 清單 4 中的內容。
這樣,您最終走出迷霧,將您的 EJB3 代碼從 JBoss 4 遷移到了 JBoss 5。
結束語
在 JBoss 4 和 JBoss 5 之間移動 EJB3 代碼並不是一件簡單的事情。您可能需要一個遷移工具(比如一個 Eclipse 插件)來自動化部分或全部代碼更改。在此之前,我希望本文能夠幫助您順利完成代碼遷移。