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

如何在OSGI框架中在运行时动态加载Java类?,java,osgi,Java,Osgi,我们正在我们的项目中执行一个POC,其中我们发送基于SOAP的请求,并相应地从web服务获得一个SOAP响应。我们的目标是在我们的应用程序中利用spring框架提供的webservices模板(客户端API)。根据我们的架构,我们创建了一个OSGI兼容包(用于使用webservices模板API与web服务交互的代码),然后将其部署到ApacheFelix容器中。我们还在Felix容器中安装了所有依赖的OSGI兼容包,以便解决所有依赖关系 根据webservices模板,默认的Web服务消息发送

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

根据webservices模板,默认的Web服务消息发送者是HttpUrlConnectionMessageSender,它在运行时由类加载器动态加载。据我所知,我们得到以下异常,因为Felix容器无法从依赖的OSGI捆绑包(web服务捆绑包包含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)
据我所知,Felix容器无法使用存在于另一个包中的ClassUtils.forName()动态加载该类。我认为这是一个协作问题,当前包有一个不同的类加载器,而不是依赖包的类加载器

这个社区有人遇到过同样的例外吗?如果是,那么您采取了哪些步骤来解决运行时类依赖关系?请分享您对解决上述问题的想法/建议。如能快速回复,我们将不胜感激,并有助于我们的POC取得成功

提前感谢,,
Mridul Chopra

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

如果您使用Maven构建包,那么可以使用生成正确的清单信息

<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>

但是,上面的例子是当您使用Maven作为构建工具时。如果您使用的是Gradle,则可以使用来构建清单。或者,如果您可以使用Ant(顺便说一句,它也有一个Maven插件)。

您是否明确地将
org.springframework.ws.transport.http
添加到清单中?按名称加载类应该一点都不成问题,只需注意您不能使用字节码检查工具(bnd)来生成清单。正如artbristol所说,您需要自定义清单,并导入
org.springframework.ws.transport.http
。你能展示你的清单吗?在OSGi中,实际上不鼓励使用Class.forName()。我建议OP读一本关于OSGi的好书,比如《OSGi在行动》
<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>
<packaging>bundle</packaging>