1 2 Previous Next 17 Replies Latest reply on Feb 5, 2003 9:39 AM by bill.burke

    Instrumentation of system classes

    belaban

      Can we instrument system classes, e.g. in the java.lang package ? For example arrays ? I'm thinking of the follwing case:

      Person:
      String name;
      int age;
      String[] hobbies;


      I want to know when somebody does p.getHobbies()[0]="bla";

      Is this possible ?
      Bela

        • 1. Re: key properties of AOP in Java
          marc.fleury

          Woaaa,

          gregork... we are just getting started here and already my assignement is to read your stuff and try to make sense of it for my little friends here.


          > The purpose of the messages is to compare some of the
          > newer proposals,
          > like Rickard's, JBoss, Jadvise and AspectWerkz to
          > "good old fashioned"
          > AspectJ.

          Fair enough


          > I believe other AOP systems should also have, and
          > start a discussion
          > about whether the other proposals have those
          > properties, could have
          > those properties, and whether it would be a good
          > idea.

          Sounds good also you will find we can actually try some of it fast in AOP/JBoss.

          > This initial message just enumerates and describes
          > some key properties
          > of AspectJ. The message is primarily focused on the
          > pointcuts and
          > advice part of AspectJ.


          > -pointcut language is compositional-
          >
          > The pointcut language is compositional. This means
          > that you
          > can take pointcuts and compose them to form other
          > pointcuts.
          > This means that you can build up crosscutting
          > structure in
          > a similar manner to what we know about building up
          > procedural
          > structure or class structure.

          Be precise makes little sense as is. Right now we have precise requirements for JBoss System that we must able to say 'on this method/field/constructor' please apply this set of interceptors. We can do dynamically.

          One of the things that would be nice is a more evolved language that enables us to provide multiple pointcuts in one sentence such as
          "apply these interceptors to methods having to do with CRUD operations" a "where get/set create/delete, intercept" kind of thing. Can you give me use cases of evolved languages?.



          > The combination of supporting named abstraction and
          > being
          > compositional means we can say nice things like:
          >
          > after() returning: move() && !cflowbelow(move()) {
          > Display.update();
          > }
          >
          > and easily understand what that means.

          not here not really. You are saying that after you return from move() and you are not in the control of "move" itself you do something.

          hmmmmm, in the case of system AOP ala JBoss I am not sure I see a use for the named abstractions. I can say the above where the pointcut is a method/field/constructor/interface method but where do I need a more evolved language?

          > -static typing-
          >
          > Pointcut and advice declarations in AspectJ are
          > statically
          > typed. This supports separate compilation and it
          > means that
          > that actual weaving becomes typesafe.

          That's nice, but we don't know at writing/compile time that the aspect is going to be weaved in. For example objects that are going to be replicated across caches we instrument dynamically, objects that are going to be monitored on a method basis (counters) can be added dynamically to the class.

          The interceptor that does the work itself is in java so the logic inside is type-safe. But the issue of weaving in that aspect at run time is feasable and works because we are in a detyped environment and because the aspects are completely orthogonal. That is why we can bring them in out of the blue.

          I don't see why 'type safety' brings you for AOP combination of behavior.

          > the
          > weaving can happen later than compile time, like load
          > time
          > or even in the VM.

          you still assume a type.

          For me there are 2 types of aspects: typed ones, detyped ones.

          Detyped ones are the system ones. They support the "invoke()" signature in a "chain of responsibility" pattern it is also the signature exposed by JMX dynamic puppies. They can be weaved under the methods of instances dynamically.

          Some interceptors come typed, meaning they expose an interface for simplicity's sake and for end users (think standard mbeans). Dynamically composing that signature as a sum of the signature is what Dynamic Proxies used to do and what JBossAOP does today with Chiba's bytecode chirurgical kit.



          > Its critical to have type safety, or else we are
          > asking people
          > to take a step back in order to take a step forward.

          see above, how can you know the types upfront, you are assuming a finite set of system aspects and bill is cranking them out every other week or so, you can't control that set of behavior unless you are doing EJB stuff. EJB defines the set.

          > The combination of the above means that named
          > pointcuts are
          > really very solid abstractions of logical events.

          But is programming in logical events, nothing more than following a thread? My mind is twisted, is it really simpler?

          > --extensible--
          >
          > The combination of the above properties, and in
          > particular the
          > orthogonality of the join point model makes AspectJ
          > feel fairly
          > extensible. For example, when we added advice
          > execution join
          > points we just had to add the join points and a new
          > pointcut.

          I believe you are talking about the extensions to the language itself meaning AspectJ. Are you not? We use Java, and I will let others who know more than I do talk.

          In our case we are dealing with java objects and the java language. Are we running into some limitations of the language? yes we are. For example pointcut 'hooks" should be present in all classes at the Object level. So we can instrument our stuff through the "Advisable" interface. Domain of application is cache, transaction, acidity, possibly cmp. The fact that this construct is not present on the Object class is a pain that we need to circumvent with javassist. Also the fact that we can't instrument jdk system classes is a bitch. But we can code around it since Paris. In any case we have already run with Bill in many "mmm I wish this was a feature of the language".

          In both cases we are thinking that we should hijack kaffe and breathe new life into it, we need a kickass VM not for performance we got mr moore for that, but for raw functionality of the bytecode. Or then again, wasn't the VM already designed for that? i mean that bill through chiba's stuff is pretty much capable of enhancing any standard java class already sooo we don't need a new VM, the java bytecode language enables us to do that at the system level.

          I am worried about the "need for a language". Is what you want to do "dynamic composition of aspects"? then (uml/xml) language thing is probably enough to specify those pointcuts for most cases.

          For me it is very visual, you can see what classes have what instrumentation and what interfaces and bla bla bla. It's visual.


          > --other properties--
          >
          > There are a number of other critical properties that
          > AspectJ
          > has that any AOP for Java should also have. Because
          > this message
          > is already long, I will just list them:
          >
          > - static advice (declare warning, error, soften)
          > - intertype declarations

          I don't know what they are.

          > - code structure model (support IDE and other
          > r browser tools)

          yes UML :) or a visual thingy on running instances. Ooooh as a sys-admin I walk in, I can say "system: give me the points of entry to this system" it returns the set of objects that have remote capabilities (JBoss remote ports, AOP remotes). It is represented by a "circle" on the screen, you can drag and drop the aspect of "monitor entry for patterns of attack DOS" onto that circle thereby instrumenting your system dynamically. Bonus, baby you are my fix.

          As a developper, I can look at my system and say "these objects should be remote and these objects should be cached, and these objects should be cmp'd". Yannis of G-Tech has a whole automated thingy that does the remoteness part by itself, we just submitted a paper with Yannis doing it with AspectJ actually. It ends up in a lot of XML but we are talking visual drawing here.

          > - Open Source open standard
          >

          hell yeah!

          > have these properties, in particular to what extent
          > Bill's new
          > design does. I'd appreciate the help, since I don't
          > know the
          > details of Bill's new design.

          I'll let someone more savvy than me answer, I just appreciate you taking the time to help us get it right. Also bill used to be your student and I promise he will pay attention in class.


          • 2. Re: Reopening getters/setters vs. field interception
            bill.burke

            Hi,

            I have watched this forum and other AOP resources for some time and feel now confident to add some cents (in EURO! :-).

            Before talking about fields I would like to extend Marc's interceptor diagram which I think is quite useful for discussion.

            Marc uses this

            [=-|||-=o

            where "[" is the interface "o" is the target object and "|||" are some interceptors. "=" is typed access and "-" is "untyped" access (via invoke). I hope I got this right.

            This picture works very well for methods, but for field access I would like to extend it with the caller object "c":

            c=[=-|||-=o

            For a normal field access the picture would then be:

            c=[o

            and with field interceptors:

            c=-|||-=[o

            Here the instrumentation has to be done on the caller side because with field access the interface is tightly coupled to the object, there is now place to insert any code in between.

            The plan to implement field interception is to use Javassist, but by using byte code manipulation at class load time we could get much more!

            With the help of Javassist you could have for fields something like this:

            ciii=[o

            where "i" stands for "inline code injection" and it could be any statement sequence accepted by the Javassist compiler.

            This would give you more efficient alternatives to the somewhat expensive field interceptor chains.

            Now you could easily specify Bela's proposal somewhere above:
            [pre]>void foo() {
            > // bla
            > a=23;
            > modified = true; // <--- synthesized code
            > // bla
            >}
            [/pre]You would just define for field "a" a code injection like:
            [pre] { $proceed; modified = true; }
            [/pre]The above is in Javassist syntax, $proceed stands for the original field access. With chained injections $proceed would stand for the previous injections.

            This is a just a basic idea without all the details, e.g. one would need a more specific specification for the injection pointcuts than just class level and may be the injected code should be more restricted than within Javassist.

            The above is not meant as a substitution for the inspector chain, so the most general field access diagram would look like:

            ciii=-|||-=[o

            The same could be also done with methods, where we would get:

            ciii=[=-|||-=iiio

            Here the code injections "iii" could be done on the caller side as well as around the method body.

            I am not sure if all this should be really done, but my point is that either a simple way with only method interception and getters/setters should be chosen or on the other hand when the Javassist route is taken much more than currently proposed could be provided.

            Elmar

            • 3. 3764872
              timfox

              > Another option would be to modify the bytecode of any
              > class that creates an instance of a System class, so
              > that instead of calling the System class' constructor
              > directly, it goes through a factory.
              > The factory could then instrument the system class,
              > before instantiating and returning it.
              >
              > This would not require you to intercept any
              > classloaders, although you would not be able to
              > advise system classes that had been created from
              > other system classes, or from Class.newInstance or
              > Constructor.newInstance also you would have to locate
              > and instrument the calling code which is tough.

              THis is exactly what I proposed offline in a private email to Bela. Locating and instrumenting the code is not tough. We already have to do this for public and protected field interception and Javassist has provided the hooks for this. My suggestion is to extend and implement System classes that delegate to the superclass implementation. So we'd have a separate hierarchy jboss.util.*; jboss.lang.Thread; etc...

              FYI, I want to avoid non-runtime pre-compilation since this is what I believe is one of the drawbacks of something like AspectJ.

              • 4. Re: Instrumentation of system classes
                timfox

                Another option would be to modify the bytecode of any class that creates an instance of a System class, so that instead of calling the System class' constructor directly, it goes through a factory.
                The factory could then instrument the system class, before instantiating and returning it.

                This would not require you to intercept any classloaders, although you would not be able to advise system classes that had been created from other system classes, or from Class.newInstance or Constructor.newInstance also you would have to locate and instrument the calling code which is tough.

                • 5. Re: Instrumentation of system classes
                  catch23

                  I'm pretty sure the JOrchestra people do this already. I'm sure they have all the answers. I remember them instrumenting the system classes and dealing with problematic native methods.

                  • 6. Re: Instrumentation of system classes
                    belaban

                    [FYI, I'm posting the reply Eli sent me below]

                    Bela,


                    > Guys,
                    >
                    > any ideas on how to instrument byte code for system classes ? See my
                    > posting on aspect forum...

                    Below, I pasted your posting from the aspect forum:


                    >Can we instrument system classes, e.g. in the java.lang package ? For

                    example arrays ? I'm thinking of the follwing case:


                    >Person:
                    >String name;
                    >int age;
                    >String[] hobbies;



                    >I want to know when somebody does p.getHobbies()[0]="bla";
                    >Is this possible ?

                    In short, yes it is possible. However, the instrumentation must be done on
                    the application class that calls p.getHobbies()[0]="bla".
                    We are handling similar kinds of cases in J-Orchestra by replacing some
                    arrays with array proxies. It is important to keep in mind that the nature
                    of
                    transformations performed by J-Orchestra is not trivial and requires direct
                    access to specific bytecode instructions. In order to handle things
                    correctly, a separate static analysis step is required to determine where
                    instrumentation should take place. I do not believe that a light-weight
                    reflective framework such as Javaassist simply is powerful enough to handle
                    the kinds interceptions you have described.

                    The answer to your general question of whether it is possible to instrument
                    bytecode of system classes is no. At least using the
                    instrumentation-at-load-time approach. The problem is that it is impossible
                    to replace the bootstrap class loader that is used to load all system
                    classes. The bootstrap class loader must be a part of the JVM.
                    Otherwise, we would have a chicken-egg kind of problem.
                    class CustomBootstrapClassLoader extends ClassLoader { ... } // who loads
                    the CustomBootstrapClassLoader and all its superclasses starting from
                    Object?


                    Eli

                    • 7. Re: Instrumentation of system classes
                      catch23

                      I am unclear why JBoss developers have chosen Javassist over BCEL for bytecode rewriting purposes? I am unfamiliar with Javassist, but judging by their API, it seems to offer less flexibility that BCEL offers.

                      Could someone explain what is the reasoning behind this?

                      • 8. Re: Instrumentation of system classes
                        bill.burke

                        > I am unclear why JBoss developers have chosen
                        > Javassist over BCEL for bytecode rewriting purposes?
                        > I am unfamiliar with Javassist, but judging by their
                        > API, it seems to offer less flexibility that BCEL
                        > offers.
                        >
                        > Could someone explain what is the reasoning behind
                        > this?

                        Simple reason: Time. Plus I really like the Javassist library. Its "Bytecode for dummies" and I would like to help the Javassist people to bring their library up to BCEL standards if it is not already there already.

                        • 9. Re: Instrumentation of system classes
                          bill.burke

                          > Another option would be to modify the bytecode of any
                          > class that creates an instance of a System class, so
                          > that instead of calling the System class' constructor
                          > directly, it goes through a factory.
                          > The factory could then instrument the system class,
                          > before instantiating and returning it.
                          >
                          > This would not require you to intercept any
                          > classloaders, although you would not be able to
                          > advise system classes that had been created from
                          > other system classes, or from Class.newInstance or
                          > Constructor.newInstance also you would have to locate
                          > and instrument the calling code which is tough.

                          THis is exactly what I proposed offline in a private email to Bela. Locating and instrumenting the code is not tough. We already have to do this for public and protected field interception and Javassist has provided the hooks for this. My suggestion is to extend and implement System classes that delegate to the superclass implementation. So we'd have a separate hierarchy jboss.util.*; jboss.lang.Thread; etc...

                          FYI, I want to avoid non-runtime pre-compilation since this is what I believe is one of the drawbacks of something like AspectJ.

                          • 10. Re: Instrumentation of system classes
                            timfox

                            Bill - looks like you've pretty much got it covered.

                            I've had a look at Javassist and it looks pretty cool. I can see that scanning code for invocations is pretty easy as you say.

                            One more question - javasssist says it doesn't support inner clases - if so, how are you going to advise calls to public methods/system constructors etc. that originate in inner classes?

                            • 11. Re: Instrumentation of system classes
                              bill.burke

                              > Bill - looks like you've pretty much got it covered.
                              >
                              > I've had a look at Javassist and it looks pretty
                              > cool. I can see that scanning code for invocations is
                              > pretty easy as you say.
                              >
                              > One more question - javasssist says it doesn't
                              > support inner clases - if so, how are you going to
                              > advise calls to public methods/system constructors
                              > etc. that originate in inner classes?
                              >
                              Answer? Don't know. We're trying to set up a relationship with the Javassist folks. If Javassist doesn't support something, we want to extend it. I like the framework and want to help them out.

                              Bill

                              • 12. Re: Instrumentation of system classes
                                marc.fleury

                                Eli,

                                I thought that in JDK1.4 you could specify your own system classloader for the VM. That let's you use specific classloaders for system classes and bypass the chicken and egg problem.

                                • 13. Re: Instrumentation of system classes
                                  marc.fleury

                                  > One more question - javasssist says it doesn't
                                  > support inner clases - if so, how are you going to
                                  > advise calls to public methods/system constructors
                                  > etc. that originate in inner classes?

                                  KISS, and if you REALLY want the feature then code it in javassist :)

                                  • 14. Re: Instrumentation of system classes
                                    marc.fleury

                                    > Another option would be to modify the bytecode of any
                                    > class that creates an instance of a System class, so
                                    > that instead of calling the System class' constructor
                                    > directly, it goes through a factory.
                                    > The factory could then instrument the system class,
                                    > before instantiating and returning it.

                                    Interesting

                                    > This would not require you to intercept any
                                    > classloaders, although you would not be able to
                                    > advise system classes that had been created from
                                    > other system classes, or from Class.newInstance or
                                    > Constructor.newInstance also you would have to locate
                                    > and instrument the calling code which is tough.

                                    We can do the last part but we can also require JDK1.4 for that feature (AOP on java.lang classes so as to build a persistent, acid String?) mmmmm



                                    1 2 Previous Next