2 Replies Latest reply on Jun 22, 2004 4:55 AM by solo

    intercepting proxies

    solo

      Hi,
      Q1)

      I've been trying to intercept proxies that JBOSS generates on client side for e.g. stateless session beans. I understand why it is not possible in general (since not loaded via the AOP classloader). Though is there any way of doing it anyhow by some programmatic registration. What I would like is something like this:

      * JNDI lookup of the home if
      * narrow, create on the home.
      * Intercept on (selected by the if containing certain metadata) (methods for the EJB remote interface).

      Q2)
      Since I did not succeed in intercepiting the proxy, I created a "ClientSLSB" class of which I intercept the constructor.

      * When constructor is invoked i grab the JNDI path and creates a subclass via AOPClassPool and adds the EJB remote interface onto it.
      * Add the interface methods that delegates to a added field (EJB) method's to invoke the remote bean.
      * Return the subclass.

      For fun I tried to add a interceptor and a AdviceBinding. But registration seems to always fail (seems that it will match using the baseclass while registering the AdviceBinding). Is it because the base class is already registered and it cannot distingwish between base and subclass.

      Basically i intercept by all($instanceof{TheEJBInterface}), but I've tried a massive ( ;-) amount of different expressions.

      Though it is of no greater importance since I genereate each method in the subclass but I wonder how it all fits in.

      Regards,
      Mario

      PS.
      Will the added contents of ResponseAttachment flow (de-/serialized) over the wire using std. JBOSS EJB proxies or is it for pure remoting only (or other)?

      I Just want to add a "hidden" context passed around between the client and the container, while in the container or within the client I can use AOP .

      (Haven't tried to write a client and server interceptors (that are configured for the bean itself since wanted to try to use the AOP fw as far as possible. Am I at a dead end so I need to write such interceptors?)
      DS.

        • 1. Re: intercepting proxies
          bill.burke

          You should be able to do:

          call(* $instanceof{EJBInterface}->*(..))
          


          You said that didn't work. Either there is a bug in JBoss AOP, or you did something wrong. I haven't had a chance to look into it. If you could, please debug this problem and get back to me of why it doesn't work. I am currently busy with a bunch of stuff and will not get back to JBoss AOP until after Java One.

          Bill



          • 2. Re: intercepting proxies
            solo

            Hi,

            Yes that was my wery wery first attemt but something is wrong since it will always end up in a exception (see below). That is why i started to try out interception of the proxy itself (but failed). At last I did generate my own proxy over the JBOSS proxy and tried to advice such but failed as well (see below for code snippets).

            I know you do not have much time but please could you bring some light on my other questions as well. There's a question below within the code as well.

            Many Regards,
            Mario





            --------------------- call pointcut exception --------------------------
            BeanIf:
            package se.dataductus.aopdemo.security;

            public interface Dummy extends javax.ejb.EJBObject
            {
            public void DummyMethod() throws java.rmi.RemoteException;
            }


            This is the pointcut:






            ....and the Exception:

            test-security:
            [java] java.lang.ExceptionInInitializerError
            [java] Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NullPointerException
            [java] at org.jboss.aop.ClassAdvisor.attachClass(ClassAdvisor.java:207)
            [java] at org.jboss.aop.AspectManager.getAdvisor(AspectManager.java:351)
            [java] at se.dataductus.aopdemo.security.TestSecurity.(TestSecurity.java)
            [java] Caused by: java.lang.RuntimeException: java.lang.NullPointerException
            [java] at org.jboss.aop.pointcut.MethodMatcher.visit(MethodMatcher.java:189)
            [java] at org.jboss.aop.pointcut.ast.ASTAll.jjtAccept(ASTAll.java:21)
            [java] at org.jboss.aop.pointcut.MatcherHelper.visit(MatcherHelper.java:70)
            [java] at org.jboss.aop.pointcut.MatcherHelper.matches(MatcherHelper.java:65)
            [java] at org.jboss.aop.pointcut.PointcutExpression.matchesExecution(PointcutExpression.java:80)
            [java] at org.jboss.aop.ClassAdvisor.resolveMethodPointcut(ClassAdvisor.java:264)
            [java] at org.jboss.aop.ClassAdvisor.createInterceptorChains(ClassAdvisor.java:432)
            [java] at org.jboss.aop.ClassAdvisor.attachClass(ClassAdvisor.java:202)
            [java] ... 2 more
            [java] Caused by: java.lang.NullPointerException
            [java] at org.jboss.aop.annotation.PortableAnnotationElement.isAnyAnnotationPresent(PortableAnnotationElement.java:112)
            [java] at org.jboss.aop.annotation.PortableAnnotationElement.isAnyAnnotationPresent(PortableAnnotationElement.java:105)
            [java] at org.jboss.aop.pointcut.MethodMatcher.visit(MethodMatcher.java:185)
            [java] ... 9 more
            [java] Exception in thread "main"
            BUILD FAILED: C:\progs\java\workspace\aopdemo\build.xml:45: Java returned: 1



            ------------------------- Intercepting a created subclass ------------------
            Advising and adding instance interceptor:

            AdviceBinding binding = new AdviceBinding("execution(* $instanceof{" + csBeanIf + "}->*(..))",null);
            binding.addInterceptor(ClientCLSBMethodInvokerInterceptor.class);
            AspectManager.instance().addBinding(binding);

            >
            > When adding the binding it will do a softmatch and in the
            > private Object matchClass(ClassExpression classExpression)
            > the clazz is not the generated subtype instead it is the pure class
            > of which i've done a copy from (and derived). It will fail to add
            > the new interceptor.
            >
            > I must admit that I do not understand how to add a instance advisor
            > and trigger it by an expression since the AdvisorBinding is taking the
            > interceptor class. On the instance I can get the instance advisor to
            > add a interceptor instance to the interceptor stack...
            >
            > The question is how do I add a interceptor instance that gets invoked
            > by an advise?
            >



            Advised advised = (Advised)obj; advised._getInstanceAdvisor().insertInterceptor(new ClientCLSBMethodInvokerInterceptor());


            Code to write subclass with ejbIf:

            CtClass cls = cp.makeClass(csClassName,cp.get("se.dataductus.aopdemo.util.ClientSLSB"));
            CtClass clsIf = cp.get(csBeanIf);
            cls.addInterface(clsIf);
            cls.makeClassInitializer();

            CtField fld = CtField.make("private " + csBeanIf + " _bean = null; ",cls);
            cls.addField(fld);
            String csMeth = "private " + csBeanIf + " _resolveBean() { if ( null == this._bean) { this._bean = super.resolve(); } return this._bean; }";

            CtMethod meth = CtNewMethod.make(csMeth,cls);
            cls.addMethod(meth);

            CtMethod []m = clsIf.getDeclaredMethods();
            for(int i = 0;i < m.length;i++)
            {
            meth = CtNewMethod.make(m.getReturnType(),m.getName(),m.getParameterTypes(),m.getExceptionTypes(),this.writeMethod(m),cls);
            cls.addMethod(meth);
            }

            cls.writeFile();
            return cls;