gpt4 book ai didi

java - 如何在 OSGI 框架的运行时动态加载 Java 类?

转载 作者:搜寻专家 更新时间:2023-11-01 03:55:13 25 4
gpt4 key购买 nike

我们正在我们的项目中执行 POC,其中我们发送基于 SOAP 的请求并相应地从 Web 服务获取 SOAP 响应。我们的目标是在我们的应用程序中利用 spring 框架提供的 web 服务模板(客户端 API)。根据我们的架构,我们创建了一个 OSGI 兼容包(用于我们使用 web 服务模板 API 与 web 服务交互的代码),然后将其部署到 Apache Felix 容器中。我们还在 Felix 容器中安装了所有依赖的 OSGI 兼容包,以便解决所有依赖项。

根据 web 服务模板,默认的 Web 服务消息发送器是 HttpUrlConnectionMessageSender,它在运行时由类加载器动态加载。据我了解,我们收到以下异常是因为 Felix 容器无法从依赖的 OSGI 包(网络服务包包含 HttpUrlConnectionMessageSender)加载类。请参阅下面的异常日志。

* org.springframework.beans.factory.BeanInitializationException: Could not find default strategy class for interface [org.springframework.ws.transport.WebServiceMessageSender]; nested exception is java.lang.ClassNotFoundException:org.springframework.ws.transport.http.HttpUrlConnectionMessageSender at  org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:126)

at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:90)

at org.springframework.ws.client.core.WebServiceTemplate.initMessageSenders(WebServiceTemplate.java:320)

at org.springframework.ws.client.core.WebServiceTemplate.initDefaultStrategies(WebServiceTemplate.java:306)

at org.springframework.ws.client.core.WebServiceTemplate.<init>(WebServiceTemplate.java:143)

at test.soapservice.service.SOAPServiceImpl.<init>(SOAPServiceImpl.java:40)

at test.soapservice.service.SOAPServiceActivator.start(SOAPServiceActivator.java:17)

at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641)

at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977)

at org.apache.felix.framework.Felix.startBundle(Felix.java:1895)

at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944)

at org.apache.felix.gogo.command.Basic.start(Basic.java:729)

引起:java.lang.ClassNotFoundException:org.springframework.ws.transport.http.HttpUrlConnectionMessageSender

    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:188)

at java.lang.ClassLoader.loadClass(ClassLoader.java:307)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)

at java.lang.ClassLoader.loadClass(ClassLoader.java:252)

at org.springframework.util.ClassUtils.forName(ClassUtils.java:211)

at org.springframework.util.ClassUtils.forName(ClassUtils.java:164)

at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:114)

据我了解,Felix 容器无法使用存在于另一个包中的 ClassUtils.forName() 动态加载类。我认为这是一个协作问题,当前包具有不同的类加载器,而不是依赖包的类加载器。

这个社区有人遇到过同样的异常吗?如果是,那么您采取了哪些步骤来解决运行时类依赖性问题?请分享您的想法/建议以解决上述问题。我们将不胜感激,并可能帮助我们使 POC 取得成功。

提前致谢,Mridul 乔普拉

最佳答案

Class.forName() 形式的类加载在任何 OSGi 容器中都不是问题。您的问题是 MANIFEST.MF 文件不包含正确的导入声明。一个包应该导出 org.springframework.ws.transport 包,而你的包应该导入相同的包。

如果您使用 Maven 来构建您的包,您可以使用 Felix Bundle Plugin生成正确的 list 信息。

<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Private-Package>my.private.package.*</Private-Package>
</instructions>
</configuration>
</plugin>
</plugins>

这应该检查您的代码并为不在您的“私有(private)”包范围内的任何内容添加导入。要完成这项工作,您应该做的另一件事是将 packaging 类型设置为 bundle

<packaging>bundle</packaging>

但是,上面的示例是您使用 Maven 作为构建工具时的情况。如果您使用的是 Gradle,则可以使用 Gradle OSGi plugin建立 list 。或者,如果使用 Ant,您可以使用 SpringSource Bundlor project (顺便说一句,它还有一个 Maven 插件)。

关于java - 如何在 OSGI 框架的运行时动态加载 Java 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9715118/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com