【问题标题】:ClassCastException in karaf only after restart仅在重新启动后,karaf 中的 ClassCastException
【发布时间】:2018-03-12 05:41:37
【问题描述】:

我有两个版本为 05.18.000 的捆绑包 A,它使用捆绑包 C 中使用的 05.18.000 的 B。

我在 Bundle D 中使用了不同版本 05.20.000 的相同包 A 和 B。

Bundle A 正在尝试将具体类强制转换为接口。接口和实现类都在 Bundle B 中。

当我在运行时同时使用 C 和 D 时,它们工作正常。

但是当我重新启动 karaf 容器时,Bundle A 中会抛出一个类转换异常。

@Override
public String parse(DeviceMessageEnvelope deviceMessageEnvelope) {

    String result = "NO RESULTS";
    LOGGER.debug("HL7MinaServerParserControllerBase.parse called.");
    try {
        HL7MinaServerCommunicationObject commObject = getHL7MinaServerCommunicationObject();

        commObject.initObject((MinaServerCom) getDeviceCom(), deviceMessageEnvelope, getParser());

        LOGGER.debug("HL7MinaServerParserControllerBase: Attempted to connect device com");
        boolean connected = getDeviceCom().connect();

        if (connected) {
            while (commObject.isRunning()) {
                LOGGER.debug("HL7MinaServerParserControllerBase.parse : In Loop isRunning() : " + commObject.isRunning());
                Thread.sleep(getWaitTime());
            }
            LOGGER.debug("HL7MinaServerParserControllerBase.parse : Exit from while commObject.isRunning()");
            result = commObject.getResult();
        }
    } catch (InterruptedException e) {
        LOGGER.warn("HL7MinaServerParserControllerBase.parse :  Error in HL7MinaServerParserControllerBase", e);
    } catch (CommunicationException e) {
        LOGGER.warn("HL7MinaServerParserControllerBase.parse :  Error in HL7MinaServerParserControllerBase", e);
    } catch (MinaSupportConfigurationException e) {
        LOGGER.warn("HL7MinaServerParserControllerBase.parse :  Error in HL7MinaServerParserControllerBase", e);
    } finally {
        try {
            getDeviceCom().release();
        } catch (CommunicationException e) {
            LOGGER.warn("HL7MinaServerParserControllerBase : Error trying to release the com", e);
        }
    }

    return result;
}

以下是错误:

[2018-03-01 22:46:38.287] [Device Id: 10237 Device Name : WA_CMS_GW] ERROR com.company.driver.factory.DeviceTask                            com.company.drvs.sdk.mina.com.server.types.MinaServerComImpl cannot be cast to com.company.drvs.sdk.mina.com.server.MinaServerCom
java.lang.ClassCastException: com.company.drvs.sdk.mina.com.server.types.MinaServerComImpl cannot be cast to com.company.drvs.sdk.mina.com.server.MinaServerCom
    at com.company.drvs.sdk.mina.com.server.types.parser.HL7MinaServerParserControllerBase.parse(HL7MinaServerParserControllerBase.java:43)[411:com.company.drvs.sdk.company-sdk-mina-support-hl7:5.20.0]
    at com.company.drvs.welchallyn.nce.parser.NCEParserController.getResult(NCEParserController.java:57)[412:com.company.drvs.welchallyn-nce.core:1.0.1]
    at com.company.drvs.welchallyn.nce.parser.NCEParserController.parse(NCEParserController.java:45)[412:com.company.drvs.welchallyn-nce.core:1.0.1]
    at com.company.drvs.welchallyn.nce.driver.Driver.execute(Driver.java:67)[412:com.company.drvs.welchallyn-nce.core:1.0.1]
    at com.company.driver.factory.DeviceTask.execute(DeviceTask.java:46)[321:com.company.dxc.DriverHarness:1.10.1.GA]
    at com.company.task.CycleTaskHarness.run(CycleTaskHarness.java:88)[312:com.company.dxc.TaskRunner:1.10.1.GA]
    at java.lang.Thread.run(Thread.java:748)[:1.8.0_161]
[2018-03-01 22:46:38.287] [Device Id: 10237 Device Name : WA_CMS_GW] WARN  com.company.task.CycleTaskHarness                                Task retry: Device Id: 10237 Device Name : WA_CMS_GW, com.company.task.TaskException: com.company.drvs.sdk.mina.com.server.types.MinaServerComImpl cannot be cast to com.company.drvs.sdk.mina.com.server.MinaServerCom
[2018-03-01 22:46:38.287] [Device Id: 10237 Device Name : WA_CMS_GW] ERROR com.company.task.CycleTaskHarness                                Task error:
com.company.task.TaskException: com.company.drvs.sdk.mina.com.server.types.MinaServerComImpl cannot be cast to com.company.drvs.sdk.mina.com.server.MinaServerCom
    at com.company.driver.factory.DeviceTask.execute(DeviceTask.java:54)[321:com.company.dxc.DriverHarness:1.10.1.GA]
    at com.company.task.CycleTaskHarness.run(CycleTaskHarness.java:88)[312:com.company.dxc.TaskRunner:1.10.1.GA]
    at java.lang.Thread.run(Thread.java:748)[:1.8.0_161]
Caused by: java.lang.ClassCastException: com.company.drvs.sdk.mina.com.server.types.MinaServerComImpl cannot be cast to com.company.drvs.sdk.mina.com.server.MinaServerCom
    at com.company.drvs.sdk.mina.com.server.types.parser.HL7MinaServerParserControllerBase.parse(HL7MinaServerParserControllerBase.java:43)[411:com.company.drvs.sdk.company-sdk-mina-support-hl7:5.20.0]
    at com.company.drvs.welchallyn.nce.parser.NCEParserController.getResult(NCEParserController.java:57)[412:com.company.drvs.welchallyn-nce.core:1.0.1]
    at com.company.drvs.welchallyn.nce.parser.NCEParserController.parse(NCEParserController.java:45)[412:com.company.drvs.welchallyn-nce.core:1.0.1]
    at com.company.drvs.welchallyn.nce.driver.Driver.execute(Driver.java:67)[412:com.company.drvs.welchallyn-nce.core:1.0.1]
    at com.company.driver.factory.DeviceTask.execute(DeviceTask.java:46)[321:com.company.dxc.DriverHarness:1.10.1.GA]
    ... 2 more

company-sdk-mina-support-hl7:5.20.0 是提到的 Bundle A。

MinaServerComImpl 和 MinaServerCom 是 Bundle B 中的实现和接口。

错误发生在这一行

commObject.initObject((MinaServerCom) getDeviceCom(), deviceMessageEnvelope, getParser());

MinsServerComImpl 通过 spring 注入,getDeviceCom() 返回 MinaServerComImpl 的实例。

请帮忙。谢谢。

【问题讨论】:

标签: java osgi apache-karaf osgi-bundle karaf


【解决方案1】:

通常的原因是同一个类有多个定义。

在 Java 中,类的标识是其完全限定名称定义它的ClassLoader 的组合。如果两个类加载器定义了一个类——即使在磁盘上使用相同的类数据(以字节为单位)——它们在 JVM 中将被视为不同的类。从这些类定义之一继承的任何子类都不会被视为另一个定义的子类型。

在您的情况下,您可能已将 MinaServerCom 类复制到多个捆绑包中。而是确保定义仅在一个捆绑包中,应从其中导出其包。其他包应该导入该包。

【讨论】:

  • MinaServerCom 接口仅在一个捆绑包中。但是我的 karaf 中有该捆绑包的多个版本。那么,我是否必须在两个捆绑包(不同版本)中导出该包?谢谢你的帮助。尼尔·巴特利特。
  • 多个版本的包意味着您确实有多个包的导出。您需要确保实例化 MinaServerComImpl 类的包和接收该对象并尝试将其强制转换为 MinaServerCom 的包从同一位置导入包含 MinaServerCom 的包。确保您导出的包是版本化的,并且导入的版本范围正确。
【解决方案2】:

ClassCastException 的出现是因为一个类的任何对象都不能转换为另一个类,只是因为它们不是“父子”关系。

正如你所说..这条线有问题..

commObject.initObject((MinaServerCom) getDeviceCom(), deviceMessageEnvelope, getParser());

这里getDeviceCom() 返回MinsServerComImpl 的对象,您尝试将其转换为MinaServerCom。那么请确定这两个类之间是否存在Is-A 关系。

应该是

class MinsServerComImpl extends MinaServerCom

class MinsServerComImpl implements MinaServerCom

【讨论】:

  • MinaServerComImpl 确实实现了 MinaServerCom。问题与 OSGI 有关。当我删除数据文件夹并重新启动 karaf 容器时。没有抛出 ClassCastException。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 2015-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2018-11-30
相关资源
最近更新 更多