GlassFish移植Tips

       最近,公司的GlassFish移植项目基本告以段落,由于之前的代码严重依赖于Weblogic,给移植工作带来了很大的难度,很多实现方式在 GlassFish中根本就没有对应的替代品。在经历了几个月的移植之后,竟让我对Weblogic开始产生好感了,作为一款商用的 Application Server,Weblogic确实非常成熟,非常强大,提供了很多特性,以帮助提高程序的运行效率,但是太笨重了,访问Admin Console极慢;GlassFish作为一款开源的Application Server,非常适合开发者使用,速度很快,并且严格遵照J2EE的标准,以达到平台独立的特性,但是确实简陋了点,只提供了最标准的实现,并且还存在 一些明显的BUG,社区不够活跃,文档、资源都很少,可能是现在SUN处于动 乱期,连商业Support都很难联系到。下面是我在做移植工作时,随笔记下 来的一些小经验,让其他的同学们少受一些折磨,少踩一些坑。

      1、EJB Client与 weblogic.jar冲突

若使用 EJB Client访问 GlassFish中的 EJB,需将 appserv-rt.jar、 appserv-ext.jar、 appserv-deployment-client.jar和 javaee.jar加入到 classpath中。若 classpath中存在 weblogic.jar,则可能会遇到错误:
java.lang.NoSuchMethodError: org.omg.CosTransactions.OTSPolicy.value()S
将 weblogic.jar从 classpath中移除即可。

      2、Transaction使用

使用 Spring的 JtaTransactionManager需要配置两个属性: JtaTransactionManager 和 userTransactionName。对于 GlassFish, JtaTransactionManager 为 java:appserver/TransactionManager , userTransactionName 为 java:comp/UserTransaction。只有 Bean管理的 SessionBean和 MDB允许使用 UserTransaction, Entity Bean只允许使用 Container管理的 transaction。如果 Container管理的 SessionBean或 MDB使用了 UserTransaction,则会出现错误: Lookup of java:comp/UserTransaction not allowed for Container managed Transaction beans 。

      3、HTTP Thread count

使用 asadmin修改 HTTP 的 thread count后,从 Admin Console上访问, Admin Server的配置可生效,但 Cluster不生效,检查 domain.xml已改变,通过 asadmin查询也已生效,应该是 GlassFish页面展示的 BUG。

      4、EJB Timer的使用

在 GlassFish中使用 EJB Timer,需要有一个独立的 XADataSource,和数据表 EJB__TIMER__TBL,建表语句可在 <server_path>/lib/install/databases中找到。对于 developer模式, GlassFish默认使用内置的 __TimerPool,不需要你手工创建 datasource和表;对于 cluster模式, Admin Server会默认使用 __TimerPool, Cluster则需要单独配置。如果让 Admin Server和 Cluster同时使用手工创建的 datasource,则可能导致 Cluster配置中的 timer datasource在 server重启后丢失, Timer Service会出现异常,这应该是 GlassFish的 BUG,目前的解决方案就是 Admin Server用默认的 Timer配置, Cluster用另外的配置。

      5、ClassLoader优先加载

在 weblogic中,可以通过配置 prefer-application-packages来优先加载 application中的类,在 GlassFish中则没有对应的方式来控制加载顺序,一个典型的场景就是:项目中采用 CXF作为 webservice的实现,但 GlassFish中默认使用了 Metro的实现,由于 Metro的 jar包比 application加载的早,就会导致 CXF依赖的类库没有正常加载,而是使用了 Metro的 JAX-WS的实现。

      6、CMP配置中的数据库表名区分大小写

CMP在 GlassFish中需要配置 sun-cmp-mappings.xml,该 XML中的 table-name是区分大小写的, Oracle中的表名默认是大写的,如果这里的 table-name写成小写,就会报找不到表的错误,可以通过添加一个 *.dbschema文件,对表名进行适配,以减少切换数据库时的修改操作。

      7、GlassFish的部署结果不可靠

在使用 asadmin部署 EAR时,如果没有遇到极其严重的错误,部署一般都会返回成功,但这个结果并不可靠,你需要关注 server.log,如果这里出现了错误,应用程序则可能没有真正部署成功,在运行时就会出现错误,所以要确保你的程序部署时, server.log中没有错误信息。

       8、TLD路径

 根据 JSP2.1规范, tld文件不能存放在 /WEB-INF/classes或者 /WEB-INF/lib目录中,特别不能放在 /WEB-INF/tags目录或子目录中,否则会出现错误:
 exception: org.apache.jasper.JasperException: PWC6180: Unable to initialize TldLocationsCache
 root cause: org.apache.jasper.JasperException: PWC6336: Illegal TLD path /WEB-INF/tags/fn.tld, must not start with “/WEB-INF/tags”
 在 Tomcat和 Weblogic中不会出现该问题, GlassFish则严格遵照规范,可将 tld文件放置在 /WEB-INF/tld目录。

     9、注册 servlet listener

在 web.xml中注册 servlet的 listener时,在 <listener>中添加多个 <listener-class>不会报错,但是只有最后一个 <listener-class>生效,因此,要注册多个 listener,需要添加多个 <listener>。

      10、 Pass-by-reference

Weblogic中的 call-by-reference能够极大的提高本地接口调用的效率,在 GlassFish中也有相应的替代,就是 pass-by-reference,可以在 sun-ejb-jar.xml中对某个 EJB进行配置,也可以在 sun-application.xml中配置,这样就可以对整个 application中的 EJB生效。

      11、 HTTP错误消息体

当 HTTP的 ErrorCode大于 400,并且相应的消息体是空时, GlassFish会自动在返回的 Response中添加错误信息,对于使用 HttpClient操作时,就可能和我们期望的 Response不同,该问题的解决办法:在往 Response中写入内容后,调用 response.getOutputStream().flush() 或 response.flushBuffer();或者在 web.xml中设置 ErrorcCde对应的 ErrorPage, ErrorPage可以是一个空内容的页面。

      12、 ServletRequest中 inputStream的使用

InputStream有一个 markSupported属性,如果该属性为 true,则支持 mark和 reset,可以多次读取该流,反之则只能读取一次该输入流。一种情形就是:如果在 Filter中读取了该 InputStream,则不能在 Servlet中再次读取。 ServletRequest中的 InputStream在不同的 Server中有不同的实现,在 Weblogic中 markSupported就设为了 true,在 GlassFish中则为 false。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值