简体   繁体   中英

Object is not an 'instanceof' it's own class

I'm trying to hunt down some issues with spring not expending a factoryBean. I've plugged into a debugger and proven that the failure is in this line of AbstraceBeanFactory:

if(!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
   return beanInstance;
}

specifically the "beanInstance instanceof FactoryBean" part is returning false when it should be true, resulting in my returning a factorybean back rather then the bean that the factory is suppose to construct.

My debugger clearly tells me that the the beanInstance is a org.springframework.beans.factory.config.PropertiesFactoryBean. When I tell eclipse to expand the class of bean I see it clearly implements FactoryBean

For further testing I went to expressions. Supposedly the expression:

beanInstance instanceof org.springframework.beans.factory.config.PropertiesFactoryBean

returns false. However beanInstance.getClass() returns

(org.springframework.beans.factory.config.PropertiesFactoryBean) (id=112)

It seems my VM is very confused about this class. I'm trying to figure out what would cause this confusion, and how I can fix it?

The most likely case seems to be confusion across multiple class loaders, but I haven't found any obvious examples. There should only be one implementation of PropertiesFactoryBean in my classpath.

What would cause instanceof to fail in this manner? How can I hunt down my root cause?

Incidentally, this is ultimately a tomcat instance I'm debugging, if it's relevant. Also, beanInstance is an instanceof Object, so intanceof does work properly sometimes.

ps. I had to type this by hand rather then copy/paste. Please assume any obvious naming mistakes are typos on my part.

edit: fixed the paren typo mentioned in comments. I figured I would do that. This code comes from Spring unmodified by me, so it's safe to assume the code itself is well written and functional, even if I did make a typo

If you have more than one webapp (or multiple versions of the same webapp in case you use Tomcat's hot deployment features) each webapp will have its own class loader, plus another class loader that loads all the stuff in Tomcat's lib folder (which is parent of the other classloaders).

So, if the interface you are checking is inside your war (or inside a lib deployed by your war), and you have multiple webapps deployed (probably some of them already undeployed but some references to objects stayed alive), assume it is a classloader problem (especially as you already confirmed that getClass() on the instance and Class.forName return different objects. Call getClassLoader on both class objects (Tomcat's class loaders have good toString methods) and probably you know which class loader / webapp they came from.

Probably short term fix is to move the jar containing the interface outside of the war and put it into tomcat's lib folder.

Long term fix is to track down the root cause and fix it, of course :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM