我正在实施一个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,或者还有另一个我无法识别的原因。 有什么想法吗?
答案 0 :(得分:1)
如果使用不同的捆绑包解析相同的类,则会出现错误。
我怀疑您将包javax.crypto
嵌入到捆绑包中。所以你的bundle看到了内部类CipherSpi,而外面的bundle看到了jdk或另一个bundle的版本。
解决方案是确保您只从一个来源解析此类api包。在您的情况下,导入包javax.crypto
并且不嵌入javax-crypto.jar
可能就足够了。相反,您必须从jdk导出包或安装包含它的包。
一般规则是永远不要嵌入可能通过暴露给外界的api看不见的包。
答案 1 :(得分:1)
正如其他答案所述,您必须非常小心,以避免通过API公开内部包。在这种情况下,您提供的清单和堆栈跟踪指向了许多严重且致命的问题。
提供的清单定义了以下Import-Package语句。
Import-Package: org.osgi.service.component;version="1.2.0",
org.slf4j;version="1.7.21"
由于以下几个原因,这立即引起怀疑:
堆栈跟踪证明您希望通过javax.crypto使用AES,但不要导入包。相反,您已在捆绑包中重新打包API,但不是实现。如果要使用JDK实现,则需要与它共享类空间。
您导入Declarative Services API(org.osgi.service.component)这是不常见的,因为DS组件通常是POJO。
您的导入全部使用单个版本,而不是版本范围。在OSGi用语中,这意味着您的导入从版本X到无穷大。这是一种反模式。
我猜测你的清单是手工创建的。我强烈建议您使用工具((such as bnd)生成清单,因为它会阻止您犯下许多错误。
答案 2 :(得分:0)