Issue Details (XML | Word | Printable)

Key: SPR-4059
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Juergen Hoeller
Reporter: Jasper Rosenberg
Votes: 0
Watchers: 3
Operations

If you were logged in you would be able to see more operations.
Spring Framework

Class cast exception in AbstractBeanDefinition.getBeanClassName()

Created: 07/Nov/07 07:07 AM   Updated: 14/Oct/08 06:09 AM   Resolved: 14/Oct/08 06:09 AM
Component/s: SpringCORE
Affects Version/s: 2.0.5
Fix Version/s: 2.5.6, 2.0.9

Time Tracking:
Not Specified

Environment: Tomcat, Java 1.6.0_02 (1.6 is missing from dropdown), struts 2

Virtual Machine: Sun JVM - 1.5


 Description  « Hide

This is the worst possible kind of bug report, and so I apologize in advance, but it has only appeared once in production and was not reproducible. On top of that, the actual case that generates the error seems to be pretty much impossible. The cast exception you see below, is in this Spring code:

/**

  • Return the class name of the wrapped bean.
    */
    public String getBeanClassName()
    Unknown macro: { if (this.beanClass instanceof Class) { return ((Class) this.beanClass).getName(); } else { return (String) this.beanClass; } }

As you can see the method checks if the field is a Class, and casts to it if it is. However, in this case below, for some reason, it tried to cast it to a String even though it was a Class. I don't know if this is some strange classloading issue, a JVM bug, or what, but I figured you would want to at least see it.

Stack trace:
------------------------------
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityModel' defined in class path resource [applicationContext-siteresources.xml]: Initialization of bean failed; nested exception is java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.String Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.String
at org.springframework.beans.factory.support.AbstractBeanDefinition.getBeanClassName(AbstractBeanDefinition.java:311)
at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:327)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1066)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:349)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:270)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByName(AbstractAutowireCapableBeanFactory.java:881)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:829)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:424)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:270)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:733)
at com.cargurus.site.interceptor.ModelInterceptor.intercept(ModelInterceptor.java:75)



Juergen Hoeller added a comment - 07/Nov/07 11:42 AM

This is almost certainly a class loading issue. It's pretty strange that even the Class class cannot be cast to Class, though!

In any case, I don't see what we could do about this in Spring's code... other than adding an explicit assertion maybe.

Juergen


Jasper Rosenberg added a comment - 07/Nov/07 05:22 PM

Thanks for taking a look. It is very strange, particularly since it isn't reproducible, and we aren't doing anything funky, just deploying a standard war containing the spring jar in tomcat 5. Ah well, hopefully it was a one off hiccup...


Juergen Hoeller added a comment - 08/Nov/07 03:49 PM

OK, closing this as not reproducible for the time being...

Juergen


Mark St. John added a comment - 15/Nov/07 02:12 PM

We saw this same issue today. Any idea what could be causing this?

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultBiddingStrategy' defined in class path resource [bidEngineBeans.xml]: Initialization of bean failed; nested exception is java.lang.ClassCastException: java.lang.Class
Caused by:
java.lang.ClassCastException: java.lang.Class
at org.springframework.beans.factory.support.AbstractBeanDefinition.getBeanClassName(AbstractBeanDefinition.java:298)
at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:313)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:912)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:346)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:246)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:128)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:955)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:729)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:416)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:642)


Joe Littlejohn added a comment - 14/Dec/07 10:22 AM

Did anyone find a workaround for this?? We've been seeing this exact issue.

Spring version:
2.0.6

Runtime environment:
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build pap32dev-20060511
(SR2))
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 AIX ppc-32 j9vmap3223-20060504
(JIT enabled)
J9VM - 20060501_06428_bHdSMR
JIT - 20060428_1800_r8
GC - 20060501_AA)
JCL - 20060511a

Stack trace:
java.lang.ClassCastException: java.lang.Class incompatible with java.lang.String
at org.springframework.beans.factory.support.AbstractBeanDefinition.getBeanClassName(AbstractBeanDefinition.java:311)
at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:327)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1075)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:346)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:270)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)


Juergen Hoeller added a comment - 14/Oct/08 06:07 AM

As discussed in SPR-5213, this seems to be a visibility issue in a multi-threading environment. The basic issue has been fixed in Spring 2.5.1 / 2.0.8 and higher, so please upgrade accordingly. I'll close a remaining corner case for Spring 2.5.6, which is what I'm reopening this issue for.

Juergen


Juergen Hoeller added a comment - 14/Oct/08 06:09 AM

getBeanClassName() and getBeanClass() use a temporary snapshot variable now in order to prevent the corner case of the variable type changing inbetween the instanceof check and the actual cast. However, for the typical case, the volatile variable introduced in Spring 2.5.1 / 2.0.8 should get you pretty far already.

Juergen