【问题标题】:ClassCastException when using javax.crypto使用 javax.crypto 时出现 ClassCastException
【发布时间】:2017-09-15 10:27:52
【问题描述】:

我正在实现一个 OSGI 包(使用 kura)来进行一些 AES 加密。 我直接在我的包中添加了第三个库 javax.crypto,这是清单:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: AES
Bundle-SymbolicName: org.eclipse.kura.AES
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: org.osgi.service.component;version="1.2.0",
 org.slf4j;version="1.7.21"
Service-Component: component.xml
Export-Package: org.eclipse.kura.AES.services
Bundle-ClassPath: .,
 lib/javax-crypto.jar

我在尝试解密时收到此错误:

java.lang.ClassCastException: com.sun.crypto.provider.AESCipher$General cannot be cast to javax.crypto.CipherSpi
        at javax.crypto.Cipher.getInstance(Cipher.java:166)
        at org.eclipse.kura.AES.services.AesServices.decrypt(AesServices.java:33)
        at org.eclipse.kura.AES.AES_Activator.activate(AES_Activator.java:19)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:235)
        at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
        at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:347)
        at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
        at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
        at org.eclipse.equinox.internal.ds.Resolver.buildNewlySatisfied(Resolver.java:473)
        at org.eclipse.equinox.internal.ds.Resolver.enableComponents(Resolver.java:217)
        at org.eclipse.equinox.internal.ds.SCRManager.performWork(SCRManager.java:816)
        at org.eclipse.equinox.internal.ds.SCRManager$QueuedJob.dispatch(SCRManager.java:783)
        at org.eclipse.equinox.internal.ds.WorkThread.run(WorkThread.java:89)
        at org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor.run(Executor.java:70)

我在我的树莓派上使用 openjdk。我尝试使用 oracle java,但仍然遇到同样的问题。要么我没有完全删除 openjdk,要么我无法确定其他原因。 有什么想法吗?

【问题讨论】:

    标签: java eclipse encryption osgi kura


    【解决方案1】:

    如果使用不同的捆绑包解决同一个类,您得到的错误是典型的。

    我怀疑你将包 javax.crypto 嵌入到你的包中。因此,您的捆绑包看到内部类 CipherSpi,而外部捆绑包看到 jdk 或其他捆绑包中的版本。

    解决方案是确保您仅从一个来源解析此类 api 包。在您的情况下,导入包javax.crypto 而不是嵌入javax-crypto.jar 可能就足够了。相反,您必须从 jdk 导出包或安装包含它的包。

    一般规则是永远不要嵌入可能通过您向外界公开的 api 可见的包。

    【讨论】:

      【解决方案2】:

      正如其他答案中提到的,您必须非常小心,避免通过您的 API 暴露内部包。在这种情况下,您提供的清单和堆栈跟踪指出了许多严重和致命的问题。

      提供的清单定义了以下 Import-Package 语句。

      Import-Package: org.osgi.service.component;version="1.2.0",
          org.slf4j;version="1.7.21"
      

      这立即令人怀疑有几个原因:

      1. 堆栈跟踪证明您想通过 javax.crypto 使用 AES,但不要导入包。相反,您已将 API 重新打包到包中,但没有重新打包实现。如果你想使用 JDK 实现,那么你需要和它共享一个类空间。

      2. 您导入声明式服务 API (org.osgi.service.component) 这样做是不寻常的,因为 DS 组件通常是 POJO。

      3. 您的导入都使用单一版本,而不是版本范围。在 OSGi 用语中,这意味着您的导入是从版本 X 到无穷大。这是一种反模式。

      我从这些问题推测您的清单是手工创建的。我强烈建议您使用工具 ((such as bnd) 来生成清单,因为它会阻止您犯许多此类错误。

      【讨论】:

        【解决方案3】:

        对于我的情况,添加后问题已解决,

        @PowerMockIgnore({"javax.crypto.*"}) 在班级级别

        Here you can find git link for issue

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-06
          • 2011-06-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多