java - Spring框架-类加载器关系

标签 java spring classloader

我有一个问题,可能与Spring /类加载器的关系有关。

我现在对这个问题的冗长表示歉意。

我有许多旧的Java应用程序,它们最初是编写的,旨在在专用JVM中运行。我们决定检查资源使用情况,即可以通过在单个JVM中运行多个应用程序来提高效率。在这种情况下,我写了一个专门针对我们的环境设计的容器管理器,它能够在容器(或沙箱)中运行每个应用程序。这种隔离容器的能力的基础当然是定制类加载器。

在我们遇到使用Spring框架的应用程序之前,所有方法都可以正常工作。我有一个带有片段的Spring配置文件,如下所示。

<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>

以下是Spring实例化bean时的日志文件片段。

DEBUG [South Agent 1](DefaultSingletonBeanRegistry.java:162)-创建单例bean'MDDStructurPackager'的共享实例

DEBUG [South Agent 1](AbstractAutowireCapableBeanFactory.java:378)-创建bean'MDDStructurPackager'的实例

DEBUG [South Agent 1](AbstractAutowireCapableBeanFactory.java:453)-急速缓存bean'MDDStructurPackager'以允许解析潜在的循环引用

DEBUG [South Agent 1](AbstractBeanFactory.java:213)-返回单例bean'Logger'的缓存实例

调试[South Agent 1](CachedIntrospectionResults.java:242)-为类[abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000]获取BeanInfo

DEBUG [South Agent 1](CachedIntrospectionResults.java:258)-缓存类[abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000]的PropertyDescriptors

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.Class]的bean属性'class'

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.String]的bean属性'colectionDate'

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[abc.def.mdd.msg.MDDComponent]的bean属性'component'

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.String]的bean属性'fileType'

调试[南部代理1](CachedIntrospectionResults.java:267)-找到类型为[java.util.ArrayList]的bean属性'listCommonWords'

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[java.util.ArrayList]的bean属性'listHeader'

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[abc.def.mdd.logger.Logger]的bean属性'logger'。

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[java.util.Map]的bean属性'mapDelimiter'

调试[南部代理1](CachedIntrospectionResults.java:267)-找到类型为[java.util.Map]的bean属性'mapElement'

调试[南部代理1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.String]的bean属性'namePackager'

调试[南部代理1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.String]的bean属性'nameSpaceXMLSchema'

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.String]的bean属性'nodeName'

调试[南部代理1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.String]的bean属性'packageXMLSchema'

调试[南部代理1](CachedIntrospectionResults.java:267)-找到类型为[abc.def.mdd.channel.ProcessingLayerListener]的bean属性'processingLayerListener'

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.String]的bean属性'realm'

调试[South Agent 1](CachedIntrospectionResults.java:267)-找到类型为[java.lang.String]的bean属性'statesObject'

DEBUG [South Agent 1](AbstractAutowireCapableBeanFactory.java:406)-完成创建豆“MDDStructurPackager”的实例

DEBUG [South Agent 1](DefaultSingletonBeanRegistry.java:162)-创建单例bean'ListAlarmChannel'的共享实例

DEBUG [South Agent 1](AbstractAutowireCapableBeanFactory.java:378)-创建bean'ListAlarmChannel'的实例

DEBUG [South Agent 1](AbstractAutowireCapableBeanFactory.java:453)-急速缓存bean'ListAlarmChannel'以允许解析潜在的循环引用

DEBUG [South Agent 1](DefaultSingletonBeanRegistry.java:162)-创建单例bean'Jakarta'的共享实例

DEBUG [South Agent 1](AbstractAutowireCapableBeanFactory.java:378)-创建bean'Jakarta'的实例

DEBUG [South Agent 1](AbstractBeanFactory.java:213)-返回单例bean'MDDStructurPackager'的缓存实例

信息:CORBA_HUAWEI_M2KJKT_ALARM(23447542):在类路径中添加了“/opt/app/abcdef/rt_dev/lib/logkit-1.2.jar”。

信息:CORBA_HUAWEI_M2KJKT_ALARM(23447542):在类路径中添加了“/opt/app/abcdef/rt_dev/lib/avalon-framework-4.1.5.jar”。

信息:CORBA_HUAWEI_M2KJKT_ALARM(23447542):在类路径中添加了“/opt/app/abcdef/rt_dev/lib/concurrent-1.3.2.jar”。

信息:CORBA_HUAWEI_M2KJKT_ALARM(23447542):在类路径中添加了“/opt/app/abcdef/rt_dev/lib/antlr-2.7.2.jar”。

调试[South Agent 1](ConstructorResolver.java:195)-
忽略构造函数[public abc.def.mdd.channel.corba.M2000AlarmChannel(
java.lang.String,
诠释
java.lang.String,
java.lang.String,
com.citycorp.mdd.msg.MDDComponent
)抛出java.lang.Exception
]
'Jakarta'的类型:org.springframework.beans.factory.UnsatisfiedDependencyException:
创建文件[/opt/app/abcdef/rt_dev/etc/HUAWEI_M2KJKT_ALARM.xml]中定义的名称为'Jakarta'的bean时出错:
通过索引为0的[java.lang.String]类型的构造函数参数表示的不满意依赖项:
无法将类型[abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000]的构造函数参数值转换为所需的类型[java.lang.String]:
无法将类型[abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000]的值转换为所需的类型[java.lang.String];
嵌套的异常是java.lang.IllegalArgumentException:
无法将类型[abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000]的值转换为所需的类型[java.lang.String]:
找不到匹配的编辑器或转换策略

以下是abc.def.mdd.channel.corba.M2000AlarmChannel类的构造函数的签名:

公共M2000AlarmChannel(MDDComponent componenet)

公共M2000AlarmChannel(字符串主机,int端口,字符串用户名,字符串密码,MDDComponent componenet)

类abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000实现MDDComponent(bean MDDStructurPackager)。



如您所见,Spring正在实例化一些bean即。 MDDStructurPackager没有问题。

问题在于实例化“Jakarta” bean。

这些行的含义:

创建文件[/opt/app/abcdef/rt_dev/etc/HUAWEI_M2KJKT_ALARM.xml]中定义的名称为'Jakarta'的bean时出错:

通过索引为0的[java.lang.String]类型的构造函数参数表示的不满意依赖项:

无法将类型[abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000]的构造函数参数值转换为所需的类型[java.lang.String]:

不清楚。我不确定尝试确定适当的构造方法时类型混淆的原因。问题可能与接口MDDComponent的加载有关。如果两次被不同的类加载器加载,这些类加载器在类加载器层次结构中不相关,则可以想象与确定正确的构造函数有关的问题。

任何感激之情,我都牢牢抓住。

谢谢
布赖恩

最佳答案

从错误消息中,听起来像Spring尝试使用此构造函数实例化该对象:

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

看起来Spring对要使用哪个构造函数感到困惑,可能是因为两个构造函数都具有MDDComponent参数(以某种方式,两个构造函数都将此参数作为最后一个参数,我很好奇这是否与Spring使用的逻辑有关。确定要使用哪个构造函数。

根据Spring manual,可以将一些参数添加到<constructor-arg>元素中,以帮助容器解析要使用的构造函数:

您可以添加“类型”:
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg type="int" value="7500000"/>
  <constructor-arg type="java.lang.String" value="42"/>
</bean>

或者您可以添加索引:
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg index="0" value="7500000"/>
  <constructor-arg index="1" value="42"/>
</bean>

(如果确实要,您可以同时指定两者)

添加这两者之一或两者都应有助于Spring解析要使用的构造函数。

作为必然结果,如果这样做没有帮助,您是否可以简单地更改XML定义以传递另一个Spring正在尝试使用的构造函数所需的参数?

顺便说一句,使用WMD中的quote标记可能会使您的问题更易读。

关于java - Spring框架-类加载器关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/554963/

相关文章:

java - Feign 客户端在 Spring boot/Crawler4j 应用程序中总是抛出空指针异常

java - 监控和分析 java 中的类加载器

java - 从提取的 war 文件动态加载外部类

java - 动态加载jar文件并使用xml创建spring beans

java - 如何在 Spring/OpenJPA 1 中重新创建更新行锁定的选择

java - 持久化关联实体时违反 Hibernate 约束

java - QuickSort:这个实现有什么问题

用于偏态正态与泊松和指数的逆累积分布的 Java 数学包

java - 使用 Eclipse(JAVA) 的 JMagick 自动化

java - 如何在 Netbeans 6.8 中为 JSF 1.2 中的 facelets 启用代码完成?