WebLogic 与 Hibernate 的兼容性
下面我们再来看 WebLogic 同著名 Java 的 OR 映射框架 Hibernate 的兼容性,并逐步展 开讨论。
Hibernate 中可能遇到的问题
系统抛出下边的异常,导致 WebLogic 异常退出:
org.hibernate.hql.ast.HqlToken org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken [from com.dhcc.mm5.QbMm5List] at org.hibernate.hql.ast.HqlLexer.panic(HqlLexer.java:57) at antlr.CharScanner.setTokenObjectClass(CharScanner.java:340) at org.hibernate.hql.ast.HqlLexer.setTokenObjectClass(HqlLexer.java:31) at antlr.CharScanner.(CharScanner.java:51) at antlr.CharScanner.(CharScanner.java:60) at org.hibernate.hql.antlr.HqlBaseLexer.(HqlBaseLexer.java:56) at org.hibernate.hql.antlr.HqlBaseLexer.(HqlBaseLexer.java:53) at org.hibernate.hql.antlr.HqlBaseLexer.(HqlBaseLexer.java:50) at org.hibernate.hql.ast.HqlLexer.(HqlLexer.java:26) at org.hibernate.hql.ast.HqlParser.getInstance(HqlParser.java:44) at org.hibernate.hql.ast.QueryTranslatorImpl.parse (QueryTranslatorImpl.java:232) at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile (QueryTranslatorImpl.java:155) at org.hibernate.hql.ast.QueryTranslatorImpl.compile (QueryTranslatorImpl.java:109) at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:75) at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:54) at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan (QueryPlanCache.java:71) at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan (AbstractSessionImpl.java:133) at org.hibernate.impl.AbstractSessionImpl.createQuery (AbstractSessionImpl.java:112) at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1583) at com.dhcc.mm5.QbMm5ListDAO.findAll(QbMm5ListDAO.java:141) at jsp_servlet.__left._jspService(__left.java:114) at weblogic.servlet.jsp.JspBase.service(JspBase.java:34) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run (StubSecurityHelper.java:226) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet (StubSecurityHelper.java:124) at weblogic.servlet.internal.ServletStubImpl.execute (ServletStubImpl.java:283) at weblogic.servlet.internal.ServletStubImpl.onAddToMapException (ServletStubImpl.java:391) at weblogic.servlet.internal.ServletStubImpl.execute (ServletStubImpl.java:309) at weblogic.servlet.internal.ServletStubImpl.execute (ServletStubImpl.java:175) at weblogic.servlet.internal.WebAppServletContext $ServletInvocationAction.run(WebAppServletContext.java:3370) at weblogic.security.acl.internal.AuthenticatedSubject.doAs (AuthenticatedSubject.java:321) at weblogic.security.service.SecurityManager.runAs(Unknown Source) at weblogic.servlet.internal.WebAppServletContext.securedExecute (WebAppServletContext.java:2117) at weblogic.servlet.internal.WebAppServletContext.execute (WebAppServletContext.java:2023) at weblogic.servlet.internal.ServletRequestImpl.run (ServletRequestImpl.java:1359) at weblogic.work.ExecuteThread.execute(ExecuteThread.java:200) at weblogic.work.ExecuteThread.run(ExecuteThread.java:172)
问题原因分析
Hibernate3.0 采用新的基于 ANTLR 的 HQL/SQL 查询翻译器,然而在 weblogic.jar 中 已经包含了 antrl 类库,但是版本并不一致,因此就会产生一些类加载的错误。出现这个 错误之后,antlr 会调用 System.exit(),这样就会导致 WebLogic 中止服务。
需要补充说明一下,在 Hibernate 的配置文件中,hibernate.query.factory_class 属性用来选择查询翻译器。
(1)选择 Hibernate3.0 的查询翻译器:
hibernate.query.factory_class=
org.hibernate.hql.ast.ASTQueryTranslatorFactory
(2)选择 Hibernate2.1 的查询翻译器
hibernate.query.factory_class=
org.hibernate.hql.classic.ClassicQueryTranslatorFactory
为了使用 3.0 的批量更新和删除功能,只能选择(1)否则不能解释批量更新的语句, 当使用的时候出现了不支持条件输入中文的情况。选择(2)可以支持输入中文,但没法解 释批量更新语句了。
解决方法
解决办法是在 hibernate.properties 文件中增加属性 hibernate.query.factory_class,属性的值是
org.hibernate.hql.classic.ClassicQueryTranslatorFactory. 如果用的是 cfg.xml 文件,
就在 hibernate.cfg.xml 中的
<property name="query.factory_class" > org.hibernate.hql.classic.ClassicQueryTranslatorFactory </property >
也可在 WebLogic 的启动脚本中,将 antlr-2.7.5H3.jar 放在最前面。
小结:以上主要提及了 Weblogic 与 spring 和 hibernate 的兼容性,一般情况下 Weblogic 与 SSH 兼容问题在于类(包)冲突,由于 Weblogic 自带了 classloader 会首先 去找到自己的 jar 文件,然后加载项目的 jar,很多项目中的 jar 均已在 Weblogic 的 jar 中被加载了,直接导致无法在项目的 war 或者 ear 中找到 jar 文件。通常的解决办法就 是:在 classpath 中配置让需要的包在 webservice.jar 之前加载。