13 Replies Latest reply on May 4, 2011 1:52 PM by davsclaus

    org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast

    jcoguser

      I hope someone could shed some light on the following issue:

       

      I'm writing a SMX 4.2.0-fuse-02-00 database look-up application using Camel, Hibernate and JPA.

      The application has 2 bundles that do database operations implementing 2 different requests. One other bundle does content base routing to direct request to one bundle or the other.

      One bundle works fine, but the other doesn't.

      I can't see much of a difference of the named-queries of the working bundle with the ones in the failing bundle.

       

      I don't want to make this a very long message, so if additional information is needed, I'll be more than glad to provide it. I've appended part of the stack trace below.

       

      Thanks in advance for any help.

       

      Caused by: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken

              at org.hibernate.hql.ast.HqlLexer.panic(HqlLexer.java:80)

              at antlr.CharScanner.setTokenObjectClass(CharScanner.java:338)

              at org.hibernate.hql.ast.HqlLexer.setTokenObjectClass(HqlLexer.java:54)

              at antlr.CharScanner.(HQLQueryPlan.java:80)

              at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:94)

              at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)

              at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1141)

              at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)

              at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:67)

              ... 56 more

        • 1. Re: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast
          ffang

          Hi,

           

          As one bundle works but another one doesn't, and those two bundles actually doing same thing,  I suggest you just use

          osgi:headers

          to see the different Import-Package of each bundle, this may inspire you.

           

          Freeman

          • 2. Re: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast
            jcoguser

            Thanks Freeman for your reply. I followed your suggestion and did found some discrepancies in the imports. After moving a few things around, I got the imports for the 2 bundles to match. However, I still got the same error.

            Then I traced a request through for each of the 2 database lookup bundles. I found out that the failing bundle has a select statement with an "IN (:list)" clause. Eventually the :list gets replaced by many instance variables (: variables) as there are in the actual list. This replacement causes the query to be parsed again during the query.getResultList(). Here is when the exception gets thrown. I narrowed it down to the antl.Utils.loadClass(String name). See code snippet below. Now my question: Is this another case of a class using the current thread's classloader to load a class that such a classloader has not visibility to, but the bundle's does.

            In any case, how do I get around it?

             

            Thanks in advance.

             

             

            public static Class loadClass(String name) throws ClassNotFoundException {

            try {

                 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

                 if (!useDirectClassLoading && contextClassLoader!=null ) {

                      return contextClassLoader.loadClass(name);

                 }

                 return Class.forName(name);

            }

            catch (Exception e) {

                 return Class.forName(name);

            }

            }

            • 3. Re: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast
              sorin7486

              Hi,

               

                     have you found a solution to this ? I have a similar problem in ServiceMix 4.3.0.

              • 4. Re: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast
                sorin7486

                Actually for me it seems that setting the following property did the trick:

                 

                 

                • 5. Re: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast
                  jcoguser

                  Sorin.

                  I found a workaround that consisted in overriding the thread classloader with the bundle classloader. If you need details let me know; however, it seems you found a solution.

                  • 6. Re: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast
                    sorin7486

                    Hi,

                     

                          It's not a verry good solution because it throws a different error on certain queries and when I google it all the answers I get say I should be using antlrn! This thing is starting to get on my nerves.

                     

                          How did you overwrite the thread classloader ? Does that have any other side effects?

                    • 7. Re: org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast
                      sorin7486

                      There's another workaround on this page:

                      http://www.yarenty.com/tools/java/56-osgihibernatepart1.html?showall=1

                       

                      I tried it but without any luck. I had it with Hibernate so I think I'll give openjpa a go.

                      • 8. Re:  ClassNotFoundException: org.hibernate.hql.ast
                        jecalvert

                        I would be very interested to see what you did. The question is where does the answer lie? It is dumb that the HQL lexer passes a class by name, but also dumb that ultimately there's some Util class using the Thread context class loader. Fuse ESB is already using "Apache ServiceMix :: Bundles :: antlr (2.7.7.3)" Would it be silly or reasonable to fork antlr and fix the "Utils" class?

                         

                        An alternative is to note that HqlLexer has antlr.CharScanner as a superclass; the call in CharScanner gets the class and then sets it to a protected field. I can't imagine why setTokenObjectClass() in HqlLexer doesn't just bypass the super and set the class directly via

                         

                        tokenObjectClass = HqlToken.class;

                        /code

                         

                        ESPECIALLY since it already throws away the string argument. At that point, one might even petition the Hibernate gods with a patch...

                        • 9. Re:  ClassNotFoundException: org.hibernate.hql.ast
                          jcoguser

                          This is what it was suggested to me. It solved my immediate problem but haven't done much testing to verify it didn't break anything else. As I said in a previous posting, the hack consisted in overriding the thread's class loader before the call to the method that will eventually result in the ClassNotFound exception. query.getResultList() in my case. The thread's original class loader is restored back after the "failing" call is completed. Good luck!

                           

                          ClassLoader cl = null;

                          try {

                               Query query =

                                   createNamedQuery ("MyEntityObject.myNamedQuery");

                               query.setParameter("param1",  getParam1());

                               query.setParameter("param2",  getParam2());

                               cl = Thread.currentThread().getContextClassLoader();

                               Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());

                               List();

                          }

                          catch (Exception e) {

                               throw new MyDatabaseException(e);

                          }

                          finally {

                               if ( cl != null )

                                    Thread.currentThread().setContextClassLoader(cl);

                          }

                          • 10. Re:  ClassNotFoundException: org.hibernate.hql.ast
                            jecalvert

                            I created an issue in the Hibernate JIRA; not sure if anyone will reply.

                            http://opensource.atlassian.com/projects/hibernate/browse/HHH-6165

                             

                            I have applied my simple patch backported to the standard Fuse hibernate bundle and I confirmed that it fixed the ClassNotFound for me.

                             

                            Really if you look at the code, there is no reason why the HqlLexer should be passing class by it's name to get loaded in another package when it can simply set it on the protected field directly, since it is a subclass. Of course, this is something that no one would really bother to notice unless you were in an OSGi env.

                             

                            https://github.com/jcalvert/hibernate-osgi-fix

                            That's my github where I've dumped the patched source and put a JAR file for anyone who needs it. I would be delighted to know that anyone else who tries it if it also fixed their exceptions.

                             

                            hoping someone from fusesource notices this

                            • 11. Re:  ClassNotFoundException: org.hibernate.hql.ast
                              davsclaus

                              Unfortunately Hibernate is most likely the most OSGi unfriendly framework out there.

                               

                              OpenJPA works much better in OSGi.

                              • 12. Re:  ClassNotFoundException: org.hibernate.hql.ast
                                sorin7486

                                Yes I migrated to OpenJPA and everything works now. But if Hibernate is so unfriendly why do I get the feeling that everything there is more support for it than for OpenJPA?

                                • 13. Re:  ClassNotFoundException: org.hibernate.hql.ast
                                  davsclaus

                                  Hibernate was created much long before OpenJPA. In fact JPA spec is heavily based on Hibernate after it has proven itself after many years.

                                   

                                  OpenJPA is used by IBM in their offerings as their JPA implementation. And IBM is going down the OSGi road. So rest assured OpenJPA will play nicely with OSGi.