Spring framework - class loader relationship

10,917

From the error message, it sounds like Spring is attempting to instantiate the object with this constructor:

public M2000AlarmChannel(String host, int port, String username, String password, MDDComponent componenet)

Looks like Spring is confused on which constructor to use, possibly because both constructors have a MDDComponent parameter (in a way, both constructors have this as their last parameter, I'm curious if that has something to do with the logic that Spring uses in determining which constructor to use. Anyway...).

According to the Spring manual, there are parameters you can add to the <constructor-arg> element to help the container resolve which constructor to use:

You can add "type":

<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg type="int" value="7500000"/>
  <constructor-arg type="java.lang.String" value="42"/>
</bean>

or you can add an index:

<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg index="0" value="7500000"/>
  <constructor-arg index="1" value="42"/>
</bean>

(You can probably specify both, if you really want to)

Adding one or both of these should help Spring resolve which constructor to use.

As a corollary, if this doesn't help, can you simply change the XML definition to pass in the parameters required for the other constructor, the one Spring is attempting to use?

BTW, it might make your question a lot more readable to use the quote tags within WMD.

Share:
10,917
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I am having a problem which is probably related to the Spring / class loader relationship.

    I will apologise for the verbosity of the question now.

    I have a number of legacy java applications which were originally written and intended to run within a dedicated JVM. We decided upon examination of the resource usage that efficiencies could be gained by running multiple applications within a single JVM. Within that context I wrote a container manager specifically designed for our environment which is capable of running each application within a container (or sandbox). The basis of this ability to isolate the containers is of course a custom class loader.

    All works well until we came across an application which uses the Spring framework. I have a Spring configuration file with fragments as below.

    <bean id="MDDStructurPackager" class="abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000">
        <property name="logger">
            <ref local="Logger"/>
        </property>
        <property name="realm">
            <value>unpack</value>
        </property>
    </bean>
    
    <bean id="Jakarta" class="abc.def.mdd.channel.corba.M2000AlarmChannel">
        <constructor-arg>
            <ref bean="MDDStructurPackager"/>
        </constructor-arg>
        <property name="interactionLayer">
            <ref local="MDDInteractionLayer"/>
        </property>
        <property name="logger">
            <ref local="Logger"/>
        </property>
        <property name="tempFile" value="/opt/app/abcdef/rt_dev/var/cache/dat/Huawei_M2000_Jakarta.dat"/>
        <property name="host" value="M2000Jakarta.ior"/>
        <property name="irpReference" value="clarity"/>
        <property name="name" value="M2000Jakarta"/>
        <property name="realm" value="Jakarta"/>
    	<property name="natAddress" value="99.999.99.9" />
    </bean>
    


    The following is a fragment from the log file as Spring is instantiating the beans.

    DEBUG [South Agent 1] (DefaultSingletonBeanRegistry.java:162) - Creating shared instance of singleton bean 'MDDStructurPackager'

    DEBUG [South Agent 1] (AbstractAutowireCapableBeanFactory.java:378) - Creating instance of bean 'MDDStructurPackager'

    DEBUG [South Agent 1] (AbstractAutowireCapableBeanFactory.java:453) - Eagerly caching bean 'MDDStructurPackager' to allow for resolving potential circular references

    DEBUG [South Agent 1] (AbstractBeanFactory.java:213) - Returning cached instance of singleton bean 'Logger'

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:242) - Getting BeanInfo for class [abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:258) - Caching PropertyDescriptors for class [abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'class' of type [java.lang.Class]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'colectionDate' of type [java.lang.String]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'component' of type [abc.def.mdd.msg.MDDComponent]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'fileType' of type [java.lang.String]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'listCommonWords' of type [java.util.ArrayList]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'listHeader' of type [java.util.ArrayList]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'logger' of type [abc.def.mdd.logger.Logger]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'mapDelimiter' of type [java.util.Map]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'mapElement' of type [java.util.Map]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'namePackager' of type [java.lang.String]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'nameSpaceXMLSchema' of type [java.lang.String]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'nodeName' of type [java.lang.String]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'packageXMLSchema' of type [java.lang.String]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'processingLayerListener' of type [abc.def.mdd.channel.ProcessingLayerListener]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'realm' of type [java.lang.String]

    DEBUG [South Agent 1] (CachedIntrospectionResults.java:267) - Found bean property 'statesObject' of type [java.lang.String]

    DEBUG [South Agent 1] (AbstractAutowireCapableBeanFactory.java:406) - Finished creating instance of bean 'MDDStructurPackager'

    DEBUG [South Agent 1] (DefaultSingletonBeanRegistry.java:162) - Creating shared instance of singleton bean 'ListAlarmChannel'

    DEBUG [South Agent 1] (AbstractAutowireCapableBeanFactory.java:378) - Creating instance of bean 'ListAlarmChannel'

    DEBUG [South Agent 1] (AbstractAutowireCapableBeanFactory.java:453) - Eagerly caching bean 'ListAlarmChannel' to allow for resolving potential circular references

    DEBUG [South Agent 1] (DefaultSingletonBeanRegistry.java:162) - Creating shared instance of singleton bean 'Jakarta'

    DEBUG [South Agent 1] (AbstractAutowireCapableBeanFactory.java:378) - Creating instance of bean 'Jakarta'

    DEBUG [South Agent 1] (AbstractBeanFactory.java:213) - Returning cached instance of singleton bean 'MDDStructurPackager'

    INFO: CORBA_HUAWEI_M2KJKT_ALARM (23447542): Added "/opt/app/abcdef/rt_dev/lib/logkit-1.2.jar" to the class path.

    INFO: CORBA_HUAWEI_M2KJKT_ALARM (23447542): Added "/opt/app/abcdef/rt_dev/lib/avalon-framework-4.1.5.jar" to the class path.

    INFO: CORBA_HUAWEI_M2KJKT_ALARM (23447542): Added "/opt/app/abcdef/rt_dev/lib/concurrent-1.3.2.jar" to the class path.

    INFO: CORBA_HUAWEI_M2KJKT_ALARM (23447542): Added "/opt/app/abcdef/rt_dev/lib/antlr-2.7.2.jar" to the class path.

    DEBUG [South Agent 1] (ConstructorResolver.java:195) -
    Ignoring constructor [public abc.def.mdd.channel.corba.M2000AlarmChannel(
    java.lang.String, int, java.lang.String, java.lang.String, com.citycorp.mdd.msg.MDDComponent ) throws java.lang.Exception ]
    of bean 'Jakarta': org.springframework.beans.factory.UnsatisfiedDependencyException:
    Error creating bean with name 'Jakarta' defined in file [/opt/app/abcdef/rt_dev/etc/HUAWEI_M2KJKT_ALARM.xml]:
    Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]:
    Could not convert constructor argument value of type [abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000] to required type [java.lang.String]:
    Failed to convert value of type [abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000] to required type [java.lang.String];
    nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000] to required type [java.lang.String]:
    no matching editors or conversion strategy found


    The following are the signatures of the constructors for the abc.def.mdd.channel.corba.M2000AlarmChannel class:

    public M2000AlarmChannel( MDDComponent componenet )

    public M2000AlarmChannel( String host, int port, String username, String password, MDDComponent componenet )

    The class abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000 implements MDDComponent (bean MDDStructurPackager).



    As you can see, Spring is instantiating some of the beans ie. MDDStructurPackager without problem.

    The problem is instantiating the 'Jakarta' bean.

    The implications of the lines:

    Error creating bean with name 'Jakarta' defined in file [/opt/app/abcdef/rt_dev/etc/HUAWEI_M2KJKT_ALARM.xml]:

    Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]:

    Could not convert constructor argument value of type [abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000] to required type [java.lang.String]:

    are not clear. I am not sure the reasons for the type confusion when attempting to determine the appropriate constructor. It is possible that the problem is associated with the loading of the interface MDDComponent. If it was loaded twice, by different class loaders which are not related in the class loader hierarchy you could imagine problems associated with determining the correct constructor.

    Any ideas gratefully received, I am grasping at straws.

    Thanks Bryan