1 2 3 Previous Next 44 Replies Latest reply on Apr 4, 2017 11:53 AM by fmiguelez Go to original post
      • 15. Re: Byteman vs JBoss Modules classloading
        jameslivingston

        And after more delay because of my holidays

         

         

        Since imports can influence type resolution via TypeGroup, the helper classloader has to be constructed much earlier, in the constructor prior to the Event at least

         

        Oh well, ok,if you say so. I tthought it looked ok the way you were doing it :-)

         

        Was there somewhere specific you can cite where you are resolving classes against the target class loader when you shoudl have been resolving against the helper classloader? I'd liek to understand what you think is needed here. In paricular I'd like to avoid creating the helper loader if we can avoid it.. Postponing it after rule parsing avoids some unecessary creates.

         

         

        The Rule constructor calls Event.create() which uses the TypeGroup to resolve various types, potentially including types that do not exist in the target loaded but are IMPORTed. I can't recall exactly what I tried that triggered it, but I think something like creating a BINDing of such a type will do it.

         

        If we need typechecking to be able to see the imports, then the naive solution is to use the helper classloader since that lets us to it all in one place, at the cost of requiring it to exist earlier. Looking at the code now, I can't see why it would have been required prior to typechecking on the first execution, so I'll need to try it without the change, and make sure I add better notes to the code as to why, or see if I can find a way to keep it delayed.

         

        in the constructor prior to the Event at least

         

        I'm not sure I understand what you mean by that. The constructor for what? and hwo prior to the Event?

        Sorry for not being clear - the Rule constructor's call to Event.create().

         

        I think we should resolve names

        against the target context first and only after that fails attempt to
        resolve against the imported contexts. The rule code is meant to be
        thought of as embedded into the target method. So, the primary meaning
        of symbols in that code should be resoloved via that injection context.
        Imports are intended to provide for additional resolution rather than
        alternative resolution. What do you think?

        I'm fine with that.

         

        I can currently see the following sub-tasks still to be completed

         

        1. add support for using a module plugin via bminstall
        2. document how to use the module plugin mechanism i.e. use relevant bminstall option or specify relevant -javaagent option
        3. document how, specifically,  to use the JBoss modules plugin
        4. more comprehensive test cases for null plugin?
        5. test cases for use of jboss modules plugin?
        6. enable bmcheck to check rules using jboss modules imports
        7. test cases for bmcheck of rules with jboss modules imports
        8. enable maven rulecheck plugin to check rules using jboss modules imports
        9. test cases formaven rulecheck plugin check of rules using jboss modules imports

        I am happy to do the documentation tasks. Where do you think we stand with regards to 4 or 5? -- more tests is never a problem :-) I

        am not sure how to do tasks 6 - 9. Currently, the rule checker loads

        class bytecode from the classpath (system loader) as a resource and then

        passes it through the transformer by hand.It then type checks any

        resulting injected rules with type resolution happening via the system

        loader. I think we need to do somethign similar but ensure we use the

        correct module loader. So, what I think what is needed is

        1. start
          the rule checker inside a JBoss Modules-based deployment (I thinkthat
          just means insert -jar /path/to/jboss-modules.jar into the java command
          line)
        2. point the JBoss Mdule scode at a modules.xml and associated modules hierarchy
        3. pass
          the name of one or more modules to the checker class and have it try
          the resource load relative to the module loader identfiied by that name

         

        Could
        you look into the JBoss Modules code and/or contact David Lloyd to see
        what is possible here and whcek whether I am barking up the right/wrong
        tree.

        Luckily I've looked into JBoss Modules things before, so have a reasonable idea what's involved. For a simple modules deployment, you could do that or have some code which used the API to set it up the same way as the modules main() does.

         

        If what you want to do is check something like Wildfly/JBoss it's going to be more complicated. They support multiple modules root for overlays (for patches) and derived layers, which is set up by some configuration files in the modules directory which WF reads.

         

        If you want to target deployment code, you also need to either manually specify everything, or give it some smarts to know the structure of EE deployments and implicit module dependencies, and that's before you get to things like EE deployments using classes from other deployments like Resource Adapters. Doing that would mean duplicating all WF's logic that handles it, both error prone and fragile, so probably isn't feasible. It may be possible to make bmsubmit push the rules to a running agent for checking but not installation, which may be both simpler and less fragile.

         

         

         

        For testing, I'm still not sure what to do. For the null plugin, we want everything to continue to work exactly the same, except that if you use an IMPORT it fails. Testing the JBoss Modules plugin would probably require a reasonable amount of work to set up test harness code, but should be possible.

        • 16. Re: Byteman vs JBoss Modules classloading
          jameslivingston

          Now I remember - TypeGroup's constructor takes the classloader as a parameter, which is used for finding the classes. The alternative would be to leave the construction of the helper in Rule.typeCheck() and then pass the helper loader into TypeGroup.resolveTypes() to pass along to Type.resolve() rather than the target loader that resolveTypes() currently passes to resolve().

           

          That could potentially cause consistency problems unless:

          1) TypeGroup.resolveTypes() called Type.resolve() with the target loader first, and then if it was still undefined tried with the helper loader, or

          2) There was the written rule that the helper loader MUST return the same Class as the target loader if it is visible there.

           

          Either of those forces us to the "prefer target classes over imported classes" option, but it sounds like we wanted to go with that choice.

          • 17. Re: Byteman vs JBoss Modules classloading
            adinn

            Hi James,

             

            Hope you had a good holiday! Good to have you back.

             

            James Livingston wrote:

             

            Now I remember - TypeGroup's constructor takes the classloader as a parameter, which is used for finding the classes. The alternative would be to leave the construction of the helper in Rule.typeCheck() and then pass the helper loader into TypeGroup.resolveTypes() to pass along to Type.resolve() rather than the target loader that resolveTypes() currently passes to resolve().

             

            Yes, a Rule initialises it's typegroup using the loader passed when it is created. The first point where a rule is created is in TransformContext.parseRule() which is called under the Transformer's transform (agent API) callback. The direct caller is TransformContext.transform() and this happens the target class/interface mentioned in a rule script is matched against a potential trigger class. parseRule() creates a Rule instance as a side-effect of parsing the script.

             

            If TransformContext.transform() sees a successful parse then it goes on to check the class and that involves checking one or more matching methods. A  method check adapter reuses an existing parsed rule if it has not already been grabbed. Alternatively, it creates a new rule (again calling Rule.create) and indexes it in the TransformContext using the target method name+descriptor. If/when a method trigger adapter gets created the rule is retrieved and unindexed. After successful injection the rule is cached in the Rule map using a key generated by the trigger adapter. The same key is inserted into the injected code so it can idenitfy the correct rule at trigger time.

             

            I don't think the Rule actually really needs to populate the typegroup with types identified via the helper loader until much later -- essentially only when we reach type check time. The adapters do perform operations which employ type names and I think in some special cases they may even try to resolve those names to classes. But the classes involved should only be ones which are referenced from the trigger method bytecode and hence they shoud be visible in the trigger method loader.

             

            So, I think we can get by by continuing to use the trigger class loader up to the point where the rule is triggered. At that point (i.e. inside ensureTypecheckCompiled()) we can update the Rule (which will, in turn, have to update its typegroup) to use the helper loader before we ask it to do any type checking.

             

            One way to (partially) check this would be to change the rule code so it only creates the typegroup under ensureTypecheckCompiled() -- it can jst set the fiels to NULL in the constructor. If this breaks then I am missing something but I think it will probably work ok.

             

            James Livingston wrote:

             

            That could potentially cause consistency problems unless:

            1)
            TypeGroup.resolveTypes() called Type.resolve() with the target loader
            first, and then if it was still undefined tried with the helper loader,
            or

            2) There was the written rule that the helper loader MUST return the same Class as the target loader if it is visible there.

             

            Either
            of those forces us to the "prefer target classes over imported classes"
            option, but it sounds like we wanted to go with that choice.

             

             

            I don't think either of these problems will bite us. So long as the helper loader always tries to resolve a class via the trigger class loader before falling back to any imported class loaders we will get consistent results.

            • 18. Re: Byteman vs JBoss Modules classloading
              adinn

              Regarding checking of rule sets with JBoss module imports from either bmcheck or the maven rulecheck plugin:

               

              1) You know more than I do so I will leave you to propose one or more implementations and then I'll see if I can pick holes in it :-)

               

              2) I would really like the rule check program to be able to be set up so that it uses the same classloader setup as will be in place when the code is actually deployed.

               

              3) In theory we need to deal with A: apps which might use JBoss modules outside of an App Server as well as B: apps which are deployed to an app server.

               

              4) In practice I suspect A constitutes the empty set so maybe we don't need to worry about it.

               

              5) If EAP/WF monkeys about with multiple module roots et al do we really need to care about that? Do you hav eany idea how signiifcant the monkeying around is likely to be for most of the rules people are likely to want to inject?

               

              6) Similary, if we ignore some/all of the automatic dependencies which Wdlfly injects how likely is that to cause a type resolution issue? Can we provide some way of specifying the extra dependencies as inputs to bmcheck/rulecheck plugin

               

              7) If any of this does matter would any of it be helped by pointing bmcheck/rulecheck plugin at an EAP install so they can replicate (at least) the easy to patch parts of the setup?

              • 19. Re: Byteman vs JBoss Modules classloading
                jameslivingston

                The set people using JBoss Modules outside of an app server may be small or empty, but that's also the relatively simple case to implement. JBoss/WildFly on the other hand, not so much.

                 

                 

                Consider the common case of someone deploying a WAR to JBoss, and they want to inject into a servlet's doGet() method. How does ByteMan find the HttpServletRequest class?

                 

                JBoss automatically adds the 'javax.servlet.api' module based on the fact that it is a WAR deployment. Similarly other module dependencies can be added based on the presence of deployment descriptors (beans.xml for CDI), the content of deployment descriptors (in non-trivial ways), and the server configuration profile. All of that can also be overridden by a jboss-deployment-structure.xml file. WARs also have the contents of the jars in WEB-INF/lib loaded too.

                 

                Assume we can figure out we need the 'javax.servlet.api' module, where do we load it's jars from? In a base JBoss installation it's in under modules/system/layers/base/, but if you have used the patch mechanism, it may be under one or more of modules/system/layers/base/.overlays/$OVERLAY/ (details stored in modules/system/layers/base/.overlays/.overlays). EAP 6 intentionally corrupts a bit in the original jar so they can't be loaded accidentally, so you can't just use the original for offline checking aside from differences causing problems. WF 10 and EAP 7 do not do that (since it cause other issues), so we can't safely just load them all and use whatever works. For derived products like RH JPP and FSW, you may also need to look under other modules/system/layers/$LAYER directories based on modules/layers.conf, with each layer also potentially having their own overlays. Users can also create custom modules directly in modules/. So in summary we may need to use modules as a module root, as well as zero or more modules/system/layers/$LAYER based on modules/layers.conf and zero or more modules/system/layers/$LAYER/.overlays/$OVERLAY based on modules/system/layers/$LAYER/.overlays/.overlays

                 

                Next consider when you have an EAR deployment. All sub-deployments (WAR, EJB-JAR) have classes in library jars (specified in application.xml) visible. Specific sub-deployment may also have utility jars somewhere in the EAR or EJB-jars visible based on their Class-Path MANIFEST.MF header. The EE spec explicitly notes that sub-deployment may or may not have classes from un-referenced EJB-jars available, and this does in fact vary between servers - JBoss 5 and 6 do the opposite here by default but both can be overrides globally and on a per-deployment basis.

                 

                Then up comes other deployments, such as JDBC drivers. The spec requires that classes belonging to a resource adapter that is used by an application are made available to an application, so the app code can potentially case Connection to OracleConnection, and that RAR is potentially another deployment and not a static module. Whether classes outside of WAR sub-deployments from one EAR are available to another EAR are again explicitly unspecified by the spec, with different servers (and version of JBoss) behaving differently.

                 

                 

                I know this kind of thing causes problems for the Eclipse server adapters and class library, which wants to find out which jars contain the API classes for a given deployment, and my understanding is that it doesn't work well and keeps breaking when things change.

                 

                Forcing people to specify imports is probably the only workable solution short of talking to a JBoss instance that has the deployment running. In practice it may not be a major issue, pulling in "javaee.api" should get most of the APIs people use transitively, which just leaves the problem of finding the correct module roots and deployment libraries where it's a WAR/EAR.

                • 20. Re: Byteman vs JBoss Modules classloading
                  adinn

                  Hi James,

                   

                  The set people using JBoss Modules outside of an app server may be small or empty, but that's also the relatively simple case to implement. JBoss/WildFly on the other hand, not so much.

                  . . .

                   

                   

                  Well, the rest of that made depressing reading :-)

                   

                  Ok, so it's going to be very difficult to ensure that we can recreate the class loader set up of deployed EAP/WF apps in order to be able to check rules with IMPORT statements or even rules for classes whch expect implicit imports other than by actually running up an app server. But the whole point of the check code is to be able to typecheck without actually having to execute code. Byteman normally relies upon app execution to load classes and trigger injection.. The problem with that when it comes to checking rules is that there is no guarantee that a specific app run will trigger loading of all the relevant classes. The offline checker finesses that problem by loading  target class bytecode (where it can) and then pushing the bytecode through a transformer. Typecheck then uses the load resolution mechanism. An equally important reason for following this approach is to avoid broken rules leading to errors in the app or the underlying app server/JVM code.

                   

                  So, if we cannot feasibly recreate the actual class loader set up then I guess we'll have to start faking it?

                   

                    https://www.youtube.com/watch?v=AcJ_yITF9so&feature=youtu.be&t=71  ;-)

                   

                  Below are few thoughts on how we might do that.

                   

                  What we really need to be able to do is

                   

                  1.   load bytecode for whatever TARGET classes are mentioned in CLASS/INTERFACE clauses
                  2.   resolve references to other classes referenced in rule bodies (BIND/IF/DO)

                   

                  If we can, for the most part, manage to do that correctly then we don't really need to worry too much about how the classes get loaded.

                   

                  At present, when no module system is in use, the checkers manage to find TARGET classes because they are in the classpath. bmcheck needs to be fed -cp xxx -cp yyy arguments to point at the relevant jars. The maven plugin relies on dependencies configured in the pom to populate the classpath with the relevant jars. So, the status quo works by users engineering -- relatively simply -- the relevant class visibility.

                   

                  So, the question is what do we need to do to make both these things work correctly when the rules are written for use in an EAP/WF deployment?

                   

                  The cheapest solution is to do almost nothing:

                   

                  1. Clearly, we can get the TARGET bytecode lookup to work if jar files are inserted into the classpath. Of course, if war or ear files are used in the deployment then this is not really going to work correctly (or do wars have some manifest entry which means that resource lookups and class loads will go via the relevant path?)
                  2. If we were to ignore IMPORT statements under the checker (use the null module checker in a "no error or warning" mode) and simply require the relevant module-specific jars to be added to the classpath then that would allow resolution of the classes that IMPORT would normally make available. In some cases it might cause version conflicts or make some classes visible which ought not to be visible but that will probably be the rare case. It would be better if the relevant module jars came after other jars in the classpath so as to try to enforce a correct ordering.

                   

                  A nicer alternative would be to provide extra config options for module system-specific rule sets allowing the user explicitly to configure sets of modules or jars to be used to resolve classes which would normally be imported automatically or via IMPORT statements.

                   

                  So, if, for example, the TARGET classes for a rule script are in a jar from module X that imports some other modules Y, Z, etc.  then we could allow the user to specify that dependency to the checker i.e. by pointing it at a jar + module combination (or maybe just a jar + jars combination) identifying the target + related classes. The implication would be that the checker should build a module loader around that configuration and use that module loader to do bytecode loading and resolution at typecheck. Where a dependency is atuomatucally added by EAP/WF then the user would have to add it by hand.

                   

                  The same sort of configuration approach could be used to allow IMPORT statements to be managed. For any given target on the right hand side of the IMPORT keyword the configuration could define where to find modules on disk or jars in the classpath that should be used to populate a module loader used for delegation.

                   

                  We could eventually deal with TARGET classes in war and ear jars by having the checker create a slightly smarter loader that knows about war or ear structure. However, I don't think wars or ears a a big deal. Most users who are injecting into ear or war code will probably be building that ear/war out of their own app code (possibly importing some embeddeed jars. So, they can either directly access the ear/war code in their build tree or can reference embedded jars via maven dependencies.

                  • 21. Re: Byteman vs JBoss Modules classloading
                    jameslivingston

                    Andrew Dinn wrote:


                    One way to (partially) check this would be to change the rule code so it only creates the typegroup under ensureTypecheckCompiled() -- it can jst set the fiels to NULL in the constructor. If this breaks then I am missing something but I think it will probably work ok.

                     

                    Testing it is used earlier, but I think only I think by ExpressionHelper , and only for TypeGroup().createArray(Type.OBJECT) in a few DOLLAR case branches. Unless we want to provide a static Type for Object arrays, we can probably just leave the type group creation where it is and switch the loader later, it just means any problems it causes may be less obvious.

                    • 22. Re: Byteman vs JBoss Modules classloading
                      adinn

                      James Livingston wrote

                       

                      Testing it is used earlier, but I think only I think by ExpressionHelper , and only for TypeGroup().createArray(Type.OBJECT) in a few DOLLAR case branches. Unless we want to provide a static Type for Object arrays, we can probably just leave the type group creation where it is and switch the loader later, it just means any problems it causes may be less obvious.

                       

                      Ok, James, thanks for finding that. Yes, please tweak the code so that any new loader created at typecheck time gets poked into the TypeGroup. I really don't think this is going to break anything -- I think (hope :-) we will find out quick if it does.

                      • 23. Re: Byteman vs JBoss Modules classloading
                        jameslivingston

                        I've just pushed some updates to https://github.com/doctau/byteman/tree/module-system.

                         

                        It seems to be working reasonably well for me with no error

                        • Current tests pass
                        • Some existing scripts work without a module system loaded
                        • Some existing scripts (without IMPORT) work with the JBoss modules system loaded
                        • Some IMPORT-using rules work with the JBoss modules system loaded, provided it's in the sys classloader not the boot one.
                        • Byteman in the boot classloader and the modules plugin in the sys loader also works.

                         

                        Putting the JBoss module system in the bootloader doesn't work because it can't see JBoss Modules, but I can't imagine that's a huge limitation since all it means is that you can't use IMPORT in a rule that may trigger on boot loader classes.

                         

                        We still need to write some things for the docs (adding "sys:byteman-jboss-modules-3.0.3-SNAPSHOT.jar,modules:org.jboss.byteman.modules.jbossmodules.JBossModulesSystem" and IMPORT).

                         

                        I'm also still not sure what to do about tests. There isn't much you can add a test for without a module system apart from that you can't use IMPORT. I could probably pull a version of JBoss modules in as a dependency, and set up some simple modules to try it out.

                        • 24. Re: Byteman vs JBoss Modules classloading
                          adinn

                          Hi James,

                          James Livingston wrote:

                          I've just pushed some updates to https://github.com/doctau/byteman/tree/module-system.

                           

                           

                          It seems to be working reasonably well for me with no error

                          • Current tests pass
                          • Some existing scripts work without a module system loaded
                          • Some existing scripts (without IMPORT) work with the JBoss modules system loaded
                          • Some IMPORT-using rules work with the JBoss modules system loaded, provided it's in the sys classloader not the boot one.
                          • Byteman in the boot classloader and the modules plugin in the sys loader also works.

                          Ok, thanks for the heads up. Excellent work.

                           

                          Putting the JBoss module system in the bootloader doesn't work because it can't see JBoss Modules, but I can't imagine that's a huge limitation since all it means is that you can't use IMPORT in a rule that may trigger on boot loader classes.

                          Ah, I think I just worked out how you did this. I assume you are loading the modules plugin from agent.Main (which, of course, is loaded via the system loader). So long as this class is loaded by name (rather than imported) and only loaded after the Byteman jar has been hoisted into the bootstrap path that's ok.

                           

                          I don't understand why this means that rule code injected into bootstrap classes cannot use IMPORT. Not that I am disagreeing with that you; I just don't follow how this works out. Can you explain?

                          We still need to write some things for the docs (adding "sys:byteman-jboss-modules-3.0.3-SNAPSHOT.jar,modules:org.jboss.byteman.modules.jbossmodules.JBossModulesSystem" and IMPORT).

                           

                          Ok, except that we need to couch this in terms of a more general model with JBoss Modules as the first implementaton -- OSGi to follow. We probably also need a tutorial to explain 1) the sort of circumstance where you need this (e.g. you want your EJB rule to print TX stats, you want your EJB helper to have access to Transaction formatting methods) and 2) how you would write your rules, how you might package and deploy your helper either via sys: or via its own module).

                           

                          Anyway, hold off on updating the docs just now. Marco Rietveld may well be updating them to Asciidoc just now (which will make life a whole lot easier). We might even usefully merge and release a SNAPHOST -- or even, say, 3.0.3 -- without docs so we can get some alpha level feedback from selected JBoss users.

                          I'm also still not sure what to do about tests. There isn't much you can add a test for without a module system apart from that you can't use IMPORT. I could probably pull a version of JBoss modules in as a dependency, and set up some simple modules to try it out.

                           

                          I think that would be a very good idea. If you can do it without busting a gut then do it. If it turns out to be really hard then you can always shelve it for now and we will return to it later.

                           

                          One other thing that we really need is to allow the rule checker to gracefully ignore IMPORT statements (since it seems we cannot really make it process them properly). So, it would be good if there was some way for the rule checker to configure the agent in a mode where it throws away IMPORT statements. This will probably mean that the rule checks then fail. However, if the user can work out a way to add the necessary classes to the classpath this could allow rules with IMPORT to be checked.

                           

                          The reason I thnk we need to make this happen in the agent not the plugin is that it would be helpful if this mode generated a warning whenever an IMPORT was ignored. I am not completely sure what needs changing to allow warnings to propagate back through to the checker but the plugin is not really in a position to do this job. The IMPORT actually gets processed (as opposed to parsed and installed) at TypeCheck time, doesn't it? So maybe we could propagate a TypeWarning to the TransformContext at this point as happens currentlly when a non-fatal problem occurs during rule processing.

                          • 25. Re: Byteman vs JBoss Modules classloading
                            jameslivingston

                            I don't understand why this means that rule code injected into bootstrap classes cannot use IMPORT. Not that I am disagreeing with that you; I just don't follow how this works out. Can you explain?

                            Sorry, I probably should have explained it. JBoss Modules didn't seem to work properly when I tried to do that, but after some more investigation it was because the rule didn't trigger where I thought it did. It breaks if an IMPORT-using rule is parsed and checked prior to JBoss modules initialising, for obvious reasons.

                             

                             

                            For IMPORT during checking, the exception is currently triggered when Rule asks the module system to create it's loader, which now occurs in Rule's constructor since I moved it earlier (when there is a helper, imports, or we're compiling to bytecode. The simplest way to have a warning would be to make RuleCheck install a variant of NonModuleSystem that emits a warning rather than throwing an exception. I quickly did that by having it call Rule.warning(), but I'll see if we can do it a better way.

                             

                            I've managed to get JBoss Modules and Failsafe working together well enough to run a copy of one of the existing tests with failsafe in a modules environment, although all failures within a TestCase are reported as one failure for now, since I have junit in multiple class loaders and it's a lot of reflection work to convert TestResult objects across. Adding some tests for module-related functionality is the next step.

                            • 26. Re: Byteman vs JBoss Modules classloading
                              adinn

                              James Livingston wrote:

                               

                              Sorry, I probably should have explained it. JBoss Modules didn't seem to work properly when I tried to do that, but after some more investigation it was because the rule didn't trigger where I thought it did. It breaks if an IMPORT-using rule is parsed and checked prior to JBoss modules initialising, for obvious reasons.

                               

                              Ah, yes of course -- IMPORT rules now have dependencies, albeit runtime ones. We will need to document this issue well.

                               

                              This is also going to be an issue when users deploy their helper classes via modules. If the target class/interface is not in a module then injection may fail should the target class get loaded before JBoss  Modules is ready. I am not sure how significant a limitation this is. Obviously, when a rule is being injected into a module-loaded class/interface then the module system will be up and running at rule create. So, the problem only happens when an IMPORT rule is being injected into a non-module class (sys or bootstrap). I would hope that it will be unusual for such rules to need a helper deployed in a module. Normally, this is done so as to link the helper to classes in modules related to that of the target class for the rule -- i.e. it means the target is also going to be in a module. It might occasionally be the case that the helper is dpeloyed this way because it needs a utility library which is only available in a module but I hope this will be uncommon.

                               

                              This will not be how it works for interface rules. For example, an interface may be defined by the JDK or in a sys path jar yet a rule may want to do something specific to a given module class implementation (e.g. it might need to filter the target instances using code provided by some imported module class). In that case injection failures will occur when trying to inject into implementation classes which are not in modules. However they should not occur when injecting into module classes which really are intended target. Also, that's maybe not the right way to write these rules. In these cases it might be better to target the actual implementation classes rather than try to inject via interfaces.

                               

                              So, I'm hoping all we have here is a documentation and education issue rather than a problem with function.

                               

                              James Livingston wrote:

                               

                               

                               

                               

                              For IMPORT during checking, the exception is currently triggered when Rule asks the module system to create it's loader, which now occurs in Rule's constructor since I moved it earlier (when there is a helper, imports, or we're compiling to bytecode. The simplest way to have a warning would be to make RuleCheck install a variant of NonModuleSystem that emits a warning rather than throwing an exception. I quickly did that by having it call Rule.warning(), but I'll see if we can do it a better way.

                               

                              I've managed to get JBoss Modules and Failsafe working together well enough to run a copy of one of the existing tests with failsafe in a modules environment, although all failures within a TestCase are reported as one failure for now, since I have junit in multiple class loaders and it's a lot of reflection work to convert TestResult objects across. Adding some tests for module-related functionality is the next step.

                               

                              Not sure what Rule.warning() is. Do you mean RuleScript.notifyFailedTransform()? Anyway, it sounds like you know what is needed better than I do so I'll leave you to sort this out.

                              James Livingston wrote:

                               

                               

                              I've managed to get JBoss Modules and Failsafe working together well enough to run a copy of one of the existing tests with failsafe in a modules environment, although all failures within a TestCase are reported as one failure for now, since I have junit in multiple class loaders and it's a lot of reflection work to convert TestResult objects across. Adding some tests for module-related functionality is the next step.

                               

                              Ok, let me know when you need me to review the tests and then we'll see if we can push your changes up to the repo.

                              • 27. Re: Byteman vs JBoss Modules classloading
                                jameslivingston

                                JBoss Modules didn't seem to work properly when I tried to do that, but after some more investigation it was because the rule didn't trigger where I thought it did. It breaks if an IMPORT-using rule is parsed and checked prior to JBoss modules initialising, for obvious reasons.

                                JBoss Modules doesn't have any flag to directly indicate that it is fully initialised, but looking at code we can easily detect if it is before or after the MBean server installation stage, which the last thing it does before invoking the application code, and that has been consistent from before 1.0 up to current master. I've added some code that looks at that (it doesn't load any classes that it hasn't loaded anyway) and emits a warning and falls back to non-modular behaviour if it's not set up. If anything goes wrong it emits a warning but continues in case the modules internals change.

                                 

                                I now have a test for using an imported class in a BIND downcast, and a test for importing the module containing the helper, both of which fail without the IMPORT statements.

                                 

                                 

                                The POM for the maven module that has the tests is a bit complex and repetitive, but I don't know if there's a lot that can be done about that and the agent's test setup is similarly repetitive. Maven could do with some abstraction support

                                 

                                 

                                Not sure what Rule.warning() is. Do you mean RuleScript.notifyFailedTransform()?

                                I meant RuleCheck.warning(). Too many class names in my head!

                                 

                                 

                                I've posted a PR at Module system by doctau · Pull Request #32 · bytemanproject/byteman · GitHub since I think it is complete enough for merging. Obviously there may be things to fix first.

                                • 28. Re: Byteman vs JBoss Modules classloading
                                  adinn

                                  HI James,

                                   

                                  All looks good so I pulled the PR into the master repo. I don't think the verbosity in the test pom is avoidable -- the agent pom is just as bad.

                                   

                                  I think we should push a 3.0.3 release i) for some power users to try out and ii) to smoke test it in case there are any unforeseen issues for non-module loader uses. We can push an 'advertised' release when we have updates to the Programmer's Guide and a tutorial to motivate the new functionality and show its use in, say, EAP.

                                  • 29. Re: Byteman vs JBoss Modules classloading
                                    jameslivingston

                                    That sounds good - especially people testing out running with the modules plugin against normal rules.