Announcement Announcement Module
Collapse
No announcement yet.
Spring AOP / Dynamic Proxies / Interfaces and Annotations Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring AOP / Dynamic Proxies / Interfaces and Annotations

    Good morning,

    I have an interesting problem that I am trying to get around.

    First of all I am using ExtJS and DirectJngine for my UI components.

    DirectJngine dynamic discovers the classes in my hierarchy that implement a certain interface and then discovers the methods that make up part of the external API by iterating over the methods and searching for the correct annotation (see example)

    Code:
    @DirectMethod
    public Collection<GrantedAuthority> getGrantedAuthorities(  ) {
    this results in an API file that is created and published to the JavaScript UI component library for the AJAX calls.

    It is when I try to create an AOP proxy for the target class that I run into problems in that the proxy does not know about the annotations and thus the API for the proxied class is empty.

    Additionally, when I iterate through my classes to dynamically generate the JS API, I am getting the name of the dynamic proxy (i.e. "$Proxy9") instead of the target class, which also breaks my API.

    Finally here is the real question(s):

    Given a proxy class (class object not instance) is there a way to determine 1) that it is a proxy and 2) how do I get the target class for that proxy.

    AOPUtils does not seem to help here since it does not like class proxy objects but instances - additionally, given the proxy class I get an instationationexception if I try to create the proxy object using the newInstance method.

    If I had this information I could intercept the creation of the API, interrogate the target class for the API based upon the annotations and swap in the appropriate names for the API, the remaining should continue to work.

    Alternatively, is there a way to get a proxy class to also recognize the annotations on the target class.

    I know that this may be a little hard to follow but hopefully someone can assist me here.

    Thanks in advance.

    Whatty
    Last edited by Whatty; Jan 14th, 2010, 01:38 PM.

  • #2
    Hi Whatty,

    I'm very interested in this topic. I'm working on a project in which I'm trying to integrate Spring and Spring Security with DirectJngine.

    So I took a look at the "djn-spring" project, and everything is working fine, as long as I expose methods on classes which don't have a corresponding aop proxy.

    Your problem is crystal clear and I hope to be able to give some advice. Quick note: in my project I'm using the CGLIB proxies and not the jdk standard ones, and I think that djn-spring, if possible, should support both.

    As for your first question, I think a combination of the standard jdk Proxy.isProxyClass() and AopUtils.isCglibProxyClass() will do.

    The second question is more complex.
    For CGLIB proxies, it should suffice to call the getSuperclass() method on the class object, as I think they are created by subclassing the target class.

    Concerning standard jdk proxies, I really don't know as I never played around with them.
    Maybe you could try to get an instance of the spring bean from the spring ApplicationContext(starting from the proxy class? I don't even know if that makes any sense) and then go with AopUtils.getTargetClass(). Please note that I could be *terribly* wrong with this one.

    As for the implementation, I took a (quick I must admit) look at the DirectJngine v1.1 source code, and I found that there is a method on the Scanner class in which the name of the directjngine action is defined looking at the "action" parameter of the @DirectAction annotation or at the string returned by Class.getSimpleName(). Do you plan on overriding that behaviour in some way?

    Thank you for taking interest in this and I would be glad to hear some news if possible

    Matteo Cerina

    Comment


    • #3
      I have spent quite some time in getting this to work properly, unfortunately, I had to go back to the actually source of the DirectJngine and start to drop in the hooks I needed to get this to work properly. Even with this implementation while I was working through it, it was fairly apparent that there is significant room for "optimization".

      I currently have an implementation that I think will work with AOP proxies but have not tested it extensively (works me for though) - and I do not believe it matters if it is a JDK proxies or a CGLIB proxy - since I do in fact use the method you mentioned.

      Unfortunately, I really don't have the time at this very moment to really work on refactoring this implementation and providing the appropriate level of unit testing etc, and would love to turn it over some sort of Spring / DirectJngine combined team since I really believe that they are opportunities for a really slick implementation here (given a really deep / expert level understanding of the Spring framework). I am actually writing the same implementation on the .NET side to support my other teams.

      I can post my code if you would like but it is definitely a "caveat emptor" situation.

      Whatty

      Comment


      • #4
        Having a look at your code would be very helpful if you are ok with it.

        If I'd ever come up with what I think could be a "better" solution, I'll be sure to post it.

        Comment


        • #5
          Please find attached part 1 of the source code that support AOP proxies.

          Again, this is a very rough implementation and there is obvious room for improvement.

          Comment


          • #6
            Here are the two other attachments that comprise the AOP support in DirectJngine.

            These three attachments must be unzipped into the project source folder and the existing DirectJngine JAR files must be removed from the project.

            Whatty

            Comment


            • #7
              Thank you so much for your code.

              However, in my particular case, I found out that all work fine by just adding an @Inherited annotation in the original DirectAction. No other change to the original source code but:
              PHP Code:
              package com.softwarementors.extjs.djn.config.annotations;
              ...
              @
              Inherited //<-- I just threw in this line
              @Retention(RetentionPolicy.RUNTIME)
              @
              Target({ElementType.TYPE})
              public @interface 
              DirectAction {
                
              String action();

              I think this works because I'm using cglib proxies and they are in fact subclasses of the target class. Sorry but I didn't have the time to check it on jdk proxies.

              Comment

              Working...
              X