这两天因为想测试一下群集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呢!