這兩天因為想測試一下群集Cache,用Myeclipse 建了一個測試程序,快把我折騰死了。
在Myeclipse的設計中,Project的粒度很細。EAR Project, WAR Project, 和EJB Project是三個不同的Project。它不支持EAR Project包打天下不太一樣。
我按照這個要求,創建了四個項目:EAR, WAR, EJB和一個公用的Pojo Project。
公司剛剛換用了SubVersion首先涮了我一把。Subeclipse 1.0.1只認一個項目一個項目的check out。一下子把我的四個項目合并成一個什么都不是的大項目。 我只好把這個大項目關掉,再一個一個的導入進來。
可是碰在新建Subversion庫的當口上,項目的服務器路徑變動了好幾次。每次都要我這么弄幾下。迫不得已,裝上TortoiseSVN-1.4.3。這東西爽!可以一下子把四個項目全取下來,而且不破壞eclipse項目結構。
然而,當我打開eclipse,又碰到一個經典問題: subeclipse 1.0.1和TortoiseSVN-1.4.3不兼容,報告說我的subversion客戶端太老(其實是它自己老了),直接罷工了。
左找右找,終于發現有人說subeclipse 1.1.6搞定了這個問題。于是升級,搞定了這個問題。
?
要說Myeclipse對于EJB和JSP的支持確實漂亮,輕輕松松的就開發完成了。部署并初步運行也是成功的。
只有一個美中不足:它生成的war包和jar包不能指定名字。在EAR的.mymetadata中,有這么一段配置:
<
project-modules
>
<
project-module
type
="WEB"
name
="Cache?Web"
id
="myeclipse.1171417787608"
context-root
="/cache"
j2ee-spec
="1.4"
archive
="Cache?Web.war"
>
<
attributes
>
<
attribute?
name
="webrootdir"
?value
="/root"
?
/>
</
attributes
>
</
project-module
>
<
project-module
type
="EJB"
name
="Cache?Ejb"
id
="myeclipse.1171417692847"
j2ee-spec
="1.4"
archive
="Cache?Ejb.jar"
?
/>
</
project-modules
>
?
包名中帶空格可不是我的風格。我嘗試修改上面的archive屬性。但是最后生成的EAR中,包名還是照舊。很有可能archive屬性根本就沒有作用。Myeclipse簡單的拿工程名做包名。
?
沒辦法,將就過吧。繼續測試。Pojo是個單獨的Hibernate Pojo項目。EJB和JSP都有引用到。
在EJB中,調用Pojo得到一個List,里面的元素是Order對象。在EJB中從Object轉成Order成功。但在JSP中轉型時,碰到一個極為古怪的問題:ClassCastException。
調用EJB得到List都成功了,可怎么從中轉出Order對象會出問題呢?打開Debug看看,List中的確是Order對象啊!太古怪了!
沒救了,死馬當活馬醫吧。把遠程EJB調用改成本地EJB調用——問題照舊!檢查所有配置文件,都簡單得不可能出問題啊!
……神啊,救救我吧。
最后,在檢查部署后的文件時發現了問題。WAR包和EJB包各自把Pojo項目中的所有classs合并了進來。這樣在一個EAR中,每個pojo的class都有兩份。JSP和EJB各引用各的,從而導致了類型不匹配。
問題的原因在于Myeclipse中指定的部署方法不對。為了省事,我在WAR和EJB的部署配置中,都選擇了“Merge dependent Java Project Delopyment"。如下圖所示。
將部署配置改為Ignore之后,然后手工將pojo包放到jboss server的lib中,問題終于解決了。
可是這樣一來,每次我都得手工的部署pojo包。在EAR的配置中有一個"Jar dependent Java projects"。選中它,并且在引用項目中選中Pojo項目。Myeclipse就會自動將Pojo包部署到EAR中。
然而,它部署是部署了,沒把人家放到classpath中去,一運行就報錯:ClassNotFound。這個問題好解決,在EJB和WAR的MANIFEST.MF中加入classpath就可以了。
一開始我用的是pojo.jar這個名字,放到classpath中后運行成功。
可是Myeclipse在每次自動生成pojo包時,給的是工程名"cache pojo.jar",里面有個空格。classpath死活不認識它,用引號引起來也不行。
問題到了最后,還是沒有圓滿解決——早知今日,我還不如直接用個ant building呢!