glassfish
  1. glassfish
  2. GLASSFISH-19395

Mapping HK2 annotations(@Service and @Inject) into OBR capability and requirement

    Details

    • Type: Task Task
    • Status: In Progress
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: future release
    • Fix Version/s: None
    • Component/s: OSGi
    • Labels:
      None

      Description

      While using on-demand provisioning of OSGi modules(glassfish.osgi.ondemand=true), we must discovery and install needed bundle and the bundle's dependencies rightly. In order to reach the goal, only using OBR to generate index file is not enough because HK2 world also defined some annotations which are used for service-level dependencies, called @Service and @Inject.

      Because @Service and @Inject have an another very important task for implementing on-demand bundle's starting, for example, while deploying a WAB with CDI, WebContainer will be started and at the same time, because WebContainer has a @inject JCDIService, deploying phrase will also start Weld-Integration bundle in which a @Service which implements JCDIService will be registered into HK2 registry.

      So, from the point to say, @Service and @Inject also correspond to OBR capability and requirement, if we can not map the annotations, while using OBR to provision, there is an possibility that we will miss some required bundles in felix cache and caused a failure of on-demand starting.

        Activity

        Hide
        TangYong added a comment -

        During several day's investigation, I have some results and solution as following:

        Solution: using deprecated Import-Service and Export-Service [1][2]

        Although Import-Service and Export-Service head have been deprecated, we
        can still use the head to meet our demand because we can consider hk2 level's service dependency as some static service dependency.

        I have confirmed that bnd or maven-bundle-plugin supports the two heads and felix obr aslo supports the two heads.

        Then, we need to resolve a problem: how to generate Import-Service and Export-Service head?

        Method1: manually adding Import-Service and Export-Service head into osgi.bundle file

        [Analyse Advantage/Disadvantage]
        Advantage: simple and fast
        Disadvantage: needing to large scale edit osgi.bundle

        Method2: extending some maven plugin(maybe hk2 maven plugin, maybe bnd...) to automaticlly scan bundle(@inject and @Service) and generate
        the two heads

        [Analyse Advantage/Disadvantage]
        Advantage: not editing osgi.bundle manually
        Disadvantage: a litter complex and needing to master maven or bnd, and also needing to invesigate how to extend

        Method3: Not modifying current module's manifest.mf, after generating obr-modules.xml, adding Import-Service and Export-Service head into the repository file by scanning each bundle

        [Analyse Advantage/Disadvantage]
        Advantage: not editing osgi.bundle manually and not extending current build architecture
        Disadvantage: (1) needing to how to add Import-Service and
        Export-Service head into the repository file because felix obr Api has not published similar api. (Note: I have sent a email to felix to consult the thing)

        (2) needing to how to scan (@inject and @Service) better and maybe needing to extend osgi-adapter module

        As a demostrating, I have used Method1 to add the two heads for web-glue and weld-integration and currently, the two modules have not some direct
        dependency(module layer dependency), however, web-glue has a hk2 service
        dependency[3] on weld-integration. So, after I edited osgi.bundles of the two modules, obr-modules.xml has added the service related requirement/capability for the two modules.

        <resource id='org.glassfish.main.web.glue/4.0.0.SNAPSHOT' symbolicname='org.glassfish.main.web.glue' ...'>
        ...
        <require name='service' filter='(service=com.sun.enterprise.container.common.spi.JCDIService)' extend='false' multiple='true' optional='false'>Import Service com.sun.enterprise.container.common.spi.JCDIService</require>
        ...

        <resource id='org.glassfish.main.web.weld-integration/4.0.0.SNAPSHOT' symbolicname='org.glassfish.main.web.weld-integration' ...>
        ...
        <capability name='service'>
        <p n='service' v='com.sun.enterprise.container.common.spi.JCDIService'/>
        </capability>
        <capability name='service'>
        <p n='service' v='org.glassfish.api.naming.NamedNamingObjectProxy'/>
        </capability>
        <capability name='service'>
        <p n='service' v='org.glassfish.weld.ResourceLoaderImpl'/>
        </capability>
        <capability name='service'>
        <p n='service' v='com.sun.enterprise.web.WebComponentDecorator'/>
        </capability>
        <capability name='service'>
        <p n='service' v='org.glassfish.api.container.Container'/>
        </capability>
        <capability name='service'>
        <p n='service' v='org.glassfish.weld.WeldDeployer'/>

        [1]: http://wiki.osgi.org/wiki/Import-Service
        [2]: RFC-0112 Bundle Repository
        [3]: in WebContainer.java, the following declares a service dependency
        @Inject @Optional
        private JCDIService jcdiService

        Show
        TangYong added a comment - During several day's investigation, I have some results and solution as following: Solution: using deprecated Import-Service and Export-Service [1] [2] Although Import-Service and Export-Service head have been deprecated, we can still use the head to meet our demand because we can consider hk2 level's service dependency as some static service dependency. I have confirmed that bnd or maven-bundle-plugin supports the two heads and felix obr aslo supports the two heads. Then, we need to resolve a problem: how to generate Import-Service and Export-Service head? Method1: manually adding Import-Service and Export-Service head into osgi.bundle file [Analyse Advantage/Disadvantage] Advantage: simple and fast Disadvantage: needing to large scale edit osgi.bundle Method2: extending some maven plugin(maybe hk2 maven plugin, maybe bnd...) to automaticlly scan bundle(@inject and @Service) and generate the two heads [Analyse Advantage/Disadvantage] Advantage: not editing osgi.bundle manually Disadvantage: a litter complex and needing to master maven or bnd, and also needing to invesigate how to extend Method3: Not modifying current module's manifest.mf, after generating obr-modules.xml, adding Import-Service and Export-Service head into the repository file by scanning each bundle [Analyse Advantage/Disadvantage] Advantage: not editing osgi.bundle manually and not extending current build architecture Disadvantage: (1) needing to how to add Import-Service and Export-Service head into the repository file because felix obr Api has not published similar api. (Note: I have sent a email to felix to consult the thing) (2) needing to how to scan (@inject and @Service) better and maybe needing to extend osgi-adapter module As a demostrating, I have used Method1 to add the two heads for web-glue and weld-integration and currently, the two modules have not some direct dependency(module layer dependency), however, web-glue has a hk2 service dependency [3] on weld-integration. So, after I edited osgi.bundles of the two modules, obr-modules.xml has added the service related requirement/capability for the two modules. <resource id='org.glassfish.main.web.glue/4.0.0.SNAPSHOT' symbolicname='org.glassfish.main.web.glue' ...'> ... <require name='service' filter='(service=com.sun.enterprise.container.common.spi.JCDIService)' extend='false' multiple='true' optional='false'>Import Service com.sun.enterprise.container.common.spi.JCDIService</require> ... <resource id='org.glassfish.main.web.weld-integration/4.0.0.SNAPSHOT' symbolicname='org.glassfish.main.web.weld-integration' ...> ... <capability name='service'> <p n='service' v='com.sun.enterprise.container.common.spi.JCDIService'/> </capability> <capability name='service'> <p n='service' v='org.glassfish.api.naming.NamedNamingObjectProxy'/> </capability> <capability name='service'> <p n='service' v='org.glassfish.weld.ResourceLoaderImpl'/> </capability> <capability name='service'> <p n='service' v='com.sun.enterprise.web.WebComponentDecorator'/> </capability> <capability name='service'> <p n='service' v='org.glassfish.api.container.Container'/> </capability> <capability name='service'> <p n='service' v='org.glassfish.weld.WeldDeployer'/> [1] : http://wiki.osgi.org/wiki/Import-Service [2] : RFC-0112 Bundle Repository [3] : in WebContainer.java, the following declares a service dependency @Inject @Optional private JCDIService jcdiService
        Hide
        TangYong added a comment -

        Using [3]'s way to edit osgi.bundles , then generating an obr file.

        Show
        TangYong added a comment - Using [3] 's way to edit osgi.bundles , then generating an obr file.
        Hide
        Sanjeeb Sahoo added a comment -

        Let's see if we can use method #3 to generate OBR capability/requirement metadata for HK2 service dependencies. I have checked in a framework for a standalone utility for generation of OBR metadata in [1]. Let's see if we can enhance it. Thanks.

        [1] https://svn.java.net/svn/glassfish~svn/trunk/fighterfish/experimental/glassfish-obr-builder. Se

        Show
        Sanjeeb Sahoo added a comment - Let's see if we can use method #3 to generate OBR capability/requirement metadata for HK2 service dependencies. I have checked in a framework for a standalone utility for generation of OBR metadata in [1] . Let's see if we can enhance it. Thanks. [1] https://svn.java.net/svn/glassfish~svn/trunk/fighterfish/experimental/glassfish-obr-builder . Se
        Hide
        TangYong added a comment - - edited

        Hi Sahoo,

        I have seen and ran glassfish-obr-builder and it is an interesting module, firstly , I want to make you confirm my understanding for the framework.

        [My understanding]
        1 glassfish-obr-builder's aim should be similar to felix obr to generate capability and requirement from bundle's Manifest.MF.

        2 The framework should want to generate capability and requirement into a new obr xml file, although we can output repository info from a existed obr xml(for example, after setting glassfish.osgi.ondemand=true, however, because ondemand starting glassfish is still in incubated status, this should have no sense). But the logic of generating capability and requirement into a new obr xml file is not still finished.

        Secondly, I have a question about the framework as following:

        [Question about the framework]
        Why we use felix obr to generate capability and requirement and instead, re-invent a wheel?
        Whether because the framework's API is more easy and convenient than felix obr's API or not?

        Thirdly, backing to GLASSFISH-19395, my thinking about whether can re-use the framework or not?

        [My thinking]
        Sure, no problem, can re-use the framework.And we only need to add the logic of generating capability and requirement from a directory containing OSGi bundles. A point to notice is that if using felix obr, we will directly use felix obr's api to finish such things.

        Thanks.

        Show
        TangYong added a comment - - edited Hi Sahoo, I have seen and ran glassfish-obr-builder and it is an interesting module, firstly , I want to make you confirm my understanding for the framework. [My understanding] 1 glassfish-obr-builder's aim should be similar to felix obr to generate capability and requirement from bundle's Manifest.MF. 2 The framework should want to generate capability and requirement into a new obr xml file, although we can output repository info from a existed obr xml(for example, after setting glassfish.osgi.ondemand=true, however, because ondemand starting glassfish is still in incubated status, this should have no sense). But the logic of generating capability and requirement into a new obr xml file is not still finished. Secondly, I have a question about the framework as following: [Question about the framework] Why we use felix obr to generate capability and requirement and instead, re-invent a wheel? Whether because the framework's API is more easy and convenient than felix obr's API or not? Thirdly, backing to GLASSFISH-19395 , my thinking about whether can re-use the framework or not? [My thinking] Sure, no problem, can re-use the framework.And we only need to add the logic of generating capability and requirement from a directory containing OSGi bundles. A point to notice is that if using felix obr, we will directly use felix obr's api to finish such things. Thanks.
        Hide
        Sanjeeb Sahoo added a comment -

        It makes to reuse Felix OBR module instead of writing our own. I leave it to you to do whatever you find easier.

        Thanks,
        Sahoo

        Show
        Sanjeeb Sahoo added a comment - It makes to reuse Felix OBR module instead of writing our own. I leave it to you to do whatever you find easier. Thanks, Sahoo
        Hide
        TangYong added a comment -

        Hi sahoo,

        I have finished the issue and put sources into the following url:

        https://github.com/tangyong/glassfish-obr-builder

        You can use and see the result according to https://github.com/tangyong/glassfish-obr-builder/blob/master/README.md .

        I reused osgi-adapter's ObrHandler and packaged glassfish-obr-builder as an osgi bundle and put the bundle into autostart directory, once glassfish domain starting, glassfish-obr-builder will generate an obr-modules.xml in domains/domain1/osgi-cache/felix directory. This effect is very similar to set glassfish.osgi.ondemand=true. However,glassfish-obr-builder is more simple and can make us do more research on provisioning stories.

        Thanks

        Show
        TangYong added a comment - Hi sahoo, I have finished the issue and put sources into the following url: https://github.com/tangyong/glassfish-obr-builder You can use and see the result according to https://github.com/tangyong/glassfish-obr-builder/blob/master/README.md . I reused osgi-adapter's ObrHandler and packaged glassfish-obr-builder as an osgi bundle and put the bundle into autostart directory, once glassfish domain starting, glassfish-obr-builder will generate an obr-modules.xml in domains/domain1/osgi-cache/felix directory. This effect is very similar to set glassfish.osgi.ondemand=true. However,glassfish-obr-builder is more simple and can make us do more research on provisioning stories. Thanks
        Hide
        TangYong added a comment -

        Currently, the glassfish-obr-builder is being enhanced in the following fileds:

        1 Provisioning Strategy
        seeing: https://github.com/tangyong/glassfish-obr-builder/issues/11

        2 Creating a client bundle to make an experiment to test 1 using glassfish-obr-builder
        seeing: https://github.com/tangyong/glassfish-obr-builder/issues/13

        3 Offering a way to populate obr resources from external maven repo
        seeing: https://github.com/tangyong/glassfish-obr-builder/issues/8
        However, 3's priority is low.

        Show
        TangYong added a comment - Currently, the glassfish-obr-builder is being enhanced in the following fileds: 1 Provisioning Strategy seeing: https://github.com/tangyong/glassfish-obr-builder/issues/11 2 Creating a client bundle to make an experiment to test 1 using glassfish-obr-builder seeing: https://github.com/tangyong/glassfish-obr-builder/issues/13 3 Offering a way to populate obr resources from external maven repo seeing: https://github.com/tangyong/glassfish-obr-builder/issues/8 However, 3's priority is low.
        Hide
        TangYong added a comment -

        About the above 3, I have estimated Apache Karaf Cave, and it has such a capability to populate obr resources from an external maven repo and populate obr resources from an user local maven repo to enhance provisioning strategy.

        In addition, about 1, once finishing it, I have an initial idea for making a gf kernel's evolution:

        1 Defining a subsystems for glassfish according to the following rule
        1)admin subsystem
        The subsystem is defined by admin infra related bundles, and while starting glassfish domain, we must deploy the subsystem because it is a core bus of glassfish self.

        2)javaee 7 spec related large subsystem
        The large subsystem is constituted by many subsystems according to javaee 7 spec. For example, for EJB spec, we can define a ejb subsystem which is defined by ejb related bundles. Once we make such a partition, a user can deploy these subsystem in on-demand way according to his/her requirement.

        3)osgi-javaee related subsystem
        The subsystem is constituted by osgi-javaee related bundles which currently are put into autostart directory.

        2 Generating System OBR using glassfish-obr-builder ahead of time
        If having 1, while starting glassfish domain, we can firstly generate Glassfish System OBR using glassfish-obr-builder, and according to the Glassfish System OBR, we can deploy admin subsystem and lately also use the Glassfish System OBR to deploy other subsystems.

        3 Integrating other the third part's frameworks
        Integrating other the third part's frameworks can also use subsystem concept to do. We only need to offer a subsystem which is constituted by the third part's frameworks related bundles. In such a subsystem definition, an user can offer an user-defined obr repo url as provisioning repo. Then, while deploying such a subsystem, we firstly provision bundles from Glassfish System OBR because some bundles maybe have been offered by glassfish, if not finding proper resources, we will provision bundles from user-defined obr repo.

        The above idea has the following advantages:
        1) speeding up glassfish domain starting
        2) saving more spaces rather than installing all bundles into felix cache.
        3) making an user have more profiles, for example, if the user creates two domains, in domain1, he/she can deploy some javaee related bundles, in domain2, he/she can deploy some osgi-javaee related bundles.

        Show
        TangYong added a comment - About the above 3, I have estimated Apache Karaf Cave, and it has such a capability to populate obr resources from an external maven repo and populate obr resources from an user local maven repo to enhance provisioning strategy. In addition, about 1, once finishing it, I have an initial idea for making a gf kernel's evolution: 1 Defining a subsystems for glassfish according to the following rule 1)admin subsystem The subsystem is defined by admin infra related bundles, and while starting glassfish domain, we must deploy the subsystem because it is a core bus of glassfish self. 2)javaee 7 spec related large subsystem The large subsystem is constituted by many subsystems according to javaee 7 spec. For example, for EJB spec, we can define a ejb subsystem which is defined by ejb related bundles. Once we make such a partition, a user can deploy these subsystem in on-demand way according to his/her requirement. 3)osgi-javaee related subsystem The subsystem is constituted by osgi-javaee related bundles which currently are put into autostart directory. 2 Generating System OBR using glassfish-obr-builder ahead of time If having 1, while starting glassfish domain, we can firstly generate Glassfish System OBR using glassfish-obr-builder, and according to the Glassfish System OBR, we can deploy admin subsystem and lately also use the Glassfish System OBR to deploy other subsystems. 3 Integrating other the third part's frameworks Integrating other the third part's frameworks can also use subsystem concept to do. We only need to offer a subsystem which is constituted by the third part's frameworks related bundles. In such a subsystem definition, an user can offer an user-defined obr repo url as provisioning repo. Then, while deploying such a subsystem, we firstly provision bundles from Glassfish System OBR because some bundles maybe have been offered by glassfish, if not finding proper resources, we will provision bundles from user-defined obr repo. The above idea has the following advantages: 1) speeding up glassfish domain starting 2) saving more spaces rather than installing all bundles into felix cache. 3) making an user have more profiles, for example, if the user creates two domains, in domain1, he/she can deploy some javaee related bundles, in domain2, he/she can deploy some osgi-javaee related bundles.
        Hide
        TangYong added a comment -

        >1 Provisioning Strategy
        >seeing: https://github.com/tangyong/glassfish-obr-builder/issues/11

        Done

        >2 Creating a client bundle to make an experiment to test 1 using glassfish-obr-builder
        >seeing: https://github.com/tangyong/glassfish-obr-builder/issues/13

        Being enhancing...

        Currently, a subsystem provioning sample can work normally.

        >3 Offering a way to populate obr resources from external maven repo
        >seeing: https://github.com/tangyong/glassfish-obr-builder/issues/8
        >However, 3's priority is low.

        Undo

        4 start subsystem based on module start level defined in subsystem xml file
        seeing https://github.com/tangyong/glassfish-obr-builder/issues/15

        Basic done and a topic needs to be discussed with sahoo.

        5 undeploying subsystem

        Doing

        Show
        TangYong added a comment - >1 Provisioning Strategy >seeing: https://github.com/tangyong/glassfish-obr-builder/issues/11 Done >2 Creating a client bundle to make an experiment to test 1 using glassfish-obr-builder >seeing: https://github.com/tangyong/glassfish-obr-builder/issues/13 Being enhancing... Currently, a subsystem provioning sample can work normally. >3 Offering a way to populate obr resources from external maven repo >seeing: https://github.com/tangyong/glassfish-obr-builder/issues/8 >However, 3's priority is low. Undo 4 start subsystem based on module start level defined in subsystem xml file seeing https://github.com/tangyong/glassfish-obr-builder/issues/15 Basic done and a topic needs to be discussed with sahoo. 5 undeploying subsystem Doing
        Hide
        Sanjeeb Sahoo added a comment -

        Tang,

        This is great progress. I have been able to build it and test as well. I think there is a slight misunderstanding about how I expected the processing to happen. I noticed you are expecting us to populate Export-Service and Import-Service metadata in osgi.bundle file. I thought approach #3 meant no changes to bundles. We would introspect bundles and generate Export-Service and Import-Service metadata from @Inject and @Service annotations.

        Sahoo

        Show
        Sanjeeb Sahoo added a comment - Tang, This is great progress. I have been able to build it and test as well. I think there is a slight misunderstanding about how I expected the processing to happen. I noticed you are expecting us to populate Export-Service and Import-Service metadata in osgi.bundle file. I thought approach #3 meant no changes to bundles. We would introspect bundles and generate Export-Service and Import-Service metadata from @Inject and @Service annotations. Sahoo
        Hide
        TangYong added a comment -

        >I thought approach #3 meant no changes to bundles. We would introspect bundles and generate Export-Service and >Import-Service metadata from @Inject and @Service annotations.

        I see and I will consider it.

        Thanks

        Tang

        Show
        TangYong added a comment - >I thought approach #3 meant no changes to bundles. We would introspect bundles and generate Export-Service and >Import-Service metadata from @Inject and @Service annotations. I see and I will consider it. Thanks Tang
        Hide
        Sanjeeb Sahoo added a comment -

        Assigning to Tang

        Show
        Sanjeeb Sahoo added a comment - Assigning to Tang
        Hide
        TangYong added a comment -

        A new project source has sent into Sahoo and wait for his comment.

        Show
        TangYong added a comment - A new project source has sent into Sahoo and wait for his comment.
        Hide
        TangYong added a comment -

        Have checked in sources.

        revision: 61742

        Show
        TangYong added a comment - Have checked in sources. revision: 61742
        Hide
        TangYong added a comment -

        At revision: 61748(a litter issue's fix)

        Show
        TangYong added a comment - At revision: 61748(a litter issue's fix)

          People

          • Assignee:
            TangYong
            Reporter:
            TangYong
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: