4 Replies Latest reply on Jul 28, 2010 6:44 AM by thomas.diesler

    Ability limit imported packages

    thomas.diesler

      Tracked by MODULES-13

       

      Consider this

       

      Bundle-SymbolicName: jbosgi323-bundleA
      Import-Package: org.jboss.test.osgi.container.classloader.support.a
      
      Bundle-SymbolicName: jbosgi323-bundleB
      Export-Package: 
        org.jboss.test.osgi.container.classloader.support.a, 
        org.jboss.test.osgi.container.classloader.support.b
      

       

      So moduleA has a dependency on moduleB because A imports package 'a' which B exports.

       

      However, loading a class from package 'b' through A is expected to fail, because A does not import nor contain package 'b'

       

      Currently this usecase fails (i.e. the class from b can be loaded through A) because you cannot control the paths that a module imports.

       

      jboss-modules effectivly has a dependency mechanism that is simmilar to OSGi Require-Bundle. Require-Bundle is generally believed bad practise. There is a chapter in the core spec that explains why it is a bad idea.

       

           3.12.3 Issues With Requiring Bundles

       

      The main concern is, that if an exporter evolves and distributes the exported paths over multiple modules (instead of just one) it'll break all clients that depent on the previous packaging choice.

       

      A dependency mechanism keyed of versioned packages does not have this problem. Clients dont care what module provides the package.

       

      Thought?

        • 1. Re: Ability limit imported packages
          dmlloyd

          Thomas Diesler wrote:

           

          Consider this

           

          Bundle-SymbolicName: jbosgi323-bundleA
          Import-Package: org.jboss.test.osgi.container.classloader.support.a
          
          Bundle-SymbolicName: jbosgi323-bundleB
          Export-Package: 
            org.jboss.test.osgi.container.classloader.support.a, 
            org.jboss.test.osgi.container.classloader.support.b
          

           

          So moduleA has a dependency on moduleB because A imports package 'a' which B exports.

           

          However, loading a class from package 'b' through A is expected to fail, because A does not import nor contain package 'b'

           

          Currently this usecase fails (i.e. the class from b can be loaded through A) because you cannot control the paths that a module imports.

           

          jboss-modules effectivly has a dependency mechanism that is simmilar to OSGi Require-Bundle. Require-Bundle is generally believed bad practise. There is a chapter in the core spec that explains why it is a bad idea.

           

               3.12.3 Issues With Requiring Bundles

           

          The main concern is, that if an exporter evolves and distributes the exported paths over multiple modules (instead of just one) it'll break all clients that depent on the previous packaging choice.

           

          A dependency mechanism keyed of versioned packages does not have this problem. Clients dont care what module provides the package.

           

          Thought?

           

          OSGi bundles are not the same thing as modules either in concept or implementation.  With modules you can in fact limit what is imported from another module by package, if you wish.  In addition, Modules implies a static, "closed" world so the concern about splitting modules is less significant, and the concern about importing by version is nonexistant.  If a module is split, then it is easy enough to create an aggregate metamodule if backwards compatibility is to be maintained.

           

          Packages do not make a good unit of granularity for import/export for modules like they do for OSGi.  Modules is meant to supply a simple, 100% deterministic structure at distribution time.  There is just no use case in the AS distribution for advanced OSGi-like semantics.  OSGi is something for user deployments, which are considerably more dynamic and portable than core AS components.  I do not believe we should try to solve one problem domain with the other solution - OSGi bundles and Modules solve two separate problems and are only superficially related.

          • 2. Re: Ability limit imported packages
            thomas.diesler

            That raises the question of "What can be a module?".

             

            An OSGi deployment is expected to work in AS7 lust like an EJB3 deployment, or WebApp deployment. So if we go down the path of "Some deployments are modules others not" there is an integration issues between the component models.

             

            Can a module have a dependency on a non-module?

            Can a non-module have a dependency on a module?

             

            So far I worked on the assumption that jboss-modules provides the limited but necessary set of primitives that allows the AS7 supported component models to map onto it and integrate with each other at the primitve level?

             

            If this is not the case, and jboss-modules precludes certain deployment types (e.g. OSGi), we need to revisit the requirements for AS7 OSGi support. Specifically that of access of OSGi services from non-OSGi deployments and vice versa.

             

            I take, if a decission at that level is made it will be easier to decide whether a feature needs to be supported at the modules level or not.

            • 3. Re: Ability limit imported packages
              dmlloyd

              Thomas Diesler wrote:

               

              That raises the question of "What can be a module?".

               

              An OSGi deployment is expected to work in AS7 lust like an EJB3 deployment, or WebApp deployment. So if we go down the path of "Some deployments are modules others not" there is an integration issues between the component models.

               

              Can a module have a dependency on a non-module?

              Can a non-module have a dependency on a module?

               

              So far I worked on the assumption that jboss-modules provides the limited but necessary set of primitives that allows the AS7 supported component models to map onto it and integrate with each other at the primitve level?

               

              If this is not the case, and jboss-modules precludes certain deployment types (e.g. OSGi), we need to revisit the requirements for AS7 OSGi support. Specifically that of access of OSGi services from non-OSGi deployments and vice versa.

               

              I take, if a decission at that level is made it will be easier to decide whether a feature needs to be supported at the modules level or not.

               

              It is the case that the current modules implementation (in theory) covers all EE use cases.  The question with OSGi is, given the set of features that modules is missing, can they be implemented in modules without sacrificing encapsulation, simplicity or performance?  If so then it's still possible to do, but I don't think that extending the module classloader and making that private implementation into a public API is the way to do this.  So rather than look at it from the perspective of adding implementation changes, let's isolate the missing features.

               

              This thread is about limiting imported package, which modules already is capable of via the possibly misleadingly-named ExportFilter (which really can apply on the import or export side).

              • 4. Re: Ability limit imported packages
                thomas.diesler
                It is the case that the current modules implementation (in theory)  covers all EE use cases.

                 

                Ok, that is good news and allows me to continue on the premisse: An OSGi bundle is a Module

                 

                Lets continue on the technical detail level

                 

                You should be able to do this already using  DependencySpec.exportExcludes/exportIncludes (yeah I know they're called  export* but it's supposed to control the exports of the dependency and  thus your imports).  Does this not work?

                Yes, that was my first approach but it does not work.

                 

                When the ModuleLoader computes the pathsToImports it always adds the dependent exportedPath

                 

                                for(String exportedPath : moduleExportedPaths) {
                                    final boolean shouldExport = depExported && filter.shouldExport(exportedPath);
                                    if(shouldExport) {
                                        exportedPaths.add(exportedPath);
                                    }
                                    if(!pathsToImports.containsKey(exportedPath))
                                        pathsToImports.put(exportedPath, new ArrayList<Module.DependencyImport>());
                                    pathsToImports.get(exportedPath).add(new Module.DependencyImport(dependency, shouldExport));

                 

                perhaps it should conceptually be something like this

                 

                                for(String exportedPath : moduleExportedPaths) {
                                    if (filter.shouldExport(exportedPath))
                                    {
                                       if(depExported) {
                                           exportedPaths.add(exportedPath);
                                       }
                                       if(!pathsToImports.containsKey(exportedPath))
                                           pathsToImports.put(exportedPath, new ArrayList<Module.DependencyImport>());
                                       pathsToImports.get(exportedPath).add(new Module.DependencyImport(dependency, shouldExport));
                                    }
                                }