glassfish
  1. glassfish
  2. GLASSFISH-13169

Add diagnostic information to explain why a module is being resolved

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Invalid
    • Affects Version/s: 3.1
    • Fix Version/s: None
    • Component/s: OSGi
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

    • Issuezilla Id:
      13,169

      Description

      The OSGi shell permits one to view what modules have been resolved at a
      particular point in time. However, it is also important to know why a module
      has been resolved. What module was it that triggered getting a module resolved?

      This is a request to add diagnostic information to the system so that one can
      find out why a module was resolved. Preferably, this would show the entire chain
      of resolutions, starting with the explicit activation of a module, i.e., a
      module that is in the Active state. For example, if module A is activated, and
      it references module B which reference modules C which in turn references D, it
      should be possible to execute some command or view some log output and see:

      D <-- C <-- B <-- A

      The inspect command in the OSGi shell does this to some extent. However, it is
      not clear what the meanings of package, bundle, fragment and service are WRT an
      OSGi module, and the dependencies as shown by that command appear to be
      theoretical based on what is declared in the meta data rather than what actually
      happened when a module was loaded.

        Activity

        Hide
        Richard S. Hall added a comment -

        It is true that you can create a command to transitively walk dependencies in OSGi, but to reiterate my point, this will not necessarily tell you why a bundle was resolved. The OSGi spec doesn't dictate incremental module resolves. The Felix framework is incremental, but the Equinox framework is not, so it tries to resolve everything any time it resolves anything. Thus there is no causality on Equinox.

        I cannot think of a good [standard] way to determine causality of resolving. Although with the OSGi R4.3 API you do have resolver hooks that give you potential triggers that started the resolve, but the hooks don't directly have access to the resolve result, they would just have to try to observe it and it still doesn't help you deal with the fact that on Equinox any resolve will result in an attempt to resolve all installed modules.

        Show
        Richard S. Hall added a comment - It is true that you can create a command to transitively walk dependencies in OSGi, but to reiterate my point, this will not necessarily tell you why a bundle was resolved. The OSGi spec doesn't dictate incremental module resolves. The Felix framework is incremental, but the Equinox framework is not, so it tries to resolve everything any time it resolves anything. Thus there is no causality on Equinox. I cannot think of a good [standard] way to determine causality of resolving. Although with the OSGi R4.3 API you do have resolver hooks that give you potential triggers that started the resolve, but the hooks don't directly have access to the resolve result, they would just have to try to observe it and it still doesn't help you deal with the fact that on Equinox any resolve will result in an attempt to resolve all installed modules.
        Hide
        Sanjeeb Sahoo added a comment -

        Modules are resolved by OSGi framework. The command Richard talked about is a Felix shell command. HK2 has ways to report why modules get activated. Ask HK2 folks.

        Show
        Sanjeeb Sahoo added a comment - Modules are resolved by OSGi framework. The command Richard talked about is a Felix shell command. HK2 has ways to report why modules get activated. Ask HK2 folks.
        Hide
        Tom Mueller added a comment -

        What osgi command or what capability in the console. Please provide details before marking this issue as resolved. Richard indicated that a command could be implemented that would walk the tree recursively. Has that been done?

        I did find a solution for this problem:

        1. Change the debug setting to be suspend=y
        2. Set a breakpoint in the hk2/osgi/adapter module, the OSGiModuleImpl.start method. I used line 217.
        3. Start the server with --debug
        4. Set up a watchpoint in the debugger for this.bundle.getLocation(). This will print the JAR file path for each JAR that is activated.
        5. Keep hitting continue until the JAR file that you are interested in shows up.

        This requires looking at the stack trace to see what caused a module to be activated. This same mechanism can be used to see why a module is resolved, by putting the breakpoint in a different place.

        Show
        Tom Mueller added a comment - What osgi command or what capability in the console. Please provide details before marking this issue as resolved. Richard indicated that a command could be implemented that would walk the tree recursively. Has that been done? I did find a solution for this problem: 1. Change the debug setting to be suspend=y 2. Set a breakpoint in the hk2/osgi/adapter module, the OSGiModuleImpl.start method. I used line 217. 3. Start the server with --debug 4. Set up a watchpoint in the debugger for this.bundle.getLocation(). This will print the JAR file path for each JAR that is activated. 5. Keep hitting continue until the JAR file that you are interested in shows up. This requires looking at the stack trace to see what caused a module to be activated. This same mechanism can be used to see why a module is resolved, by putting the breakpoint in a different place.
        Hide
        Sanjeeb Sahoo added a comment -

        Please use osgi command or osgi console. Setting felix.log.level to 4 also produces resolver output in debug mode.

        Show
        Sanjeeb Sahoo added a comment - Please use osgi command or osgi console. Setting felix.log.level to 4 also produces resolver output in debug mode.
        Hide
        Tom Mueller added a comment -

        Bulk update to reassign dochez issue to component lead.

        Show
        Tom Mueller added a comment - Bulk update to reassign dochez issue to component lead.
        Hide
        Richard S. Hall added a comment -

        We might be switching to Gogo shortly and its implementation of the "inspect"
        command is a little more useful in this case:

        org.apache.felix.gogo.runtime [3] exports packages:
        ---------------------------------------------------
        org.apache.felix.service.command; version=0.6.0 imported by:
        org.apache.felix.gogo.command [2]
        org.apache.felix.gogo.shell [4]
        org.apache.felix.shell.remote [6]
        org.apache.felix.service.threadio; version=0.6.0 UNUSED

        You can see here that is shows who imports it. However, it doesn't walk this
        transitively. However, it would be possible for us to create a command that does.

        Show
        Richard S. Hall added a comment - We might be switching to Gogo shortly and its implementation of the "inspect" command is a little more useful in this case: org.apache.felix.gogo.runtime [3] exports packages: --------------------------------------------------- org.apache.felix.service.command; version=0.6.0 imported by: org.apache.felix.gogo.command [2] org.apache.felix.gogo.shell [4] org.apache.felix.shell.remote [6] org.apache.felix.service.threadio; version=0.6.0 UNUSED You can see here that is shows who imports it. However, it doesn't walk this transitively. However, it would be possible for us to create a command that does.
        Hide
        Tom Mueller added a comment -

        I haven't found the output of the inspect command to be useful for this. The capability option lists what
        packages are exported by the bundle, but it doesn't say which resolved bundles are actually using those
        capabilities. So short of doing an inspect p r on every resolved bundle to see which ones reference the bundle
        of interest, there isn't any way of answering the question "why did this bundle get resolved?"

        We probably do not need a solution in the general sense. Rather, maybe just a log message at the beginning of
        the resolution of a module that indicates what module is causing the resolve to happen.

        Show
        Tom Mueller added a comment - I haven't found the output of the inspect command to be useful for this. The capability option lists what packages are exported by the bundle, but it doesn't say which resolved bundles are actually using those capabilities. So short of doing an inspect p r on every resolved bundle to see which ones reference the bundle of interest, there isn't any way of answering the question "why did this bundle get resolved?" We probably do not need a solution in the general sense. Rather, maybe just a log message at the beginning of the resolution of a module that indicates what module is causing the resolve to happen.
        Hide
        Richard S. Hall added a comment -

        I don't think this is possible in the general sense. At a minimum, the OSGi spec
        allows a framework to resolve bundles at its own discretion, which means there
        may be no reason why a module was resolved other than the framework wanted it
        that way.

        Further, there is no sort of resolver API in the framework to ask, "If I resolve
        bundle foo, what other bundle's will resolve as a result." The best you can do
        is try to resolve something and then see which bundles also changed state after
        the resolve. However, there are inherent race conditions with this and still the
        framework is free to resolve arbitrary bundles at the same time, so there may be
        no real relationship among the bundles whose state changed.

        Technically, you could try to use the framework's own resolver to ask "what if"
        questions, but this is not standardize API, nor do you necessarily have any
        guarantees that the results are the same when you actually try to commit them.

        I think the best you can do is analyze the dependencies that exist among modules
        after they are resolved to determine why something may have been resolved.

        Finally, the results from the "inspect" command show you actual dependencies
        based on run-time information, not theoretical information.

        Show
        Richard S. Hall added a comment - I don't think this is possible in the general sense. At a minimum, the OSGi spec allows a framework to resolve bundles at its own discretion, which means there may be no reason why a module was resolved other than the framework wanted it that way. Further, there is no sort of resolver API in the framework to ask, "If I resolve bundle foo, what other bundle's will resolve as a result." The best you can do is try to resolve something and then see which bundles also changed state after the resolve. However, there are inherent race conditions with this and still the framework is free to resolve arbitrary bundles at the same time, so there may be no real relationship among the bundles whose state changed. Technically, you could try to use the framework's own resolver to ask "what if" questions, but this is not standardize API, nor do you necessarily have any guarantees that the results are the same when you actually try to commit them. I think the best you can do is analyze the dependencies that exist among modules after they are resolved to determine why something may have been resolved. Finally, the results from the "inspect" command show you actual dependencies based on run-time information, not theoretical information.

          People

          • Assignee:
            Sanjeeb Sahoo
            Reporter:
            Tom Mueller
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: