项目之前在 Tomcat 环境下一直都正常运行,今天应客户要求需要迁移到 webLogic 10.3.6 下, 部署后竟然抛出了 org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken 异常,经过一番搜索后弄明白了问题的产生原因及解决方法。
问题原因
Hibernate3 采用新的基于 antlr 的 HQL/SQL 查询翻译器,在 hibernate3 中需要用到 antlr,然而这个包在 weblogic 中已经包含了 antrl 类库,所以会产生一些类加载的错误,无法找到在 war 或 ear 中的 hibernate3.jar。
解决方案
方案一:修改 Hibernate 配置 hibernate.query.factory_class 设置其他查询翻译器
hibernate.query.factory_class= org.hibernate.hql.ast.ASTQueryTranslatorFactory
hibernate.query.factory_class= org.hibernate.hql.classic.ClassicQueryTranslatorFactory
方案二:修改 weblogic 的类加载顺序
- <weblogic-web-app
- xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
- http://xmlns.oracle.com/weblogic/weblogic-web-app/1.3/weblogic-web-app.xsd">
- <container-descriptor>
- <!--优先加载位于 Web 应用程序的 WEB-INF 目录中的类,然后再加载应用程序或系统类加载器中的类-->
- <prefer-web-inf-classes>false</prefer-web-inf-classes>
- </container-descriptor>
- </weblogic-web-app>
说明:如果刚好你的应用使用了 CXF 发布 webService,那么使用该方案后会出现 javax/xml/namespace/QName 无法识别的异常,大概错误信息如下:
- Invocation of init method failed; nested exception is java.lang.LinkageError:
- loader constraint violation: when resolving field "DATETIME" the class loader (instance of weblogic/utils/classloaders/ChangeAwareClassLoader)
- of the referring class, javax/xml/datatype/DatatypeConstants, and the class loader (instance of <bootloader>) for the field's resolved type,
- javax/xml/namespace/QName, have different Class objects for that type
该问题如何解决将在后面的方案三和方案四时提到。
方案三:设置 weblogic 的 PRE_CLASSPATH
- set PRE_CLASSPATH=F:\repository\antlr\antlr\2.7.7\antlr-2.7.7.jar
方案四:设置 prefer-application-resources 和 prefer-application-packages
- <weblogic-web-app
- xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
- http://xmlns.oracle.com/weblogic/weblogic-web-app/1.3/weblogic-web-app.xsd">
- <container-descriptor>
- <prefer-web-inf-classes>false</prefer-web-inf-classes>
- <prefer-application-resources>
- <resource-name>META-INF/services/javax.xml.ws.spi.Provider</resource-name>
- </prefer-application-resources>
- <prefer-application-packages>
- <package-name>antlr.*</package-name>
- </prefer-application-packages>
- </container-descriptor>
- </weblogic-web-app>
附:weblogic.xml 部署描述符参考文档
http://docs.oracle.com/cd/E24329_01/web.1211/e21049/weblogic_xml.htm
http://edocs.weblogicfans.net/wls/docs92/webapp/weblogic_xml.html
参考资料:
http://guojuanjun.blog.51cto.com/277646/288121
http://tobato.iteye.com/blog/1845969
http://*.com/questions/2702266/classnotfoundexception-hqltoken-when-running-in-weblogic