【问题标题】:OSGi Bundle status is not Active (CQ5 Maven Project) WHY?OSGi Bundle 状态不活跃(CQ5 Maven 项目) 为什么?
【发布时间】:2015-04-28 07:10:53
【问题描述】:

我知道,当 CQ 中的 bundle 状态为安装时,存在依赖关系,这就是 bundle 不能为“Active”的原因。

我在 CQ5 服务中使用 Jersey Client v 2.17,所以我需要 Jersey Core Client Jar。我在 /bundle/pom.xml 中添加了依赖项。我的包成功编译和部署但从未激活

我在 Felix 控制台中手动添加了 Jersey 客户端 Jar,通过这样做我的包被激活但 Jersey 客户端 Jar 未激活,所以我不断收到 ClassNotFoundError也是 Jersey Client Jar 中的传递依赖项。

我尝试了以下方法:

  1. 手动尝试通过在 Felix 控制台中添加 Jars 来解决依赖关系。 我失败了。循环永远不会结束(传递依赖)
  2. 尝试通过更改 Jersey Core 客户端 Jar 的清单进行一些调整,我添加了 DynamicImport-Package: *。这欺骗了 OSGi 容器,在运行时它会找到罐子。这在过去对我有用,但现在它需要一些不存在的类。(Jersey Client 和 My Bundle 都变得活跃但我得到了 class NOT found 错误,因为类实际上 不存在 无论如何 我试图愚弄 OSgi 容器失败
  3. 所以尝试了另一件事,我在 /bundle/pom.xml 中添加了所有依赖的 Jar。当我使用 Maven 时,我认为这可以解决问题,但我的包仍然是 Installed 而不是 Active

我的第三步是惨败。无论如何,当您在 Felix 控制台中手动安装所有 Jars 时,Maven 对您有什么好处?!!

我该怎么办?

【问题讨论】:

    标签: java maven osgi aem


    【解决方案1】:

    首先,Maven 仅帮助您处理构建时依赖项,而 Maven 依赖项位于 jar 级别。将 bundle 安装到 OSGi 容器中时,您必须处理包级别的运行时依赖项。

    因此构建时和运行时之间存在不匹配,因为依赖项的工作方式不同。您可能会争辩说 Maven 根本不是那么好匹配,这就是为什么至少有一些做很多 OSGi 应用程序的人已经切换到 Bnd/Bndtools 和命令行 Gradle 构建。

    回到你的问题。您在运行时遇到缺少的依赖项。您的捆绑包正在导入任何捆绑包都未导出的包。要解决此问题,您可以使用以下两种策略之一:

    1. 您可以在包中嵌入所有需要的依赖项。实际上,您需要嵌入 Jersey 客户端(以及它需要的所有依赖项)。您不会将其中任何一个暴露给其他包,所有代码最终都会在您的包中。
    2. 您可以将所需的所有依赖项安装为捆绑包。这意味着您需要传递地找到运行 Jersey 客户端所需的所有包。有一些工具可以帮助您。 Maven 不是其中之一。

    希望这会有所帮助。这可能不是您希望听到的。

    【讨论】:

    • 我不会真正将第一个建议视为解决方案,因为它有效地覆盖了 OSGi 的动态依赖机制。
    • 再一次,模块化系统的目标之一是创建具有低耦合性的模块,除非代码被许多不同的模块重用,否则嵌入它可能会好得多。我绝对不会完全丢弃它。在这种情况下,如果使用此 Jersey 客户端的唯一模块是发布者创建的模块,或者如果他想让他的模块尽可能易于安装,那么减少外部依赖项是有意义的。与往常一样,我们的世界并非非黑即白。 :)
    • @MarcelOffermans 我该如何做第 1 步?请详述。我什至将我的客户端 API 从 Jersey 切换到 Apache。我的包在运行时变得活跃和threw java.lang.NoSuchMethodError: org.apache.http.config.ConnectionConfig.getBufferSize()I。请帮助这真的很烦人。
    【解决方案2】:

    @Marcel Offermans 的回答是正确的,你应该安装你的包需要运行的所有依赖项,如果它们太多,你没有正确管理它们。至于如何轻松部署它们,CQ5 有一个很好的方法。

    在 CQ5 中,您通常通过包安装应用程序,这些包只是一个 zip 文件,其中包含要复制到 JCR 存储库的内容内容和您的应用程序可能需要的任何 Java 包。

    您可能已经注意到,通常在 CQ5 应用程序中,您有 2 个 maven 模块,(提示:使用他们的 maven archetypes 来创建您的项目)一个用于内容,一个用于 java 代码(可能不止一个,也可能没有)。 当您构建内容包时,任何共享相同 groupID 的包都会自动嵌入到包中,但如果您使用的是尚未安装的任何包,您应该对其进行配置,使其也被嵌入。

    此示例配置取自package documentation。它应该让您了解如何添加您需要与应用程序一起部署到 OSGi 容器的任何依赖项:

     <plugin>
           <groupId>com.day.jcr.vault</groupId>
            <artifactId>content-package-maven-plugin</artifactId>
            <version>0.0.20</version>
            <extensions>true</extensions>
            <configuration>
            <filters>
                <filter>
                <root>/apps/myapp</root>
                </filter>
             </filters>
             <embeddeds>
                <embedded>
                <groupId>org.apache.sling</groupId>
                <artifactId>org.apache.sling.jcr.jackrabbit.usermanager</artifactId>
                <target>/apps/myproject/install</target>
                 </embedded>
             </embeddeds>
             </configuration>
        </plugin>
    

    作为最后的提示,使用http://localhost:4502/system/console/depfinder 中的 OSGi 依赖项查找器来查找您可能需要的任何依赖项。它可能已经安装在您的实例中而您没有注意到。

    如果您想要在包中嵌入一个 jar,使其不暴露,您可以使用 maven-bundle-plugin(我假设您正在使用它,因为它是 AEM 开发的标准) ,使用Embed-Dependency 命令:

    <Embed-Dependency>artifactId</Embed-Dependency>
    

    有关如何使用此命令的更多选项,请参阅the documentation

    【讨论】:

    • :: 这看起来是个很棒的方法,但是包不是 OSGi 格式的,所以包没有被 OSGi 容器拾取,你能帮我解决这个问题吗?我如何将依赖项嵌入到我的包中,这样它就不会暴露给任何其他 jar。?
    • 如果 jar 是你的,你应该把它做成一个 bundle。如果这不是一个选项,有时在 servicemix 项目中有许多流行库的可用捆绑版本。如果这也不可能,您将不得不使用 BND 将其包装成一个捆绑包
    • 我知道如何将 jar 转换为 OSGi 格式。见我上面的回答。但是像这样将它们放在安装文件夹中可以使 jar 也可用于其他包。我不想要那个。我所要求的在 CQ 中是否可行?
    • 如果是这种情况,那么您需要按照@Marcel Offermans 的建议将 jar 直接嵌入到您的包中。
    • 我该怎么做?我以前没有听说过这个,也没有看过你所说的任何教程!能否请您详细说明。
    【解决方案3】:

    我解决了。 @Marcel Offermans 和 @santiagozky 都以自己的方式正确。但是我通过我的经验发现了一些东西,我想分享一下。

    1)MAVEN Bundle Plugin- 此 Maven 配置文件可帮助您下载所有依赖项(包括传递的依赖项直到上一级),自动将它们转换为 OSGi 格式并将其放置在您的目标文件夹中。 所以可以直接在 OSGi 控制台中上传它们。关注这个Link

    注意:只需使用 bundleall 而不是 wrap 查看我的 pom 条目

    <!-- My Profile to Resolve Tansitive Dependencies -->
            <profile>
                      <id>create-osgi-bundles-from-dependencies</id>      
                      <build>
                            <plugins>
                                 <plugin>
                                       <groupId>org.apache.felix</groupId>
                                       <artifactId>maven-bundle-plugin</artifactId>
                                       <version>2.0.1</version>
                                       <extensions>true</extensions>
                                       <executions>
                                             <execution>
                                                   <id>wrap-my-dependency</id>
                                                   <goals>
                                                         <goal>bundleall</goal>
                                                   </goals>
                                                   <configuration>
                                                         <wrapImportPackage>;</wrapImportPackage>
                                                   </configuration>
                                             </execution>
                                       </executions>
                                 </plugin>
                            </plugins>
                      </build>   
                </profile>
            <!-- transitive dependenceis ENds -->
    

    使用命令:mvn -Pcreate-osgi-bundles-from-dependencies bundle:bundleall

    2) @santiagozky 提到的方法将捆绑包放在安装文件夹中但它不是 OSGi 格式,因此捆绑包不会启动。对此@santiagozky 有任何意见吗?

    【讨论】:

    • @santiagozky 您的扩展答案似乎更有希望。我先试试看。因为我的工作,但有点像一个黑客。
    猜你喜欢
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 2013-02-10
    • 2011-05-21
    • 1970-01-01
    • 2012-04-20
    相关资源
    最近更新 更多