"jimpo991" wrote :
| I still don't understand why all this results in a ClassCastException about
FullTextIndexEventListener. If my war uses the hibernate jars from WEB-INF, and they
don't contain org.hibernate.search package, where does the classcastexception come
from?
Valid question. I hadn't completely got an answer to that yesterday so i had
intentionally left out the explanation for the classcast from my earlier post. But now,
after going through the Hibernate Annotations code and adding some log statements and
enabling verbose class logging, i guess i understand what the issue is. Let me try to put
it here. Let's consider the case where you did NOT place the hibernate-search.jar file
in the WEB-INF/lib of your application:
1) Where in the code does this classcast occur- The name of the class where this happens
is AnnotationConfiguration.java (which is part of the hibernate-annotationsxxx.jar). The
lines of the code are (just copied the relevant part here - see the line marked in bold):
try {
| searchEventListenerClass = ReflectHelper.classForName(
| "org.hibernate.search.event.FullTextIndexEventListener",
| AnnotationConfiguration.class );
|
| }
| ...//some code here
| PostInsertEventListener[] listeners =
getEventListeners().getPostInsertEventListeners();
| newListeners[length-1] = (PostInsertEventListener) searchEventListener;
| ...//some more code here
|
|
So when the FullTextIndexEventListener is being cast to PostInsertEventListener, the
classcast is being thrown. But looking at the FullTextIndexEventListener class definition,
it infact does implement this interface:
public class FullTextIndexEventListener implements PostDeleteEventListener,
PostInsertEventListener,
| PostUpdateEventListener, Initializable {
|
As you have been wondering, since the FullTextIndexEventListener is available ONLY in the
hibernate-annotations.jar file present in the server/lib folder, how could it be that the
FullTextIndexEventListener be loaded by 2 different classloaders. A bit of verbose class
logs revealed that it was not the FullTextIndexEventListener that was loaded by different
classloaders. It turned out that the PostInsertEventListener was being loaded by
different classloaders. Here's the reason - The PostInsertEventListener is part of the
hibernate (core) jar. The hibernate jar is present in the server/lib folder as well as the
application's WEB-INF/lib folder. The PostInsertEventListener was once loaded by the
application specific classloader. Then when the following code was executed
searchEventListenerClass = ReflectHelper.classForName(
| "org.hibernate.search.event.FullTextIndexEventListener",
| AnnotationConfiguration.class );
the FullTextIndexEventListener (present in hibernate-annotations.jar in server/lib) got
loaded by the parent classloader since it was not present in your application's
WEB-INF/lib folder. While loading this class, the server also loaded (again) the
PostInsertEventListener (remember the FullTextIndexEventListener implements this
interface) , this time using the classloader which loaded FullTextIndexEventListener -
which turns out to be the parent classloder (since the parent classloader was used, it
picked up this interface from the hibernate3.jar present in the server/lib folder and not
the hibernate-3.2.5.jar present in the WEB-INF/lib of your application). Ultimately, the
PostInsertEventListener was loaded by 2 different classloaders through the hibernate3.jar
(in server/lib) and hibernate-3.2.5.jar (in WEB-INF/lib). This resulted in the classcast.
Adding the hibernate-search.jar to WEB-INF/lib solves the problem because, the
FullTextIndexEventListener (and eventually the PostInsertEventListener ) will be loaded by
the application specific classloader instead of the parent classloader.
Makes sense?
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4097752#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...