6 Replies Latest reply on Jan 24, 2013 3:56 AM by komododave

    Receiving "Failed to read artifact descriptor" for a FAB deployed into ESB

    komododave

      We've deployed a standard JAR as a FAB into a Fuse ESB container running within a Fabric.

       

      We have a custom profile X extending the fuse-esb-full profile. The fabric-bundle feature in installed on X, and we've used Fuse Management Console to add our FAB mvn URI to X.

       

      The container provisions ok, but we can't see any sign of activity from the FAB. We've not done much to change the JAR project before this deployment, since your documentation suggests little is necessary. All we had to change for successful provisioning was a dependency from activemq-all to mq-fabric, since this is the version supplied by the ESB container.

       

      The JAR itself has a main class with the standard public static void main(..) defined. I've specified the main class in the project's POM in case this was needed by the FAB deployment mechanism.

       

      We have log4j configured in the project to point to a filesystem location accessible from the ESB container. However, no log appears. Since it's possible this could be caused by improper log4j configuration, we added a few lines of code at the start of the application's main method to create a file and write test output to it. Again, this doesn't happen.

       

      Connecting to the ESB container and running osgi:list | grep -i 'our-app' displays:

       

      com.anon.our-app(0.0.1.SNAPSHOT)

       

      I'm not sure whether this status of Active indicates the bundle has been started or not. So I tried running fab:start 90 to try starting it. This produces the following error:

       

      Error executing command: Failed to read artifact descriptor for com.anon:our-app:jar:0.0.1-SNAPSHOT

       

      I've tried defining a simple BundleActivator implementation in the app in case this was an unmentioned requirement for FAB deployment, but it's made no difference.

       

      Do you have any idea why we receive this error, or why the bundle seems lifeless?

        • 1. Re: Receiving "Failed to read artifact descriptor" for a FAB deployed into ESB
          iocanel

          Fab is not supposed to bootstrap a jas using the MainClass.

           

          The proper mechanism for bootstraping is having an Activator class and Activator metadata inside your MANIFEST.MF.

           

          Now regarding logging. Fuse ESB provides centralized logging configuration via pax-logging and you should better rely to it.

          • 2. Re: Receiving "Failed to read artifact descriptor" for a FAB deployed into ESB
            komododave

            This is confusing and disappointing for us, because according to the  FAB docs the procedure is designed specifically to support deployment of JAR applications with little to no modification, and that page doesn't mention even once a requirement for a BundleActivator definition.

             

            Can you please clarify - are you suggesting that to deploy a JAR application in an ESB container we must define a BundleActivator for it? If so, must we use the maven-bundle-plugin to generate manifest data and then deploy as a FAB to Fabric?

             

            Where's Stan Lewis when you need him...

            • 3. Re: Receiving "Failed to read artifact descriptor" for a FAB deployed into ESB
              iocanel

              I verify that for plain jar application you will need to add an Activator class and header. Spring and Blueprint applications can still work without it (if they the contain a META-INF/spring/.xml or an OSGI-INF/blueprint/.xml descriptor respectively). You can find spring/blueprint examples at: https://github.com/fusesource/fuse/tree/master/examples

               

              To further clarify:

               

              Fab provides a way of converting a jar to an OSGi bundle by reusing its maven metadata. Moreover it provides a common classloader model between your build tool and your container. Bootstraping the application is out of the scope of FAB. Fab will just convert the application into a bundle. The bootstraping of the bundle will be left to the container. The container currently supports bootstraping by bundle activator, spring / blueprint descriptors.

               

              Using the maven-bundle-plugin to generate the manifest is a good idea, but its not a requirement (meaning that you can provide a manifest or generate one with the tool of your choice).

              • 4. Re: Receiving "Failed to read artifact descriptor" for a FAB deployed into ESB
                komododave

                Thank you for taking time to write this very clear response iocanel. It's a pleasure to finally understand what was going wrong.

                 

                We'll create a BundleActivator and generate the manifest headers as you've prescribed.

                • 5. Re: Receiving "Failed to read artifact descriptor" for a FAB deployed into ESB
                  davsclaus

                  Hopefully some day this becomes easy in OSGi / Karaf, but just having some annotation on a java bean, that the container discovers and uses for lifecycle callbacks.

                   

                  Maybe even standards such as CDI when that becomes workable in OSGi / Karaf. This is an ongoing work, also at Apache Camel, in the camel-cdi component.

                   

                  I am pushing for easier development and deployment on Karaf, for end users who dont know / dont care / dont have the time / or really dont need to go down learning all the myriad's and inner details of deploying to an OSGi container.

                   

                  FAB is certainly a big step in the right direction.

                  • 6. Re: Receiving "Failed to read artifact descriptor" for a FAB deployed into ESB
                    komododave

                    It's good to know you're seeking to further automate creation of an OSGi bundle, davsclaus. It seems straight forward enough to replicate what's defined in the public static void main(...) in BundleActivator#start so that a custom BundleActivator needn't be defined. That's assuming all cleanup occurs within the application already, so an empty BundleActivator#stop can be defined.