1 2 3 Previous Next 44 Replies Latest reply on Apr 4, 2017 11:53 AM by Fernando Miguelez

    Byteman vs JBoss Modules classloading

    Radek Koubský Newbie

      Hello Byteman community,

      there is a post about classloading Helper hits "argument type mismatch" on EAP

      I am facing the same problem with Wildfly 8.

       

      Has anybody made any progress on the proposed solution by Andrew Dinn?

       

      I would like to try to implement such solution for JBoss Modules. I have no idea how much time does it take, how complicated it is, but still I am curious.

      I went trough the whole call stack of installing my own Helper class when rule is executed and this is my naive assumption how it works:

      Byteman.jpg

      Thanks,

      Radek

        • 1. Re: Byteman vs JBoss Modules classloading
          Andrew Dinn Master

          Hi Radek,

           

          First off, no one has started working on a solution for this yet.

           

          Second, anyone who attempts it is going to need to allocate quite a lot of  time -- I estimated about 6 months for someone who does not know Byteman and at least 3 months for someone who knows it really well (i.e. me :-). Even then  it may not even be possible to implement what is really needed which may reduce the timescales to 2 (or 1) month but at the cost of failing.

           

          Third, your picture is sort of right as an account of what happens now but does not really make it clear what is going on. Here is a more precise account of how resoluton of rule code happens.

           

          1) When Byteman type checks a rule injected into method m of class C it resolves class names using the classloader Cl_C of the class C. So, the only way names occurring in the rule get resolved is if the class loader can see them. That includes the rule helper class H. If H is not visible to classloader Cl_Cthen the rule will fail to type check.

           

          2) When Byteman interprets rules injected into method m of class C it it does so using reflection, employing the methods and fields of classes identified at type check. So, interpretation of code injected into class C can only work if the classes mentioned int the rule are visible to  Cl_C.

           

          2) When Byteman compiles a rule injected into method m of class X it places the compiled bytecode into an automatically generated subclass Hs of the rule's helper class H. It uses a newly generated  classloader Cl_Hs to create this subclass and ensures that Cl_Hs  delegates to Cl_C. So essentially name resolution in compiled rules is exactly the same as for interpreted rules i.e. the compiled code can only refer to classes which are visible to Cl_C.

           

          If Cl_C is the bootstrap  loader then references to bootstrap classes by name can be resolved fine but names for classes deployed via the classpath will fail to resolve. So will references to classes deployed in modules. This is why you need to load your helper jar into the bootstrap path in order to inject into bootstrap classes like String, FileOutputStream etc.

           

          If Cl_C is the system loader then references to bootstrap classes or to other classes deployed via the classpath can be resolved fine. However, references to classes deployed in modules will still fail to resolve. This is why you need to install your helper jar into the system path when injectign into classes in the classpath

           

          If Cl_C is a module loader then you are at its mercy when it comes to resolving classes. Normally your rule will only be able to refer to classes which are not defined by Cl_c if the module loader explicitly imports system classes or other modules. That presents a problem for the Byteman agent classes because when the agent is installed the classes in the agent jar are loaded into the system loader and -- unless you go tinkering with the module spec for Cl_C so that it imports the Byteman classes they are not going to be visible. Nor will your helper class be visible.

           

          There is a get out of course.  JBoss Modules can be told  to delegate lookups for Byteman classes (so can OSGi) and indeed to do the same for your helper class. You just need to set the approprate  system property e.g. run with -Djboss.modules.system.pkgs="org.jboss.byteman.*,org.my.helper.*" So, the real classloader diagram is more like this

          BootLoader 
          |  \    \
          |  Thread . . .
          SystemLoader
          |  \    \      \
          |  Rule  Helper  MyHelper
          | org.jboss.*                                  \
          | org.my.*                                      | org.jboss.*
          | java.*  ModuleLoader M2  ModuleLoader M3      | org.my.*
          |        /    ____________/                    | java.*
          ModuleLoader M1                                ModuleLoader M4
          |  \  \  \
          |  C  C1  C2
          | *.*
          CompiledRuleLoader
            \
            MyHelper_Sub extends MyHelper
          
          RULE MyRule
          CLASS C
          METHOD add_a_c1(C1,int)
          HELPER MyHelper
          . . .
          
          
          
          
          
          
          
          


          So, when you tyepcheck or compile the rule using loader Cl_C you can refer to classes in M1, M2 or M3 and you can refer toByteman classes or class MyHelper. There are 2 problems with this setup.

           

          Firstly, your rule cannot refer to classes in some other module loader M4 which is not imported by M1 e.g. assuming M4 is the JBoss JTA implementation jar and M1 is an EJB jar then would not be able to check the state of a static like TransactionImple.activeTransactionCount.

           

          Secondly, your helper cannot refer to classes in M1. It has been placed in the system classpath and that means it cannot see module classes.

           

          Of course, you could deploy your helper in its own module M_H and have that module import M4 but then you still have the problem that  M_H is not visible from M1. So, you also need to alter the existing module M1 to make M_H visible.

           

          Now the suggestion for a Byteman import mechanism is to avoid the need to modify existing modules. So, where Byteman currently uses the classloader of the target class to typecheck and interpret a rule it would instead create a child classloader which merged other modules into the lookup path. The same option would be available with the child classloader used for compiled rules. So, for example, you could use the child to delegate requests to locate system classes or you could use it to import module M4 or your helper module M_H.

           

          BootLoader 
          |  \    \
          |  Thread . . .
          SystemLoader
          |  \    \ 
          |  Rule  Helper
          |
          | org.jboss.*                                  \
          | org.my.*                                      | org.jboss.*
          | java.*  ModuleLoader M2  ModuleLoader M3      | org.my.*
          |        /    ____________/                     | java.*
          ModuleLoader M1                                ModuleLoader M4    ModuleLoader M_H
          |  \  \  \                                    /    \  \          /      \
          |  C  C1  C2                                 /      C3  C4      /      MyHelper
          |              _____________________________/__________________/
          RuleModuleLoader
            \
            MyHelper_Sub extends MyHelper
          
          RULE MyRule
          CLASS C
          METHOD add_a_c1(C1,int)
          HELPER MyHelper
          IF C3.counter > 10
          . . .
          
          
          
          
          
          
          


          • 2. Re: Byteman vs JBoss Modules classloading
            Radek Koubský Newbie

            Hi Andrew,

            thank you for your comprehensive answer.

            6 months is really long time and I have to finish my master studies (actually in 6 months as well). So, I will keep using dollar expression workaround in my rules for now. Good luck with finding somebody who tries to implement it!

            • 3. Re: Byteman vs JBoss Modules classloading
              Andrew Dinn Master

              Hi Radek,

               

              Thank you in return for giving me the impetus to set out the problem and possible solution a bit more clearly. One of the very nice things about open source is that questions and answers don't just happen in a circle of one.

               

              The good news is that you probably needn't drop your master studies anyway -- I may have someone lined up for this task very soon.

               

              Can you tell me anything about what you have been using Byteman to do? It's always good to hear what users have done with it rather than just find out what they have not been able to do.

               

              regards,

               

               

              Andrew DInn

              • 4. Re: Byteman vs JBoss Modules classloading
                Radek Koubský Newbie

                You are welcome,

                somebody must have reopened the problem and it was my turn:)

                 

                I am using byteman in my master thesis which consists of two parts (links are projects on github):

                a) extending wildfly logging capabilities - I decided to use byteman (RadekKoubsky/byteman-wildfly-log · GitHub)

                b) sending logs from wildfly to elasticsearch cluster (RadekKoubsky/elasticsearch-wildfly-log · GitHub)

                 

                When you started discussion, I would like to ask if byteman is the best possible option for wildfly (specially for the classloading) or there is something else that can solve the clasloading problem e.g. Javassist (I have never used it).

                I am at the start of adding logs, so I am able to switch to another bytecode manipulation tool (I prefer byteman, it has good documentation and it is easy to understand, but I would like to know your opinion).

                • 5. Re: Byteman vs JBoss Modules classloading
                  Andrew Dinn Master

                  Hi Radek,

                   

                  Thanks very much for pointing me (and other forum readers) at your code and your rules.

                   

                  I think Byteman is probably as good a solution as any for what you are trying to do. If you try to use javassist or ASM to do your own  transformation you will still face the problem that the code you inject can only use methods which are visible from the module loader of the class you are injecting into . . .  a-and you'll have to do your own class transformation at the bytecode level rather than at the Java level. This would also be true if, say, you tried to use some other tool such as AOP to do the job.

                   

                  If you did decide to do your own transformation then you could achieve what you need by replicating the the sort of solution I am proposing. You would lneed to generate the code you want to inject into an auxiliary class and call it indirectly. The auxiliary needs to be created from a classloader which delegates both to the target class's loader and to a module loader for a module containing any other classes you want the auxiliary to be able  to link to (e.g. your current helper class). However, that requires you rebuilding a large slab of what  Byteman already implements (including the bytecode transformation code which is a very big task even if you don;t have ot build somethign as general purpose as Byteman). I think it would be far less work just fixing Byteman to support an import mechanism.

                   

                  The only advice I have to offer regarding your current solution is rather tentative since it may well not apply depending upon circumstances. If possible you should try to avoid using AT LINE xxx in your rules. Your rules will be much less fragile if you can use a location specifier based on a structural marker in the code (AT EXIT, AT CALL xxx, AFTER WRITE yyy 3, etc). I understand that sometimes the only way to target a specific injection point is using AT LINE and I also recognise that this advice doesn't really apply if you know you will only ever be targeting one specific release (where the line numbers are never going to change). But in general, consider that a structure based location specifier can only be invalidated when the target method is edited whereas an AT LINE specifier will be invalidated by any edit to the file which inserts or deletes a line preceding the trigger point. Using AT LINE is an easy habit to get into and that makes it a bad habit to have acquired when, say, you are implementing tests that you want to reuse across releases.

                   

                  regards,

                   

                  Andrew Dinn

                  • 6. Re: Byteman vs JBoss Modules classloading
                    Radek Koubský Newbie

                    Thank you for your advice.

                    You are right that the AT LINE locator is not good choice for reusability of rules across releases, I used it for the first time because it was the easiest way.

                    I definitely want to make the rules reusable in next releases of Wildfly (9 is out now), so I will replace the AT LINE with something suitable like AT INVOKE (btw I like the "count" parameter!).

                     

                    So, I am going to use Byteman for my logs with possibility of use the new feature in future.

                    When I find any problem I will make new thread in the user forum.

                    • 7. Re: Byteman vs JBoss Modules classloading
                      James Livingston Apprentice

                      I've been looking into implementing this, and had some discussion with Andrew via email, but it probably should have been here on the forum (oops).

                       

                      > The problem is basically that to typecheck rules, interpret rules,

                      > compile/run rules, and use a helper it may need to see additional

                      > classes. As far as I can tell from your explanation, they should all

                      > use the same set of visible classes, so having typechecking and

                      > interpreting use the helper-subclass loader ("Cl_Hs") would work, aside

                      > from it not existing yet at typechecking time.

                       

                      Yes, that's right the job merely requires providing each module system a

                      means of handing over a suitable classloader when it is needed. The

                      actual creation of the helper subclass will not actually require any change.

                       

                      The hard bit is to create the helper subclass in a module loader which

                      can see both the trigger class's module and the helper class's module.

                      But each module system provides a way of specifying module links so we

                      jsut need to gather the desired linkage and then get the module system

                      to support it.

                       

                      n.b. the helper class's module may already have imported the trigger

                      class module. For example, that would be needed if one (or some)of the

                      helper builtins accepted $this as an argument. But then again the helper

                      class's module may only need to import other modules. For example, the

                      helper builtins might only be passed primitive, String or List values

                      but one (or some) of them might want to be able to test or print the

                      state of current Transaction.

                       

                      > So we'd need a plugin system for creating that loader (and equivalent

                      > information for typecheck-time), with potential implementations for non

                      > -modular systems (equivalent to what we have now), JBoss Modules, OSGi,

                      > and Jigsaw. Optionally being able to auto-detect what impl to use.

                       

                      Yes, we need a level of indirection so that Byteman juts creates a

                      normal class loader by default but can use a module-loader specific

                      mechanism when a module system is in place in the runtime. If an IMPORT

                      statement is found in the body of a rule or at top level in a script

                      then we need a module loader which imports the requested modules. So a

                      module-system plugin will give us that level of indirection. This means

                      the current mechanism also needs wrapping up inside a plugin mechanism.

                      In fact that change should probably be committed as a preparatory step

                      (although, as always with a design problem, you may actually need to

                      implement a working solution before you know what to prepare for :-).

                       

                      Yes, the subclass loader needs to be created at type check time and then

                      used to create the subclass. I think that is already how it is done. If

                      not then only a minor tweak should be needed. The current code already

                      uses a special loader that delegates to the trigger class's loaded when

                      it creates the subclass. That is to avoid polluting the trigger class's

                      loader with a Byteman-generated class. This means that when a rule is

                      uninjected the subclass loader can be dropped and bothit and the

                      generated class can be garbage-collected.

                       

                      n.b. if a rule requires no IMPORTs then we probably don't need to

                      delegate to the module plugin -- we could just create a delagting loader

                      to inherit from the trigger class's loader. However, I think it would be

                      best to delegate anyway so the plugin manages all cases, even the

                      trivial ones. One reason for dong everything via the plugin is to keep

                      it uniform. In particualr, we will eventually need to support some sort

                      of lifecycle end callback -- when a rule is uninjected we should tell

                      the module loader that the corresponding module loader is no longer

                      needed -- and that will be easier if we don't have any special casing to

                      consider.

                       

                      I still am not sure what is possible as regards Jigsaw. I am sure we

                      need a mechanism to access classes across Jigsaw module boundaries but I

                      have not researched what runtime options we have for doing that. Anyway,

                      JBoss modules will be the first place to start.

                       

                      Auto-detection would be a nice add-on but for the first cut I suggest

                      that we use an agent-load time parameter to reset the default.

                       

                      > We'd also need some new rule syntax for adding imports to the data that

                      > gets handed to the plugin to create it. I don't think the details of a

                      > "IMPORT MODULE ..." would need to be the same since the module systems

                      > are different, but obviously we wouldn't add unnecessary differences.

                       

                      Yes, I think as far as user visible changes go we just need to support

                      an IMPORT statement. Any text following the IMPORT keyword (up to end of

                      line) would be module-system specific text identifying a single module

                      to be imported into the helper subclass's loader.

                       

                      An IMPORT could occur in the body of a rule, say in the same position as

                      the HELPER clause between METHOD and LOCATION clauses, in which case it

                      applies just for that rule. It could also occur at the top level in a

                      script, in which case applies to all subsequent rules in script.

                       

                      Multiple IMPORT statements, both within a rule and at top level, would

                      accumulate. So, the plugin needs to be passed a list of String in the

                      request for a loader.

                       

                      The current set of top-level imports could be emptied by a top-level

                      IMPORT statement with no trailing text (other than white space). That's

                      similar to how the HELPER setting currently works. it would probably

                      also be be legitimate to use an empty IMPORT statement as the first

                      IMPORT in a rule body to cancel the top-level imports just for that rule.

                       

                      I agree with making the plugin handle all cases, whether IMPORT it used or not.

                       

                       

                      Obviously what is needed will change as problems are discovered during development, but as a first pass interface the plugin API could look something like:

                      void init(String args); // allow parameters to be passed via javaagent string

                      Class createRuleAdapter(ClassLoader triggerLoader, String[] imports, String helperName, byte[] helperBytes);

                      void destroyRuleAdapter(Class klass);

                      The no-modules implementation being "return (new ClassbyteClassLoader(triggerClassLoader)).addClass(helperAdapterName, classBytes);" and no-ops for the other two method.

                       

                      The method to destroy the adapter may be needed or useful for some module systems. We might need to pass the Rule or some other identifier to the create and destroy methods so that the implementation can identify which is which properly.

                       

                       

                      Obviously byteman will need to load the plugin implementation, so how is something we need to think about. In the case of JBoss Modules, a plugin will obviously need to use the modules API which should be in the system classloader. One obvious option is to require the plugin implementation to be visible to the system classloader and have the class name specified via the javaagent options (and bminstall script option). Another way would be to pass the jar name and read something out of META-INF but that would limit it to one plugin implementation per jar.

                       

                      Related to that, would we want to ship our implementations in the main byteman jar (requiring all dependencies at compile time) or as separate jars (needing more configuration to use). We should support loading them from a jar for external plugin implementations, but our ones could go either way.

                      • 8. Re: Byteman vs JBoss Modules classloading
                        Andrew Dinn Master

                        Obviously what is needed will change as problems are discovered during development, but as a first pass interface the plugin API could look something like:

                        void init(String args); // allow parameters to be passed via javaagent string

                        Class createRuleAdapter(ClassLoader triggerLoader, String[] imports, String helperName, byte[] helperBytes);

                        void destroyRuleAdapter(Class klass);

                        The no-modules implementation being "return (new ClassbyteClassLoader(triggerClassLoader)).addClass(helperAdapterName, classBytes);" and no-ops for the other two method.

                         

                        Oh, yes, a plugin init method is a good idea.

                         

                        I am not sure about the other two methods though. I have reviewed the current code and I believe the creation of the loader and the RuleAdapter class needs to be done as two separate steps.

                         

                        Currently a rule is type-checked and then compiled the first time the rule is triggered by a call to Rule.ensureTypeCheckedCompiled().

                         

                            private synchronized boolean ensureTypeCheckedCompiled()
                            {
                                if (checkFailed) {
                                    return false;
                                }
                        
                                if (!checked) {
                                    // ensure we don't trigger any code inside the type check or compile
                                    // n.b. we may still allow recursive triggering while executing
                                    boolean triggerEnabled = false;
                                    String detail = "";
                                    try {
                                        typeCheck();
                                        compile();
                                        checked = true;
                                        installed();
                                    } catch (TypeWarningException te) {
                                    . . .
                        

                         

                        Rule.typecheck() ensures that all type references in the rule code can be resolved relative to the trigger class's loader. It also ensures that all the elements of the BIND, IF and DO clauses are labelled with a correct value type.

                         

                        Rule.compile() assigns a HelperAdapter class to the rule's helperImplementation field. It simply uses InterpretedHelperAdapter if the rule is just using the default helper and is not compiled to bytecode. That avoids the cost of creating a classloader and RuleAdapter helper subclass in the common case ( I think  we need to continue to avoid this overhead so, contrary to what I suggested earlier, this is one case where we won't want to call out to the plugin). Otherwise, it generates  a RuleAdapter helper subclass. In both these current cases type checking  proceeds using the trigger class loader to recelve class references but in the second case it would be just as valid to use the loader of the adpater class.

                         

                        When we switch to using a module plugin then the current situation is no longer valid. We can only use InterpretedHelperAdapter if we have the defautl helper, no compilation to bytecode and no imports. In all other cases we need to generate a RuleAdapter subclass. The presence of imports means we have to typecheck using a generated loader rather than the trigger loader. We may not have any imports but we shoud use the generated loader anyway so we have only one special case (helperImplementation == .InterpretedHelperAdapter).

                         

                        Now, theproblem with your suggested API is that we cannot create the helper subclass until the rule has passed typecheck. That's because we may need to generate an implementation for execute0() and can only do that if we have the required, correct type info. However, except for the basic common case we need to  generate a loader before we can start typecheck. So, we need to create the loader first and then use it to create the RuleAdapter helper subclass later i.e. the API needs to be

                         

                        void init(String args); // allow parameters to be passed via javaagent string

                        ClassLoader createLoader(ClassLoader triggerLoader, String[] imports);

                        void destroyLoader(ClassLoader helperLoader);

                        Class createRuleAdapter(ClassLoader helperLoader, String helperName, byte[] helperBytes);

                         

                        The plugin will have to provide its own equivalent of ClassbyteClassLoader to expose the defineClass API of whatever module-specific loader it implements.

                         

                        Obviously byteman will need to load the plugin implementation, so how is something we need to think about. In the case of JBoss Modules, a plugin will obviously need to use the modules API which should be in the system classloader. One obvious option is to require the plugin implementation to be visible to the system classloader and have the class name specified via the javaagent options (and bminstall script option). Another way would be to pass the jar name and read something out of META-INF but that would limit it to one plugin implementation per jar.

                         

                        Related to that, would we want to ship our implementations in the main byteman jar (requiring all dependencies at compile time) or as separate jars (needing more configuration to use). We should support loading them from a jar for external plugin implementations, but our ones could go either way.

                         

                        I think module system-specific plugins need to be shipped as a separate jar.. They can be made available by adding the jar to the system or bootstrap classpath (using -javagent boot:: or sys: options so they are loaded into the same space as Byteman) and passing the name of a module plugin class to the Byteman agent as a javaagent option. The manager needs to implement the API above as instance methods. Byteman will need to load the module plugin class and stash away an instance at startup in a place where the rule code can access it. By default, Byteman will simply create an instance of an internal class which implements the current behaviours.

                         

                        If the plugin needs access to module system-specific classes then Byteman can arrange for that by passing the plugin instance a handle which provides access to the class base (a wrapper around the Instrumentation instance). Since the plugin will be in the same protection domain as Byteman it should be able to look up module loader management classes and do whatever it wants with them using reflection and/or suitable classloading trickery :-). I am sure what is needed will become clearer when you try to implement the JBoss Modules-specific plugin.

                        • 9. Re: Byteman vs JBoss Modules classloading
                          James Livingston Apprentice

                          Makes sense, thanks Andrew.

                          • 10. Re: Byteman vs JBoss Modules classloading
                            James Livingston Apprentice

                            I've pushed some initial stuff up to doctau/byteman at module-system · GitHub, as a proof of concept. I just ran a rule which intercepted a class in the 'org.jboss.as.server' module of JBoss which used referred to a class in the 'org.hibernate' which fails if you don't add a "IMPORT org.hibernate" line and append "sys:$PATH/byteman-jboss-modules-3.0.1.jar,modules:org.jboss.byteman.modules.jbossmodules.JBossModulesSystem " to the agent options

                             

                            There's a lot of work to do to make it handle classes safely, deal with errors, adhere to code style and so on, but the amount of code involved isn't actually that large.

                            • 11. Re: Byteman vs JBoss Modules classloading
                              Andrew Dinn Master

                              I've pushed some initial stuff up to doctau/byteman at module-system · GitHub, as a proof of concept. I just ran a rule which intercepted a class in the 'org.jboss.as.server' module of JBoss which used referred to a class in the 'org.hibernate' which fails if you don't add a "IMPORT org.hibernate" line and append "sys:$PATH/byteman-jboss-modules-3.0.1.jar,modules:org.jboss.byteman.modules.jbossmodules.JBossModulesSystem " to the agent options

                               

                              James, that is truly awesome progress in such a short space of time. Congratulations! and mega-kudos :-]

                               

                              I'm afrraid I am going to be away on holiday for two weeks starting Friday (that's why the next talk is this Thursday). So, I don't think I'll be able to give this a thorough review. But I will take a good look and see if I think there is anything I can spot that might need revising (I have given it a quick scan and it certainly looks right and very clean).

                               

                              There's a lot of work to do to make it handle classes safely, deal with errors, adhere to code style and so on, but the amount of code involved isn't actually that large.

                               

                              Hmm, aren't both of those things inevitably true of something which has been nailed -- especially the latter (although, the same can also be said of many things which are not right :-).

                              • 12. Re: Byteman vs JBoss Modules classloading
                                Andrew Dinn Master

                                Hi James,

                                 

                                The code is looking very good. I'll see if I can giev ti a fine-tooth comb review tomorrow for detaled and low-impact coding issues but in terms of the design and the overall functionality it looks really good.

                                 

                                The one thing I identified that we need to think about is how to give the offline/maven plugin type checkers access to a module system that allows them to check rules using imports (it's fine for now to use an empty module system).

                                 

                                Also, we need to think how we can provide some basic testing of the module functionality as part fo the build.

                                 

                                Otherwise, awesome work.

                                 

                                regards,

                                 

                                 

                                Andrew Dinn

                                • 13. Re: Byteman vs JBoss Modules classloading
                                  James Livingston Apprentice

                                  Some changes are up now, including using reflection in Main so it works properly when in the bootstrap loader. 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. I need to check that it is both early enough and that it doesn't depend on anything yet to be set up.

                                   

                                  On type resolution, there is the question of what to do if the target class' loader and an import contain identically named classes. My first though was that 'local' classes should win over imports, but that may lead to problems.

                                   

                                  Since a rule may be applied to multiple classes, they may not see the same type for a given name. That happens now, but it is consistent since it always uses what the target class sees. If you import a module and refer to a class from it, you may want to use that imported class and not have the rule broken if the target class' loader happens to have one of the same name. On the other hand, maybe you really do want to refer to a target loader class and preferring imports would mean you can't do that. Making it configurable would be technically easy, but may start down a rabbit hole of complex settings to indicate what you mean, which I'd prefer not to do.

                                  • 14. Re: Byteman vs JBoss Modules classloading
                                    Andrew Dinn Master

                                    Hi James,

                                     

                                    Sorry for the delay -- lots to catch up on after getting backfrom holiday.

                                     

                                    using reflection in Main so it works properly when in the bootstrap loader

                                     

                                    Yes, that looks good.

                                     

                                    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.

                                     

                                    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?

                                     

                                    On type resolution, there is the question of what to do if the target class' loader and an import contain identically named classes. My first though was that 'local' classes should win over imports, but that may lead to problems.

                                     

                                    It think this is potentially a problem whichever way it happens. Also, it is a problem that a module system can already face -- we are not intiorducing anything radically new here. In many cases it won't matter which way a name is resolved because the same org.my.Foo will be found by delegation through either class loader. The case where there are two versions on the two delegation paths will most likley be a versioing clash and we can't really fix that.

                                     

                                    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?

                                     

                                    As it stands it looks to me like the core plgin functionality and the core JBoss modules plugin support is very close to complete. I have posted a request for you to jon the bytemanproject group at github which will give you access to the master repo. So you are very welcome to check this in when you see fit. We could consider making this current functionality available as a trial feature in the next release while  we finish whatever else needs doing.

                                     

                                    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.

                                    1 2 3 Previous Next