首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用javax.crypto时的ClassCastException

使用javax.crypto时的ClassCastException
EN

Stack Overflow用户
提问于 2017-04-19 17:24:02
回答 3查看 1.1K关注 0票数 0

我正在实现一个OSGI bundle (使用kura)来做一些AES加密。我直接在捆绑包中添加了第三个库javax.crypto,清单如下:

代码语言:javascript
复制
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

当我尝试解密时,我得到了这个错误:

代码语言:javascript
复制
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)

我在我的raspberry pi上使用openjdk。我尝试使用oracle java,但仍然遇到同样的问题。要么是我没有完全删除openjdk,要么是我无法确定的另一个原因。有什么想法吗?

EN

回答 3

Stack Overflow用户

发布于 2017-04-19 17:45:35

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

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

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

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

票数 1
EN

Stack Overflow用户

发布于 2017-04-20 00:32:21

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

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

代码语言:javascript
复制
Import-Package: org.osgi.service.component;version="1.2.0",
    org.slf4j;version="1.7.21"

由于以下几个原因,这立即变得可疑:

  1. 堆栈跟踪证明您希望通过javax.crypto使用AES,但不导入包。相反,您已经将API重新打包到捆绑包中,而不是一个实现。如果你想使用JDK实现,那么你需要和它共享一个类空间。
  2. 你导入声明式服务应用程序接口(org.osgi.service.component),这样做是不寻常的,因为DS组件通常是POJO。
  3. 您导入的所有内容都使用单一版本,而不是版本范围。用OSGi的话说,这意味着您的导入是从版本X一直到无限大的。这是一个反模式。

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

票数 1
EN

Stack Overflow用户

发布于 2020-12-15 23:42:11

由于我的案例问题在添加后得到了解决,

类级别的@PowerMockIgnore({"javax.crypto.*"})

Here you can find git link for issue

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43491542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档