11 Replies Latest reply on Sep 7, 2012 7:05 AM by thomas.diesler

    Creating OSGI Bundle using Template or Archtype

    djchapm

      Hi,

       

      Very new to OSGI and JBoss AS7.  I've done all the quickstarts and few hours of googling.  I haven't come across any great tutorials on how people are creating their OSGI bundles using eclipse or JBoss Developer Studio.

       

      Are there any templates (for General "Plug-in" Project type) or preferably maven archtypes defined for creating the latest JBoss Osgi bundles for deployment in JBoss AS 7.1?

       

      Templates all seem to use eclipse osgi or older versions of dependent libraries.  The Quickstart helloworld OSGI uses org.osgi.core but I was thinking there would be something like org.jboss.osgi for use with jboss osgi that comes with AS 7.

       

      I'm investigating abiltiy to do side-by-side deployments/upgrades in a production system without restarting the application.  Fairly large project - ~300 portlets, 80 web/bus services.

       

      Thanks!

        • 1. Re: Creating OSGI Bundle using Template or Archtype
          djchapm

          Update.... Keep in mind I'm total beginner struggling through.... The problem with everyone elses examples is that they run embedded, or arquillian, or are bundled together with a bunch of stuff I don't need or at least I don't think I need.  My goal here is to come up with a decent eclipse/JBoss Dev Studio 'project' format that may be used for several different teams working on individual modules in parallel, and separately.  I also want to be able to seamlessly rebuild/redeploy/restart via maven without having to touch my running application.

           

          So I started with the jboss-as-helloworld-osgi maven quickstart project which does a decent job - it allows me to deploy to my server through maven, and builds/packages correctly using felix maven plugin.

          Plugins:

            org.jboss.as.plugins.jboss-as-maven-plugin

             org.apache.felix.maven-bundle-plugin.

           

          mvn clean package jboss-as:deploy

           

          Then I have no clue what i'm doing with blueprint but blueprint appears to be a bit of a best-practice.  I created src/main/resources/OSGI-INF/blueprint/config.xml file that I copied from somewhere and it seemed to get picked up and processed right away.  So I guess that is how you convert an osgi bundle to blueprint.

           

          Last thing I did (in getting above to work) was add the following capabilities that weren't in the standalone.xml file out of the box under the osgi subsystem configuration:

                          <capability name="org.apache.aries:org.apache.aries.util:0.4" startlevel="2"/>

                          <capability name="org.apache.aries.proxy:org.apache.aries.proxy:0.4" startlevel="2"/>

                          <capability name="org.apache.aries.blueprint:org.apache.aries.blueprint:0.4" startlevel="2"/>

           

          Things deploy and I'm able to see it in my jboss admin console and start the bundle successfully. 

           

          When I do the jboss-as:deploy, it replaces the current osgi module with the new one, but it ends up in a not-started state.  Anyone know how to get jboss-as:deploy, or some other maven plugin , to automatically start the module after I deploy it?

           

          Then if anyone knows how I can connect to my module service from a non-osgi web app, running in jboss as7, that would be great. I tried doing an

          @Resource

          BundleContext context;

           

          But this fails with ClassDefNotFound error perfectly described by https://issues.jboss.org/browse/AS7-5146 which appears will not be fixed until JBoss AS 7.2 comes out in a few months.

           

          Anyone know of a workaround?

           

          Also - if anyone wants to clarify anything I may have stumbled upon that isn't correct here, please do so.

           

          Thanks,

            Dan C.

          • 2. Re: Creating OSGI Bundle using Template or Archtype
            thomas.diesler

            Dan,

             

            lets do this one by one.

             

            #1 blueprint

             

            Blueprint adds a level of complexity that you might want to cut out of the equasion if you are just trying basic stuff. I suggest you get familiar with the notion of dynamic services through ServiceTracker and BundleActivator. When you wnat to do stuff declaratively, look at Declarative Services (DS). Folks who like Blueprint usually come from a Spring background. IMHO, it is mandatory to have a good understanding of the underlying priciples before you can successfully deply Blueprint bundles. Also have a look at the differences.

             

            #2 Bundle redeployment

             

            This is something that is indeed not well documented. Please monitor/vote on

             

            • [AS7-5430] Add doc + test coverage for Bundle redeployment

             

            #3 @Resource BundleContext context

             

            The general functionality has been supported for a long time. Have a look at the test cases in AS7 or from the relevant jbosgi release.

             

            Having said that I encourage you to use the latest jboss-as/master mainly because the last AS7 community release 7.1.1.Final (09-Mar-2012) has happend so long ago and OSGi integration has improved much since. I bet, when you have done your ground work you will have a 7.2 release available anyway.

             

            I also personally have a strong interest in seeing feedback on the latest - ideally before it gets released.

            • 3. Re: Creating OSGI Bundle using Template or Archtype
              djchapm

              Hi, Thanks so much for your help.  I have so many questions - it's awesome to have your attention on this since 80% of the reading I've done going back to 2009 has been authored by you.

               

              Some background....

              I have years of experience in Spring.  Reason I was looking at Blueprint was because it seems that it's better at managing dependencies, making it easier for clients.

              Perhaps DS is just as good for our purposes.  I'll look into it but feel a bit stubborn at this point trying to close the loop with BP. 

              Using Redhat JBoss 7.1.2.Final

                Since we're on Redhat licensed version, I'm guessing their JBoss 7.2 release will be about a quarter behind the community release.  May not be an option for us.

               

              I believe jbosgi 1.1.2 is what is in the above JBoss version.  I have submitted a Redhat ticket to find out in case they are wrapping things, and to get help on my @Resource injection.

               

              So regarding general functionality link you provided, you're saying that the @Resource injection should work fine since 2011?  Then I must not have my capabilities set properly or default jboss modules do not contain necessary classes?  I used a provided dependency.  And I'm still new to how subsystems and capabilities are reflected in my war runtime classpath.  I see a lot of talk about manuall modifying the Manifest, but with the felix-mavin-plugin and the jboss-as-maven-plugin I was thinking the Manifest would take care of itself.

               

              I have run the tests that come with jbosgi download... and they run fine on an embedded server. But so many examples and interesting wiring of dependencies etc - I can't figure out just how it's working in terms of lowest common denominator.  Perhaps if each test was its own self contained/lean project I could figure it out - but from new guy perspective it seems like many different implementations bundled together.

               

              By the way - As a quick means of proving this out I've simply stuck the @Resource into a hello world rest service in the EE Web App.... wouldn't think that would matter, but here is the stack snippits:

               

               

               

              18:34:25,570 INFO [org.jboss.weld.ClassLoading] (MSC service thread 1-4) catching:

              org.jboss.weld.resources.spi.ResourceLoadingException : Error loading class com.titan.rest.TitanEchoRESTService

              at org.jboss.weld.resources.ClassTransformer.loadClass(

              ClassTransformer.java:167 ) [weld-core-1.1.8.Final-redhat-1.jar:1.1.8.Final-redhat-1]

              ...

               

               

               

               

              Caused by: java.lang.NoClassDefFoundError: Lorg/osgi/framework/BundleContext;

              at java.lang.Class.getDeclaredFields0(Native Method ) [rt.jar:1.6.0_21]

              at java.lang.Class.privateGetDeclaredFields(Class.java:2291) [rt.jar:1.6.0_21]

              at java.lang.Class.getDeclaredFields(Class.java:1743

              ) [rt.jar:1.6.0_21]

              at org.jboss.weld.util.reflection.SecureReflections$4.work(

              SecureReflections.java:105 ) [weld-core-1.1.8.Final-redhat-1.jar:1.1.8.Final-redhat-1]

              ...

               

               

               

              Caused by:

              java.lang.ClassNotFoundException : org.osgi.framework.BundleContext from [Module "deployment.TitanEE-ear.ear.TitanEE-web-0.0.1-SNAPSHOT.war:main" from Service Module Loader]

              at org.jboss.modules.ModuleClassLoader.findClass(

              ModuleClassLoader.java:190 )

              at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(

              ConcurrentClassLoader.java:468 )

              • 4. Re: Creating OSGI Bundle using Template or Archtype
                thomas.diesler

                https://github.com/jbossas/jboss-as/tree/7.1.2.Final/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/osgi/ejb3

                 

                @Stateless
                @LocalBean
                public class SimpleStatelessSessionBean implements Echo {
                
                    @Resource
                    BundleContext context;
                ...
                }
                

                 

                Your deployment needs to have an explicit dependency on module org.osgi.core

                 

                 @Deployment(name = EJB3_DEPLOYMENT_NAME, managed = false, testable = false)
                 public static JavaArchive getTestArchive() {
                     final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, EJB3_DEPLOYMENT_NAME);
                     archive.addClass(SimpleStatelessSessionBean.class);
                     archive.setManifest(new Asset() {
                         public InputStream openStream() {
                             OSGiManifestBuilder builder = OSGiManifestBuilder.newInstance();
                             builder.addManifestHeader("Dependencies", "org.osgi.core,deployment.ejb3-osgi-target:0.0.0");
                             return builder.openStream();
                         }
                     });
                     return archive;
                 }
                
                • 5. Re: Creating OSGI Bundle using Template or Archtype
                  djchapm

                  Progress... I was able to get past the Class exceptions above based on your advice.  I had seen similar advice before, but lacking the Maven expertise - needed to do a bit of training today.

                  I updated my maven build plugin as follows:

                      <plugin>
                      <artifactId>maven-war-plugin</artifactId>
                      <version>2.1.1</version>
                      <configuration>
                       <failOnMissingWebXml>false</failOnMissingWebXml>
                       <archive>
                        <manifestEntries>
                         <Dependencies>org.osgi.core,org.jboss.osgi.framework,deployment.TitanBPBundle:0.1</Dependencies>
                        </manifestEntries>
                       </archive>
                      </configuration>
                     </plugin>

                   

                  My blueprint bundle is called "TitanBPBundle" and version deployed is 0.1.0.

                   

                  You can see it deployed on server startup (set osgi subdeployment to eager):

                  21:30:32,042 INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) JBAS015876: Starting deployment of "TitanBPBundle-0.1.jar"

                  21:30:32,448 INFO [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011001: Bundle installed: org.apache.aries.blueprint:0.4.0

                  21:30:34,589 INFO [org.jboss.osgi.framework] (MSC service thread 1-2) JBOSGI011001: Bundle installed: TitanBPBundle:0.1.0

                   

                  Then when my war goes to deploy, it is reading manifest headers and not liking something.. I am not understanding this error message:

                  21:30:38,308 INFO  [org.jboss.as.controller] (Controller Boot Thread) JBAS014774: Service status report
                  JBAS014775:    New missing/unsatisfied dependencies:
                        service jbosgi.integration.PersistentBundlesHandler.COMPLETE (missing) dependents: [service jbosgi.framework.INIT]
                        service jboss.module.spec.service."deployment.TitanBPBundle"."0.1" (missing) dependents: [service jboss.module.service."deployment.TitanEE.ear.TitanEE-ejb-0.0.1-SNAPSHOT.jar"
                  .main, service jboss.module.service."deployment.TitanEE.ear.TitanEE-web-0.0.1-SNAPSHOT.war".main, service jboss.module.service."deployment.TitanEE.ear".main]
                        service jboss.osgi.as.initial.deployments.COMPLETE (missing) dependents: [service jbosgi.integration.PersistentBundlesHandler]

                  A little cryptic, any help?  I tried variations on the name and version of my bundle.... Couldn't satisfy dependency.

                  • 6. Re: Creating OSGI Bundle using Template or Archtype
                    thomas.diesler

                    A ModuleIdentifier has a 'name' and 'slot' part. Unlinke OSGi the slot is not a version but a string that sorts in lexicographical order

                     

                    0.1 != 0.1.0

                     

                    If you define an explicit dependency for a non-osgi module (i.e. TitanEE.ear.TitanEE-web-0.0.1-SNAPSHOT.war has a dependency on deployment.TitanBPBundle)

                    You can either not specify the slot or name the slot explicitly.

                     

                    Starting from 7.2.0.Alpha1 (current master), it should be sufficient to put both the WAR and the Bundle into an EAR and not define the dependency at all.

                     

                    The issue with missing dependencies for PersistentBundlesHandler.COMPLETE is related to server restart, which adds another layer of complexity.

                    To avoid that you can remove the data/osgi-store directory before you restart the server. We can look at server restart issues when the basic deployments work.

                    • 7. Re: Creating OSGI Bundle using Template or Archtype
                      rssole

                      I could only add that this is proven to work where by "proven" I precisely mean... "proven on JBoss 7.1.0 and 7.1.1".

                       

                      It is crucial that you match versions you specify in manifest of your deployments... thus forget names of you artifacts like: TitanBPBundle-0.1.jar
                      For OSGi one of essential things is of course manifest and instructions within it.

                       

                      E.g for my war build I've put:

                      <Dependencies>org.osgi.core,deployment.bundle-context-provider:1.0.0.SNAPSHOT</Dependencies>

                       

                      Where bundle-context-provider is OSGi bundle deployed to OSGi subsystem.

                      For bundle, I've put the following bundle plugin instruction: <Bundle-Version>${project.version}</Bundle-Version> where (in this example) version is exactly 1.0.0.SNAPSHOT

                       

                      Then, make sure you put the correct version into manifest of your war.

                       

                      Hope this helps

                      • 8. Re: Creating OSGI Bundle using Template or Archtype
                        djchapm

                        Hi Thomas,

                         

                        So my war depends on the osgi bundle due to manifest.  The bundle is deployed and started.  The war file is deployed and started. 

                        The edits to my war maven plugin are as follows:

                           <plugin>
                            <artifactId>maven-war-plugin</artifactId>
                            <version>2.1.1</version>
                            <configuration>
                             <failOnMissingWebXml>false</failOnMissingWebXml>
                             <archive>
                              <manifestEntries>
                               <Dependencies>org.osgi.core,org.jboss.osgi.framework,deployment.TitanBPBundle:0.1.0.SNAPSHOT</Dependencies>
                              </manifestEntries>
                             </archive>
                            </configuration>
                           </plugin>

                        So it seems both are deployed and happy, but I am still unable to perforrm

                        @Resource

                        BundleContext ctx;

                         

                        in my web application.  I get a jndi error that the item doesn't exist.:

                         

                             Error looking up java:comp/env/org.jboss.tools.examples.rest.MemberResourceRESTService/ctx in JNDI

                         

                        Thanks for your help.  When this is completed I'll write up something here a little more consolidated and clear if it helps for the blueprint non-osgi -> osgi scenario using maven+ide etc.

                        • 9. Re: Creating OSGI Bundle using Template or Archtype
                          thomas.diesler

                          @Resource

                          BundleContext ctx;

                           

                          is supposed to work in any EE component - also in a plain war without module depenencies on a bundle.

                          Can you please verify tht first. If adding a module dependency on a bundle breaks that functionality it would be a bug an we create a jira for it.

                          • 10. Re: Creating OSGI Bundle using Template or Archtype
                            djchapm

                            Followed these steps with a Clean JBs 7.1.2.Final (redhat) server running standalone-full.xml.

                             

                            1. New "Java EE Web Project"

                            2. comes w/ some basics like rest, mvc, session bean, Deploys and works.

                            3. Added @Resource BundleContext ctx to the session bean and update class imports.

                            4. Deploy Failure, Exception that boils down to:

                             

                            Caused by: java.lang.ClassNotFoundException

                            : org.osgi.framework.BundleContext from [Module "deployment.JWebEETest.war:main" from Service Module Loader]

                             

                            5. Add following to build plugin "maven-war-plugin" 2.1.1 configuration:

                            <archive>

                             

                              <manifestEntries>

                             

                                <Dependencies>org.osgi.core,org.jboss.osgi.framework</Dependencies>

                             

                              </manifestEntries>

                             

                            </archive>

                             

                            6. Deployed.  Crap it worked.

                            7. Added print statement...

                               Context: BundleContext[system.bundle:0.0.0]

                            8. Deployed TitanBPBundle with no references.

                            9. Restart Server, Start App and Test again.

                            - Worked

                            10.  Start TitanBPBundle using Console and test again.

                            - Worked.  what's up with this.

                            11. Add reference from app to TitanBPBundle in manifest, retest.

                            - Dang, worked again.  how frustrating.  Trying to figure out difference....

                            12. Add a "Runtime" dependency on my module to the web app pom.

                            - Works.

                            13.  Add @Resource BundleContext ctx; to the example REST service

                            - Aha - I guess this has been my problem all along.

                            Caused by:

                            javax.naming.NameNotFoundException

                            : env/org.jboss.tools.examples.rest.MemberResourceRESTService/ctx -- service jboss.naming.context.java.module.JWebE

                            ETest.JWebEETest.env."org.jboss.tools.examples.rest.MemberResourceRESTService".ctx

                             

                            Okay - so what tipped me off was uncertainty when you said "any EE component".  So any access to BundleContext should be done only from something like an EJB or something?

                             

                            What are the limits here?  I figured the annotation scanner would scan everything in the classpath for @Resource and inject where needed.

                             

                            Please explain.

                             

                            Thanks,

                              Dan C.

                            • 11. Re: Creating OSGI Bundle using Template or Archtype
                              thomas.diesler

                              I can confirm that there is an issue

                              https://issues.jboss.org/browse/AS7-5507