Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error when replacing Spring Bean with a subclass

I have a working call to a web service; we implement the logic to call the web service with a Spring bean configured with annotation:

@ManagedResource(objectName = "bean:name=XServiceMBean")
@Service("xService")
public class XServiceImpl implements XService
{
// working code here
}

For testing purposes, I would like to extend this class and inject the subclass instead of this one, so I made:

@ManagedResource(objectName = "bean:name=XServiceMBean")
@Service("xService")
public class XServiceImplTest extends XServiceImpl
{
// working code here
}

and commented out the two annotation lines from the superclass.

Spring doesn't like it. When I run, I get:

Error creating bean with name 'xService':Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'xService' must be of type [com.hsc.correspondence.rules.XService], but was actually of type [com.hsc.correspondence.rules.impl.XServiceImplTest]

I tried it again putting an explicit "implements XService on my subclass, with the same result.

Am I doing something illegal in Spring? The original XServiceImpl has a number of @Resource annotations in it; I didn't think that would matter, I expected them to get injected just like they did before.

Is there a way to do what I want to do, which is have a test class with absolute minimized changes to the original? (I would consider configuring in XML except I don't make those decisions in the project I'm on, but I didn't think it would matter to what I'm trying to do.


additional puzzlement: the error message says "Bean named 'xService' must be of type ...XService, but was actually of type XServiceImplTest". But XServiceImplTest implements XService, just like XServiceImpl does.

additional puzzlement #2: I copied the entire XServiceImpl to the class XServiceImplTest, commented out the annotations from XServiceImpl, and cleaned and rebuilt and ran. Got the same result. Now the only difference between the two classes is their class names. It gets stranger and stranger. Can anyone suggest why Spring might care what the class name is?

like image 431
arcy Avatar asked Dec 21 '25 16:12

arcy


1 Answers

I see three possible causes for this:

  1. Your code doesn't look like the one you are showing, and the inheritance hierarchy isn't there. (Since you say you directly added the interface this is unlikely, but you might want to double check your imports)

  2. There is old compiled classes on the classpath. If there is an old compiled version lying around of XServiceImplTest this might get picked up. Try a clean of all class/target folders.

  3. You are running in some kind of classloader issue, and the interface gets loaded by a different classloader than the test implementation. Put a breakpoint on the line where the execption is thrown and inspect the classloaders of the various classes involved.

    You can do that by doing x.getClass().getClassLoader() on any instance of interest. In a plain vanilla application this will return the same instance for all x. In OSGI applications and web application you might get different ClassLoaders. The type of the ClassLoader and their parent relation ship should give some hint about what is going on.

like image 109
Jens Schauder Avatar answered Dec 23 '25 06:12

Jens Schauder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!