1 2 Previous Next 20 Replies Latest reply on Apr 15, 2003 12:15 PM by bill.burke

    AOP Introductions(Extensions)

    bill.burke

      What I had originally named Extensions has a real name in AOP I am told. Introductions.

      Introductions are adding interfaces, methods, fields, constructors to an object or class:

      POJO pojo = ...;
      Cached cachedObj = (Cached)pojo;
      cachedObj.flush();

      where flush() is either delegated to an instance of an "introduced" class, or handled by an interceptor.

      We will only support adding Interfaces. Either on a per class level, or a per instance level. Let's discuss per class first.

      Class Introduction:



      org.some.interface
      org.some.other



      This is the simplest to implement. The methods defined in the given interfaces will be added to the class and simple invoke down the interceptor chain. An interceptor is expected to handle the method invocation.

      The next is:



      org.some.interface
      org.some.other

      <delegate-class>org.some.delegate</delegate-class>


      Introduced interface invocations will be delegated to an instantiation of the delegate-class. The delegate-class will be required to implement an empty constructor for the 1st iteration. If the extension class is advised, then a reference to the extended object will be placed within its metadata for reference.

      Also there will be a configurable way to specify what interceptor chain should be traversed. The extended class's, the delegate-class's, and/or both.

      The main problem I see with this is Serializable. Currently all AOP attached data and fields are not serialized across the wire. This is done on purpose because we want to support clients that are not using JBoss AOP. There are 2 things we can do for this. One, optionally provide a flag to make AOP fields non-transient, or use ClassProxy. AOP ClassProxy's are dynamically created classes that inherit from a base class and implement every public method of the base class to provide interceptor chains. They are used to provide interception for non-advised objects in AOP Remoting. They are serializable across the wire and retain their metadata. Actually. This ClassProxy construct is how will will support per instance introduction.

      PER INSTANCE INTRODUCTIONS:

      Per instanc introductions will be implemented using ClassProxy described above. Per instance introductions will be API driven. Meaning there will be no pre-XML config for this type of stuff.


      Well that's it for now. That's my current brain dump. Implementation will follow later.

      Bill

        • 1. Re: Please help test M2-preview1
          bill.burke

          JIRA RFE for tracking the requested combo/list feature for possible configs. (Its M3 stuff not M2) http://jira.jboss.com/jira/browse/JBMAIL-4. There is a corresponding RFE presently logged for JBMail's build that is really for Cheese (but we don't have a project/module for Cheese and at present I'm not sure if there is enough interest in Cheese to warrant its own project). The Cheese issue is http://jira.jboss.com/jira/browse/JBMAIL-3 and it is basically the underlying support needed to implement 4 in JBMail M3.

          • 2. Re: AOP Introductions(Extensions)
            marc.fleury

            this introduction business can be either typed or detyped. All we are taking about is adding aspects to an object by introducing either a detyped aspect (a la cache bela work) or typed aspects with interfaces and proxies.

            It is clear that the typed aspect require Dynamic Proxy or the equivalent construct from Bill with the ClassProxy. Other than that the detyped ones work better in in-ref aspects.

            • 3. Re: AOP Introductions(Extensions)
              bill.burke

              > this introduction business can be either typed or
              > detyped. All we are taking about is adding aspects
              > to an object by introducing either a detyped aspect
              > (a la cache bela work) or typed aspects with
              > interfaces and proxies.
              >
              > It is clear that the typed aspect require Dynamic
              > Proxy or the equivalent construct from Bill with the
              > ClassProxy. Other than that the detyped ones work
              > better in in-ref aspects.
              >

              You don't need a DP or CP with introductions as long as the introductions are defined before the class is loaded.

              • 4. Re: AOP Introductions(Extensions)
                aloubyansky

                >
                >
                > org.some.interface
                > org.some.other
                >
                > <delegate-class>org.some.delegate</delegate-class>
                >

                I need something similar for persistence.
                First iteration of JDO implementation is almost ready. It's not yet transactional though, i.e. each setter goes to the db. Getter goes to the db only if the asked field is not yet loaded.

                Persistable POJO must implement PersistenceCapable interface and have some added fields. This part I currently implement manually.

                I thought about a chain of code enhancers first. A code enhancer at class loading time instruments a POJO for a specific service, i.e. persistence, cache, etc and after it's done, delegates to the next code enhancer in the chain. So, that at the end of the chain the POJO is instrumented for all the asked services.

                I think, introductions with delegate instance *per* POJO instance should solve my problems too. And I would like to delegate not only method invocations of the specified interfaces but also method invocations of the POJO's methods. For example, to have a delegate object that will intercept all POJO's get/set methods + specified interface methods. What do you think?

                alex

                • 5. Re: AOP Introductions(Extensions)
                  vadheraju

                  Hi Bill/Marc,

                  I am just trying to understand the AOP framework.
                  Could you suggest me a way to get start with it?
                  Do we have any docs on this.

                  Your direction would be appreciated.

                  Rajeshwar Rao

                  • 6. Re: AOP Introductions(Extensions)
                    bill.burke

                    > Hi Bill/Marc,
                    >
                    > I am just trying to understand the AOP framework.
                    > Could you suggest me a way to get start with it?
                    > Do we have any docs on this.
                    >
                    > Your direction would be appreciated.
                    >
                    > Rajeshwar Rao

                    See doco here:
                    http://www.jboss.org/index.html?module=html&op=userdisplay&id=developers/projects/jboss/aop


                    The AOP services haven't really been documented yet. I will docoment them sometime in the 1st few weeks of May.

                    • 7. Re: AOP Introductions(Extensions)
                      llucifer

                      > I need something similar for persistence.
                      > First iteration of JDO implementation is almost
                      > ready. It's not yet transactional though, i.e. each
                      > setter goes to the db. Getter goes to the db only if
                      > the asked field is not yet loaded.
                      >
                      > Persistable POJO must implement PersistenceCapable
                      > interface and have some added fields. This part I
                      > currently implement manually.

                      I did sth. similiar in Ruby (http://www.ruby-lang.org/), an OO scripting language that supports "meta programming". With Ruby's capabilities to change class definitions at runtime it was easy for me to implement a nearly fully transparent persistence layer. A great help was that ruby supported "Mixins" wich is was is called "Introductions" in this thread.

                      • 8. Re: AOP Introductions(Extensions)
                        marc.fleury

                        > I need something similar for persistence.
                        > First iteration of JDO implementation is almost
                        > ready. It's not yet transactional though, i.e. each
                        > setter goes to the db. Getter goes to the db only if
                        > the asked field is not yet loaded.

                        see with bill to make this 'transactional'

                        what you really want to know is if there is a transaction going on, there is code that does that in the EJB chain.

                        What you need to do then is to keep track of all the changes in that transACTION. A simple way to do that is to intercept the set and keep a Field object representing my field (initialized at chain insertion time?). That list stays with a session coordinator and at the end of the transaction, one listener notifies the session coordinator. This list of changed state is then numbered and sent to replication or persistence.

                        > Persistable POJO must implement PersistenceCapable
                        > interface and have some added fields. This part I
                        > currently implement manually.

                        no no no, this is why you want AOP you dynamically create that interface in runtime. The classloaders are instructed to instrument any class you declare, including the persistable ones. Give the classloader the list of interceptors you want the system to apply to your class and you will get an instance that supports that interface and implements it with the interceptors/delegate that you wrote.


                        > I thought about a chain of code enhancers first. A
                        > code enhancer at class loading time instruments a
                        > POJO for a specific service, i.e. persistence, cache,
                        > etc and after it's done, delegates to the next code
                        > enhancer in the chain. So, that at the end of the
                        > chain the POJO is instrumented for all the asked
                        > services.

                        yes, yes, yes that is the way. That is the way, do me a favor AND FUCKING TALK TO BILL. He will put you on the right track and don't waste time.

                        Also talk to Adrian about that class replacement trick he pulled in Paris, where the classloader gets fooled even for system classes.

                        Owning your own VM .....

                        > I think, introductions with delegate instance *per*
                        > POJO instance should solve my problems too. And I
                        > would like to delegate not only method invocations of
                        > the specified interfaces but also method invocations
                        > of the POJO's methods. For example, to have a
                        > delegate object that will intercept all POJO's
                        > get/set methods + specified interface methods. What
                        > do you think?

                        You will need it for CRUD operations mapped to more generic structures. For example the Collections framework of java has a very specific CRUD signature; one that actually makes sense :). In that fashion you CAN instrument even a native collection in JBoss (and in JBoss only).

                        Finally a real persistent representation of the fantastic collections classes thanks to AOP on JBoss

                        With AOP on JBoss, "anything is possible" (TM)

                        >
                        > alex

                        marcf

                        • 9. Re: AOP Introductions(Extensions)
                          marc.fleury

                          lucifer,

                          can you spare the definition of relationships in a clear and simple manner?

                          marcf

                          • 10. Re: AOP Introductions(Extensions)
                            aloubyansky

                            > What you need to do then is to keep track of all
                            > the changes in that transACTION. A simple way to do
                            > that is to intercept the set and keep a Field object
                            > representing my field (initialized at chain insertion
                            > time?). That list stays with a session coordinator
                            > and at the end of the transaction, one listener
                            > notifies the session coordinator. This list of changed
                            > state is then numbered and sent to replication or
                            > persistence.

                            implementation details :) I already have a generic dirty fields tracking. It means it should work in transactional and non-transactional environments.

                            public class Person
                            {
                            private String name;
                            private Contacts contacts;
                            ...

                            public class Contacts
                            {
                            private Address address;
                            private String phone;
                            ...

                            public class Address
                            {
                            private String city;
                            private String street;

                            All this stuff is mapped to one table PERSON.
                            Person.contacts.phone and Person.contacts.address.city are in default-fetch-group. Log from the testcases:

                            // default-fetch-group loading
                            DEBUG [JMXFacadeService] person.getContacts();
                            DEBUG [StoreManagerImpl] load command: SELECT PHONE, CITY FROM PERSON WHERE PERSON_OID = '8636'

                            // load street field
                            DEBUG [org.avoka.jmx.JMXFacadeService] person.getContacts().getAddress().getStreet()
                            DEBUG [org.jboss.persistence.jdo.store.StoreManagerImpl] load command: SELECT STREET FROM PERSON WHERE PERSON_OID = '8626'

                            // in another "session" update city and flush
                            // step 1. default-fetch-group is loaded
                            DEBUG [org.avoka.jmx.JMXFacadeService] person.getContacts().getAddress().setCity("Kiev");
                            DEBUG [org.jboss.persistence.jdo.store.StoreManagerImpl] load command: SELECT PHONE, CITY FROM PERSON WHERE PERSON_OID = '8626'
                            // step 2. ((JBossPersistenceManager)pm).flushAll(); <- triggers flushing
                            DEBUG [org.jboss.persistence.jdo.store.StoreManagerImpl] update command: UPDATE PERSON SET CITY='Kiev' WHERE PERSON_OID = '8626'


                            >> Persistable POJO must implement PersistenceCapable
                            >> interface and have some added fields. This part I
                            >> currently implement manually.
                            >
                            > no no no, this is why you want AOP you dynamically
                            > reate that interface in runtime. The classloaders are
                            > instructed to instrument any class you declare,
                            > including the persistable ones. Give the classloader
                            > the list of interceptors you want the system to apply
                            > to your class and you will get an instance
                            > that supports that interface and implements it with the
                            > interceptors/delegate that you wrote.

                            The problem is that, needed instrumentation might not always be achieved with AOP "instrumentation blocks", i.e. interceptors, mixins, etc.
                            Now, when I have something working I am thinking about how to adjust it to AOP blocks. Indeed, I think, I can do it. But there will be some overhead.
                            Anyway just lets evaluate the idea. Custom enhancer is not tied to AOP blocks and can instrument classes as needed.
                            - this could improve performance of instrumented classes by doing some things directly and not going through interceptors, mixins and so on;
                            - simplify the development, i.e. no need to think about how to implement this in AOP blocks;
                            - finally, custom enhancers could co-exist with AOP instrumentation. Say, chain of enhancers is applied before AOP instrumentation.


                            > Also talk to Adrian about that class replacement trick
                            > he pulled in Paris, where the classloader gets fooled
                            > even for system classes.

                            At the moment, I don't see problems with class replacing. I already do it when persistent objects are loaded. But collections are not supported yet.

                            >> I think, introductions with delegate instance *per*
                            >> POJO instance should solve my problems too. And I
                            >> would like to delegate not only method invocations of
                            >> the specified interfaces but also method invocations
                            >> of the POJO's methods. For example, to have a
                            >> delegate object that will intercept all POJO's
                            >> get/set methods + specified interface methods. What
                            >> do you think?
                            >
                            > You will need it for CRUD operations mapped to more
                            > generic structures. For example the Collections
                            > framework of java has a very specific CRUD signature;
                            > one that actually makes sense :).
                            > In that fashion you CAN instrument even a native
                            > collection in JBoss (and in JBoss only).

                            I am not sure we are talking about the same thing. I talked about a mixin that will intercept methods not only mentioned in the specified interface for it but also other POJOs methods/fields. But now, it seems to me, it's not a good idea.

                            alex

                            • 11. Re: AOP Introductions(Extensions)
                              marc.fleury

                              > public class Person
                              > {
                              > private String name;
                              > private Contacts contacts;
                              > ...
                              >
                              > public class Contacts
                              > {
                              > private Address address;
                              > private String phone;
                              > ...
                              >
                              > public class Address
                              > {
                              > private String city;
                              > private String street;
                              >
                              > All this stuff is mapped to one table PERSON.

                              You are assuming a table representation. I am looking for a simple state tracking at the object level, see what bill has done for acid.


                              > The problem is that, needed instrumentation might not
                              > always be achieved with AOP "instrumentation blocks",
                              > i.e. interceptors, mixins, etc.
                              > Now, when I have something working I am thinking
                              > about how to adjust it to AOP blocks. Indeed, I
                              > think, I can do it. But there will be some overhead.
                              > Anyway just lets evaluate the idea. Custom enhancer
                              > is not tied to AOP blocks and can instrument classes
                              > as needed.

                              Let's make sure we are talking about the same thing. The persistence engine is a consumer of state changes, meaning the list of fields in your object graph that have been modified in the previous transaction.

                              That information is information we can retrieve at the object setter level (and in fact in the future for all field access). That information is relevant to the cache replication engine, which replicates those leaves that have changed and only those, and the persistence engine which can cache statements for a given set of changed leaves.

                              > - simplify the development, i.e. no need to think
                              > about how to implement this in AOP blocks;

                              State change is an AOP service. Persistence of that state change for POJO's is the generalized CMP engine. I don't care about the EJB implementation that should not evolve, I am talking about a JDO persistence layer.

                              > - finally, custom enhancers could co-exist with AOP
                              > instrumentation. Say, chain of enhancers is applied
                              > before AOP instrumentation.

                              I don't need a chain I need one interceptor that notifies of the list of state changes within the transaction and it is the job of the persistence engine to use the right update queries to store in the database the new data. Cache it on set index (that will require some work) and you optimize the query retrieval.

                              > > Also talk to Adrian about that class replacement
                              > trick
                              > > he pulled in Paris, where the classloader gets
                              > fooled
                              > > even for system classes.
                              >
                              > At the moment, I don't see problems with class
                              > replacing. I already do it when persistent objects
                              > are loaded. But collections are not supported yet.

                              which is why you don't see the problem yet. You don't support collections. Supporting collections introduces the problem of how to represent it's structure in a database but for the pure cache implementation (bela) it introduces the problem of tracking changes of the CRUD nature (add, remove, removeAll, put etc). We need to instrument these in AOP. Using class swapping is the way to do it naturally through the classloader level.

                              > > You will need it for CRUD operations mapped to
                              > more
                              > > generic structures. For example the Collections
                              > > framework of java has a very specific CRUD
                              > signature;
                              > > one that actually makes sense :).
                              > > In that fashion you CAN instrument even a native
                              > > collection in JBoss (and in JBoss only).
                              >
                              > I am not sure we are talking about the same thing. I

                              we are not :)

                              marcf

                              • 12. Re: AOP Introductions(Extensions)
                                aloubyansky

                                > You are assuming a table representation.

                                not at all.

                                > I am looking for a simple state tracking at the object
                                > level, see what bill has done for acid.


                                i do it.

                                >> At the moment, I don't see problems with class
                                >> replacing. I already do it when persistent objects
                                >> are loaded. But collections are not supported yet.
                                >
                                >which is why you don't see the problem yet. You don't
                                > support collections. Supporting collections introduces
                                > the problem of how to represent it's structure in a
                                > database but for the pure cache implementation (bela)
                                > it introduces the problem of tracking changes of the
                                > CRUD nature (add, remove, removeAll, put etc). We need
                                > to instrument these in AOP. Using class swapping is the
                                > way to do it naturally through the classloader level.

                                still don't see it. who stops me to substitute the collection class? but, ok, let me do it first.

                                >> I am not sure we are talking about the same thing. I

                                >we are not :)

                                ;)

                                alex

                                • 13. Re: AOP Introductions(Extensions)
                                  llucifer

                                  Marc,

                                  > can you spare the definition of relationships in a
                                  > clear and simple manner?

                                  sorry, but I don't understand exactly what you want. I wasn't talking about relationships but I will explain how they are handled by my little ruby framework I you want me to.

                                  -billy.

                                  • 14. Re: AOP Introductions(Extensions)

                                    > still don't see it. who stops me to substitute the
                                    > collection class? but, ok, let me do it first.

                                    the classloader will:

                                    $ cat Test.java
                                    package java.something;

                                    public class Test
                                    {
                                    public static void main(String[] args)
                                    {
                                    System.out.println("Hot Stuff!!");
                                    }
                                    }

                                    $ java java.something.Test
                                    Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.something

                                    Can't load anything into java.* package.

                                    1 2 Previous Next