1 2 3 Previous Next 36 Replies Latest reply on Sep 13, 2011 1:05 PM by Dan Sirbu

    META-INF/services for module extensions - question/issue

    Dan Sirbu Newbie

      Hi,

       

         I have create a module testmod that is stored into /home/jboss7/modules/com/mycomp/testmod/main with the appropriate jar file. The META-INF/services contains the necessary defition for a java service to be loaded.

       

         I also create a testextension module that is stored into /home/jboss7/modules/com/mycomp/testextension/main. In testextenstion module.xml I add the dependency towards the testmod in order to have the classpath set properly.

       

         I have 2 situations:

       

      (a) If I set the testmod as a global module in the standalone.xml, the the META-INF/services class defined there is loaded and available to a war file since when I deploy the WAR file via the ServletContextListner I can bootstrap the spi.

       

      (b) If I define the textextension in standalone.xml (and remove the global definition), then try to bootstrap the testmod from the testextension, then the META-INF/services is no longer loaded and the SPI is not working anylonger.

       

         I am wondering if my test is valid. And if yes, what would be the reason that the testmod META-INF/services is not available to the textextension module. In the dependency definiton I tried : services="export" export="true" for example ( I try "import" too) but no luck.

       

         Looking more carefully at the META-INF/services of the testextension module, there is one needed by jboss in order to kickstart the extension. And that get's called. So what I did, is to add the services from the testmod within the testextension -> still not luck.

         And that sounds similar with : "https://issues.jboss.org/browse/AS7-4" - which tough looks to be old and addressed. I am using the GA version.

       

        Any tips ?

       

      BR,

      Dan S.

        • 1. Re: META-INF/services for module extensions - question/issue
          Dan Sirbu Newbie

          Stepping into jboss-module code, I realized that the ServiceLoader.load method "overwritten" at runtime by the ConcurrentClassLoader.loadClass from jboss-modules, which at one point will read the jar file via the jarFileRessourceLoader method - BUT it will NOT look at the META-INF/services.

           

          At least I did not see that.

           

          So, the question would be: is this a feature or an issue or I am missing something ?

           

          Since I am new with AS7 would be nice if one could confirm.

           

          BR,

          Dan S.

          • 2. Re: META-INF/services for module extensions - question/issue
            Stuart Douglas Master

            Can you post your module.xml files for your two modules?

            • 3. Re: META-INF/services for module extensions - question/issue
              Dan Sirbu Newbie

              Here they are - I add services="import" based on : "https://docs.jboss.org/author/display/MODULES/Module+descriptors" chapter services, imports and exports

              Same thing - I do not see the implementation class being read from the META-INF/services. The class that is loaded is only the interface class !

               

              the module extension has the following definition:

               

              <?xml version="1.0" encoding="UTF-8"?>

              <module xmlns="urn:jboss:module:1.0" name="com.mycomp.module">

                  <resources>

                      <resource-root path="module-jboss-impl.jar"/>

                      <resource-root path="dnsjava.jar"/>

                      <resource-root path="module-api.jar"/>

                  </resources>

               

                  <dependencies>

                      <module name="javax.api"/>

                      <module name="org.javassist"/>

                      <module name="org.jboss.staxmapper"/>

                      <module name="org.jboss.as.controller"/>

                      <module name="org.jboss.as.server"/>

                      <module name="org.jboss.modules"/>

                      <module name="org.jboss.msc"/>

                      <module name="org.jboss.logging"/>

                      <module name="org.jboss.vfs"/>

                      <module name="org.apache.log4j"/>

                      <module name="javax.xml.bind.api"/>

                      <module name="javax.transaction.api"/>

                      <module name="com.sun.xml.bind"/>

               

                       <module name="com.mycomp.generic" services="import"/>

                  </dependencies>

              </module>

               

              the module that is "imported" into the module extension is:

               

              <?xml version="1.0" encoding="UTF-8"?>

              <module xmlns="urn:jboss:module:1.0" name="com.mycomp.generic">

                  <resources>

                      <resource-root path="generic-impl.jar"/>

                      <resource-root path="module-api.jar"/>

                  </resources>

               

                  <dependencies>

                      <module name="javax.api"/>

                      <module name="org.javassist"/>

                      <module name="org.jboss.staxmapper"/>

                      <module name="org.jboss.as.controller"/>

                      <module name="org.jboss.as.server"/>

                      <module name="org.jboss.modules"/>

                      <module name="org.jboss.msc"/>

                      <module name="org.jboss.logging"/>

                      <module name="org.jboss.vfs"/>

                      <module name="org.apache.log4j"/>

                      <module name="javax.xml.bind.api"/>

                      <module name="javax.transaction.api"/>

                      <module name="com.sun.xml.bind"/>

                  </dependencies>

              </module>

              • 4. Re: META-INF/services for module extensions - question/issue
                Dan Sirbu Newbie

                Adding traces the only thing that it grabs from META-INF is the following:

                 

                10:40:14,350 TRACE [org.jboss.modules] Found previously loaded class org.jboss.as.controller.registry.OperationEntry$EntryType from Module "org.jboss.as.controller:main" from local module loader @18e2b22 (roots: /home/jboss7/modules)

                10:40:14,350 TRACE [org.jboss.modules] Attempting to find all resources META-INF/services/org.jboss.as.controller.Extension in Module "com.mycomp.module:main" from local module loader @18e2b22 (roots: /home/jboss7/modules)

                10:40:14,351 INFO  [com.mycomp.jboss.module.extension.SubsystemExtension] Initializing MMAS subsystem.

                10:40:14,351 TRACE [org.jboss.modules] Finding class org.jboss.as.controller.ExtensionContext from Module "com.mycomp.module:main" from local module loader @18e2b22 (roots: /home/jboss7/modules)

                 

                And the module that is not an extension I do not have anything related to META-INF/services so it does not even try .....

                 

                That is what I have with this test on the module.xml:

                 

                <module name="com.mycomp.generic" services="import" export="true"/>

                • 5. Re: META-INF/services for module extensions - question/issue
                  Dan Sirbu Newbie

                  Hi,

                   

                    Coming back on this && let's try to be more clear.

                   

                    I added into module generic a jboss extension by implementing a dummy "org.jboss.as.controller.Extension" and I have another service "com.mycomp.havefun.NotReally" with it's implementation. META-INF/services update accordingly.

                   

                    The module extension has already an implementation of "org.jboss.as.controller.Extension". META-INF/services updated. This same module has a definition into standalon.xml in order to be kickstarted by jboss modules at startup as an extension of AS7.

                   

                    Now, with the previous module.xml I can see that BOTH jboss controller extensions from BOTH module are started.

                   

                    BUT - I still fail to have that META-INF/service "com.mycomp.havefun.NotReally" loaded !

                   

                    So, rephrasing my question, how can I have the jboss module kickstarting not only the jboss extension BUT my service too ?!? Don't see much on web.

                   

                     I looked at the OSGI service and it seems that the OSGI framework that has some services defined is added programatically not as a module ...... And I am wondering if I have to do the same. If yes, any doc's on how to achieve that ?!?

                   

                  BR,

                  Dan S.

                  • 6. Re: META-INF/services for module extensions - question/issue
                    Brian Stansberry Master

                    The <extension> element in standalone.xml is not meant to be a generic facility for loading ServiceLoader-based services. It's meant for installing implementations of org.jboss.as.controller.Extension (i.e. new manageable subsystems) and nothing else. That's why your dummy implementations get loaded.

                     

                    If you're not looking to add a manageable subsystem, I recommend deploying a sar with a META-INF/jboss-service.xml that declares an mbean whose start() method does the ServiceLoader.load() call.

                    • 7. Re: META-INF/services for module extensions - question/issue
                      Brian Stansberry Master

                      Another hook, besides mbeans, that the AS provides for installing services from a deployment is the MSC https://github.com/jbossas/jboss-msc/blob/master/src/main/java/org/jboss/msc/service/ServiceActivator.java. Basically, the AS scans any deployment for a META-INF/services/org.jboss.msc.service.ServiceActivator file. If found, the ServiceLoader mechanism is used to load the specified ServiceActivator implementation, and then its activate() method is invoked. Via that mechanism you could install an MSC service, and that service could do your ServiceLoad start from its start() method, and also do any cleanup from its stop() method.

                      • 8. Re: META-INF/services for module extensions - question/issue
                        Dan Sirbu Newbie

                        Hi Brian,

                         

                           My question is I do have some 'shared' jar's that have some API's / SPI's defined. Will they be available to a WAR or RAR etc .... as singletons if I kickstart the service via the SAR as sugested ?

                         

                        BR,

                        Dan S.

                        • 9. Re: META-INF/services for module extensions - question/issue
                          Dan Sirbu Newbie

                          Hi Brian,

                           

                             The ServiceActivator would work but it will depend on a deployment which I would like to avoid. SAR will be same - will require a deployment.

                           

                             I taught that by defining a module I could kickstart some SPI's but here it is clear that it will have to go via module Extension ifc which has it's own limitations.

                           

                          BR,

                          Dan S.

                          • 11. Re: META-INF/services for module extensions - question/issue
                            Brian Stansberry Master

                            Re: making an API / SPI available to other deployments...

                             

                            See https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7 for background and details on the following.

                             

                            A war, ear, or any other deployment can specify a dependency on external modules either by adding a jboss-deployment-structure.xml in its META-INF dir or by adding a Dependencies: manifest entry in MANIFEST.MF. See "Dependencies: Manifest Entries" and "JBoss Deployment Structure File" in the above doc.

                             

                            That module can either be one of the modules in the $JBOSS_HOME/modules dir, or it can be a module the AS dynamically creates when a deployment (e.g. a jar containing the API/SPI) is deployed. For modules dynamically created for deployments, the name of the module is "deployment.xxx". See "Deployment Module Names" in the above doc for details on "xxx".

                             

                            Simple example, if you had a jar "my-spi.jar" that included your SPI, you could deploy it, and then a war that needed visibility to the classes in that module could add this to its META-INF/MANIFEST.MF

                             

                            Dependencies: deployment.my-spi.jar

                            • 12. Re: META-INF/services for module extensions - question/issue
                              Jason Greene Master

                              Another approach to consider is that you can use an EJB singleton, which is portable.

                               

                              Are you actually using services? Or is this just about sharing classes?

                              • 13. Re: META-INF/services for module extensions - question/issue
                                Dan Sirbu Newbie

                                OK. I also tryed in a different way: setting in the "ee" subsystem the jar files as global modules and that seemed to work too.

                                 

                                Thanks!

                                 

                                BR,

                                Dan S

                                • 14. Re: META-INF/services for module extensions - question/issue
                                  Dan Sirbu Newbie

                                  Hi Brian,

                                   

                                     I have taken a break from the subject and after giving multiple taughts I still think there is a "flaw". Here is my view based on my current understanding:

                                   

                                     I can have, let's say, two kind of modules: one that implements the module ifc thus an extension && one that does not. Let's name : ModuleExtension the one that has defined an interface towards the : org.jboss.as.controller.Extension ifc; and let's name Module the one that does not have such a definition.

                                    What I understand is that the ModuleExtension by design should not have any other service defined - which is OK. And if it does it is discarded - which again is OK.

                                    What I also understand is that the Module by design can have a service defined. Now the service defined into Module is available to any war, rar, etc... file that is deployed and have somehow a dependecy defined towards that Module (see prev dicussions on how one can achieve that). And the war file, for example, uses the 'regular' Service.load instead of using the jboss-module one - which is what one would expect.

                                    So far so good.

                                   

                                    Now, let's say that ModuleExtension needs Module for whaterver reason. Then one would go into "module.xml" of ModuleExtension and add a dependency towards that Module. Then, what I would expect as behaviour is that the Module service should be available to ModuleExtension via the 'regular' Service.load and not via the jboss-module service loader ! Since Module is not defined as a jboss-module extension, then the ModuleExtension should be able to have access to the Module service interface via the 'regular' Service.load and that because, to me, the Module should be in the classpath of the ModuleExtension one such a dependency has been created. There is no real need to go towards jboss-module service loader - at least I do not see one.

                                   

                                    If a war file, for example, would need access to ModuleExtension it would add a dependecy towards it. The dependency should ensure that the objects defined with the ModuleExtension become visible to the war file including the ones from the Module meaning that the classpath of the ModuleExtension would be made available to the war. At least that is I think a dependency should do.

                                   

                                    If one would do that, then there will a lot more flexibility in the way that the jboss-module would work - in my opinion.

                                   

                                  BR,

                                  Dan S.

                                  1 2 3 Previous Next