Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Brainstorming: Weird JPA problem, possibly classpath or jar versioning problem?

I'm seeing a weird error message and am looking for some ideas as to what the problem could be. I'm sort of new to using the JPA.

I have an application where I'm using Spring's Entity Manager Factory (LocalContainerEntityManagerFactoryBean), EclipseLink as my ORM provider, connected to a MySQL DB and built with Maven. I'm not sure if any of this matters.....

When I deploy this application to Glassfish, the application works as expected.

The problem is, I've created a set of stand alone unit tests to run outside of Glassfish that aren't working correctly. I get the following error (I've edited the class names a little)

com.xyz.abc.services.persistence.entity.MyEntity cannot be cast to com.xyz.abc.services.persistence.entity.MyEntity

The object cannot be cast to a class of the same type? How can that be?

Here's a snippet of the code that is in error

Query q = entityManager.createNamedQuery("MyEntity.findAll");
List entityObjects = q.getResultList();
for (Object entityObject: entityObjects) {
   com.xyz.abc.services.persistence.entity.MyEntity entity = (com.xyz.abc.services.persistence.entity.MyEntity) entityObject;

Previously, I had this code that produced the same error:

CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(com.xyz.abc.services.persistence.entity.MyEntity.class));
List entityObjects = entityManager.createQuery(cq).getResultList();
for (Object entityObject: entityObjects) {
   com.xyz.abc.services.persistence.entity.MyEntity entity = (com.xyz.abc.services.persistence.entity.MyEntity) entityObject;

This code is question is the same that I have deployed to the server.

Here's the innermost exception if it helps

Caused by: java.lang.ClassCastException: com.xyz.abc.services.persistence.entity.MyEntity cannot be cast to com.xyz.abc.services.persistence.entity.MyEntity
    at com.xyz.abc.services.persistence.entity.factory.MyEntityFactory.createBeans(MyEntityFactory.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:115)
    ... 37 more

I'm guessing that there's some jar I'm using in Glassfish that is different than the ones I'm using in test. I've looked at all the jars I have listed as "provided" and am pretty sure they are all the same ones from Glassfish.

Let me know if you've seen this weird issue before, or any ideas for correcting it.

like image 544
Vinnie Avatar asked Apr 10 '10 21:04

Vinnie


2 Answers

This could also be a class loading problem. The same class definition, loaded by two different class loaders, is seen as different classes by the JVM.

You could try this to get information about the class loaders in the game:

Query q = entityManager.createNamedQuery("MyEntity.findAll");
List entityObjects = q.getResultList();

ClassLoader loader1 = 
    com.xyz.abc.services.persistence.entity.MyEntity.getClass().getClassLoader();
System.out.println("MyEntity's class loader is " + loader1);
for (Object entityObject: entityObjects) {
  ClassLoader loader2 = entityObject.getClass().getClassLoader();
  System.out.println("Class loader of entity " + entityObject + " is " + loader2);
}

Instead of System.out.println you could of course use calls to your preferred logging framework.

Here is a series of articles with more details about class loading.

like image 116
Péter Török Avatar answered Oct 07 '22 02:10

Péter Török


This clearly smells a ClassLoader issue (maybe due to the weaving needed by EclipseLink). Do you use the LoadTimeWeaver? Do you have any javaagent stuff configured? Does the problem occur on the command line under Maven? in your IDE? Please clarify.

like image 35
Pascal Thivent Avatar answered Oct 07 '22 01:10

Pascal Thivent