我遇到了一个可能与 Spring / 类加载器关系有关的问题。
我现在为这个问题的冗长道歉。
我有许多最初编写并打算在专用 JVM 中运行的遗留 Java 应用程序。我们在检查资源使用情况后决定,可以通过在单个 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 时日志文件的片段。
调试 [South Agent 1] (DefaultSingletonBeanRegistry.java:162) - 创建单例 bean 'MDDStructurPackager' 的共享实例
调试 [South Agent 1] (AbstractAutowireCapableBeanFactory.java:378) - 创建 bean 'MDDStructurPackager' 的实例
调试 [South Agent 1] (AbstractAutowireCapableBeanFactory.java:453) - 急切地缓存 bean 'MDDStructurPackager' 以允许解析潜在的循环引用
调试 [South Agent 1] (AbstractBeanFactory.java:213) - 返回单例 bean 'Logger' 的缓存实例
DEBUG [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 属性“类”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.lang.String] 的 bean 属性“colectionDate”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型为 [abc.def.mdd.msg.MDDComponent] 的 bean 属性“组件”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.lang.String] 的 bean 属性“fileType”
调试 [South Agent 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 属性“记录器”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.util.Map] 的 bean 属性“mapDelimiter”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到 [java.util.Map] 类型的 bean 属性“mapElement”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.lang.String] 的 bean 属性“namePackager”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.lang.String] 的 bean 属性“nameSpaceXMLSchema”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.lang.String] 的 bean 属性“nodeName”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.lang.String] 的 bean 属性“packageXMLSchema”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [abc.def.mdd.channel.ProcessingLayerListener] 的 bean 属性“processingLayerListener”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.lang.String] 的 bean 属性“领域”
调试 [South Agent 1] (CachedIntrospectionResults.java:267) - 找到类型 [java.lang.String] 的 bean 属性“statesObject”
DEBUG [South Agent 1] (AbstractAutowireCapableBeanFactory.java:406) - 完成创建 bean 'MDDStructurPackager' 的实例
调试 [South Agent 1] (DefaultSingletonBeanRegistry.java:162) - 创建单例 bean 'ListAlarmChannel' 的共享实例
调试 [South Agent 1] (AbstractAutowireCapableBeanFactory.java:378) - 创建 bean 'ListAlarmChannel' 的实例
调试 [South Agent 1] (AbstractAutowireCapableBeanFactory.java:453) - 急切地缓存 bean 'ListAlarmChannel' 以允许解析潜在的循环引用
调试 [South Agent 1] (DefaultSingletonBeanRegistry.java:162) - 创建单例 bean 'Jakarta' 的共享实例
调试 [South Agent 1] (AbstractAutowireCapableBeanFactory.java:378) - 创建 bean 'Jakarta' 的实例
调试 [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, int, java.lang.String, java.lang.String, com.citycorp.mdd.msg.MDDComponent )抛出
bean 'Jakarta' 的 java.lang.Exception ]:org.springframework.beans.factory.UnsatisfiedDependencyException:
创建文件 [/opt/app/ 中定义的名称为 'Jakarta' 的 bean 时出错abcdef/rt_dev/etc/HUAWEI_M2KJKT_ALARM.xml]:
通过构造函数参数表达的不满足的依赖关系,索引为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 组件)
public M2000AlarmChannel(String host, int port, String username, String password, 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 创建错误:
通过类型为 [java.lang.String] 的索引 0 的构造函数参数表示的不满足依赖关系:
无法将类型 [abc.def.mdd.msg.alarm.huawei.MDDPackagerAlarmM2000] 的构造函数参数值转换为所需类型 [java.lang.String]:
不清楚。在尝试确定适当的构造函数时,我不确定类型混淆的原因。问题可能与接口 MDDComponent 的加载有关。如果它被加载两次,在类加载器层次结构中不相关的不同类加载器,您可以想象与确定正确构造函数相关的问题。
任何感激地接受的想法,我都在抓住稻草。
谢谢布莱恩