OSGi Bundle status is not Active (CQ5 Maven Project) WHY?

五迷三道 提交于 2019-12-11 10:55:07

问题


I know that when the status of a bundle in CQ is installed, there are dependencies and that is why the bundle cannot be "Active".

I am using a Jersey Client v 2.17 in a CQ5 Service, so I need the Jersey Core Client Jar. I added the dependency in the /bundle/pom.xml. My bundle successfully compiles and deploys BUT NEVER TURNS ACTIVE

I added the Jersey Client Jar in Felix Console manually, by doing this my bundle got activated but the Jersey Client Jar is not active so I keep getting ClassNotFoundError as there are transitive dependencies in the Jersey Client Jar as well.

I tried the following:

  1. Manually tried resolving dependencies by adding Jars in Felix Console. I failed. The Loop never ends(Transitive Dependencies)
  2. I tried some tweaking by changing the manifest of the Jersey Core Client Jar, I added DynamicImport-Package: *. This tricks the OSGi conatainer, that at runtime it will find the Jars. This has worked for me in the past but now it needs some classes that aren't present.(Both Jars the Jersey Client and My Bundle become active BUT I get class NOT found Error as the classes are actually not there no matter how much I try to fool the OSgi Conatainer)Failed.
  3. So tried another thing, I added all the dependent Jars in the /bundle/pom.xml. As I am using Maven I thought this would solve the issue but my bundle is still Installed NOT Active

My Third step was a miserable failure. What good is Maven to you when you are installing all the Jars MANUALLY in Felix console anyways ?!!

What should I do ?


回答1:


First of all, Maven only helps you with build-time dependencies, and Maven dependencies are at the jar level. When installing bundles into an OSGi container, you have to deal with run-time dependencies, which are at the package level.

So there is a mismatch between build-time and run-time, as dependencies work differently. You could argue that Maven is not that good a match at all, which is why at least some people that do a lot of OSGi applications have switched to Bnd/Bndtools and a command-line Gradle build.

Back to your problem. You are running into missing dependencies at runtime. Your bundle is importing packages that are not exported by any bundle. To fix that, you can use one of two strategies:

  1. You can embed all the dependencies you need inside your bundle. Effectively here you'd need to embed the Jersey Client (and transitively all dependencies it needs). You would not expose any of those to other bundles, all code would end up in your bundle.
  2. You can install all dependencies you need as bundles. That means you need to transitively find all packages you need to run the Jersey Client. There are some tools available to help you with that. Maven is not one of them.

Hope this helps. It might not be what you were hoping to hear.




回答2:


@Marcel Offermans answer is correct, you should install all dependencies that your bundle needs to run, if they are too many, you are not managing them properly. As how to easily deploy them, CQ5 has a nice way of doing it.

In CQ5 you normally install applications through packages, which are nothing but a zip file, which contains both content content to be copied into the JCR Repository and any Java bundle your application might need.

You may have noticed that normally in CQ5 applications you have 2 maven modules,(tip: use their maven archetypes to create your projects ) one for content and one for java code (could be more than one, or none). What happens when you build the content package is that any bundle that shared the same groupID is embedded into the package automatically, but it you are using any bundle that is not already installed, you should configure it so it is embedded as well.

This example configuration is taken from the package documentation. It should give you and idea of how to add any dependency you need to deploy to the OSGi container along with your application:

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

as a final tip, use the OSGi dependency finder in http://localhost:4502/system/console/depfinder to locate any dependency you might need. It might be already installed in your instance without you noticing.

If what you want is to embed a jar inside a bundle, so it is not exposed, you can do that with the maven-bundle-plugin (I'm assume you are using it since it's the standard for AEM development), using the Embed-Dependency command:

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

See the documentation for more options of how to use this command




回答3:


I solved it. Both @Marcel Offermans and @santiagozky you are correct in your own way. But there are somethings that I found out through my experience, I'd like to share.

1)MAVEN Bundle Plugin- This Maven Profile Helps you download all your dependencies(including transitive ones till to last level), Converts them automatically to OSGi format and places it in you target folder. So one can upload them in OSGi Console Directly. Follow this Link

Note: Just use bundleall instead of wrap see my pom entry

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

Use command: mvn -Pcreate-osgi-bundles-from-dependencies bundle:bundleall

2) Method Mentiond by @santiagozky puts the bundle in install folder BUT IT IS NOT IN OSGi FORMAT, so the bundle doesn't start. Any inputs on this @santiagozky ?



来源:https://stackoverflow.com/questions/29912636/osgi-bundle-status-is-not-active-cq5-maven-project-why

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!