CharScanner; panic: ClassNotFoundException: org.hibernate.hql.ast.HqlToken
or when trying to run an application using HQL with antlr as parser, the following stacktrace may appear:
org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken [ from org.example.hibernate.Customer]
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:242)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:112)
at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:57)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
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:1627)
at org.example.hibernate.HQLSample.selectCustomer(HQLSample.java:41)
at Test.doGet(Test.java:38)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:821)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:184)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3717)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
Cause
Classloading issues with antlr library bundled with WebLogic Server that is not compatible with Hibernate 3.
Solution
It is necessary to use antlr 2.7.6 (this version works, however more details of which version should be check with Hibernate as being a third party tool).
There are 4 possible workarounds for this classloading issue:
1. Package antlr.jar into WEB-INF/lib and add the following tag to weblogic.xml
(this works for war alone or packaged into an ear).
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
2. If it is an ear file then put antlr.jar at APP-INF/lib (or at web application level: WEB-INF/lib) and modify weblogic-application.xml adding the following tag:
<prefer-application-packages>
<package-name>antlr.*</package-name>
</prefer-application-packages>
3. Change property hibernate.query.factory_class from hibernate configuration file (hibernate.cfg.xml).
(if hibernate.query.factory_class doesn't exist then this value is assigned by default):
<property name="hibernate.query.factory_class"
value="org.hibernate.hql.ast.ASTQueryTranslatorFactory">
</property>
to a different parser (classic):
<property name="hibernate.query.factory_class"
value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory">
</property>
4. Set at server classpath level antlr library before WLS classpath.
(warning: this is the less recommended option because it impacts the whole WLS and may affect another modules).
In setDomainEnv.cmd (or any of the start-up scripts) set the next value at the end of the file, referring to antlr library's location:
set CLASSPATH=C:\jars\antlr-2.7.6.jar;%CLASSPATH%
References
http://download.oracle.com/docs/cd/E21764_01/web.1111/e13706/classloading.htm
http://community.jboss.org/wiki/HibernateCoreMigrationGuide30#weblogic
1 comment :
Excellent summary of the problem and its solutions!
Post a Comment