简体   繁体   中英

Issue with AOP and JMX without Spring

I wrote an program to trace the performance of an application using AspectJ with a requirement that the tracing can be enabled or disabled at runtime using JMX so that i can change the value using jconsole/HtmlAdaptorServer. Now again i have to keep the Pointcut in AOP.xml file so that we can change the poincut when need. As soon as I am kepping the pointcut in aop .xml file nothing happens.Below is the code please let me know what to do or what am I missing.

Since I am using JMX here I am declaring MBean

    package com.ags.performance.asp;

    public interface SystemMonitoringAspectMBean {


    public void setEnabled(boolean enabled);
    public boolean isEnabled();
  }

Here I am using MBean and creating an Aspect

   package com.ags.performance.asp;

   //import ...
   import org.apache.log4j.Level;
   import org.apache.log4j.Logger;
   import org.aspectj.lang.ProceedingJoinPoint;
   import org.aspectj.lang.annotation.Around;
   import org.aspectj.lang.annotation.Aspect;
   import org.aspectj.lang.annotation.Pointcut;


   @Aspect
   public abstract class AbstractPerformanceMonitoringAspect
   implements SystemMonitoringAspectMBean{


    private Logger logger = Logger
            .getLogger(AbstractPerformanceMonitoringAspect.class);
    public volatile boolean enabled ;

    @Pointcut
    public abstract void monitoredOp();

    @Around("monitoredOp()&& !within(AbstractPerformanceMonitoringAspect)")
    public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
        if (!isEnabled()) {
            return pjp.proceed();
        }
        long start = System.nanoTime();
        try {
            return pjp.proceed();
        } finally {
            long complete = System.nanoTime();
            logger.log(Level.INFO, "Operation "
                    + pjp.getSignature().toShortString() + " took "
                    + (complete - start) + " nanoseconds");
        }
    }

    public synchronized void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public  synchronized boolean isEnabled() {
        return enabled;
    }
}

Then I am creating Agent so that I can change the values at runtime

    package com.ags.performance.asp;


   import com.sun.jdmk.comm.HtmlAdaptorServer;
   import org.aspectj.lang.annotation.Aspect;
   import org.aspectj.lang.annotation.Pointcut;
   import javax.management.MBeanServer;
   import javax.management.ObjectName;
   import java.lang.management.ManagementFactory;

   @Aspect
  public class SystemMonitoringAspect extends AbstractPerformanceMonitoringAspect {
  @Pointcut
  public void monitoredOp() {
  }

public SystemMonitoringAspect(){

    MBeanServer mBeanServer = null;
    mBeanServer = ManagementFactory.getPlatformMBeanServer();

    HtmlAdaptorServer adapter = new HtmlAdaptorServer();

    ObjectName adapterName = null;
    ObjectName perfAspectBean = null;

    try
    {

        perfAspectBean = new ObjectName( "SystemMonitoringAspect:name=performAspectLogger" );
        mBeanServer.registerMBean( this, perfAspectBean );


        adapterName = new ObjectName( "SystemMonitoringAspect:name=htmladapter,port=9092" );

        adapter.setPort( 9092 );

        mBeanServer.registerMBean(adapter, adapterName);
        adapter.start();
    }
    catch( Exception e )
    {

        e.printStackTrace();
    }
}

public static void main(String[] args) {

    new SystemMonitoringAspect();


 }
}

AOP.xml file which will be kept in META_INF folder

<aspectj>
<aspects>
    <!-- aspect name="com.ags.performance.asp.PerformanceLoggingAspect"/-->
     <aspect name="com.ags.performance.asp.SystemMonitoringAspect"/>

     <concrete-aspect 
            name="com.ags.performance.asp.SystemMonitoringAspect"      extends=
            "com.ags.performance.asp.AbstractPerformanceMonitoringAspect">
            <pointcut name="monitoredOp" expression="execution(* com.ags..*.*(..)"/>
     </concrete-aspect>
</aspects>
     <weaver options="-verbose –showWeaveInfo">

     </weaver>
</aspectj>

Disclaimer: I have never used JMX before, I was just interested in your question and quickly read the beginning of Oracle's JMX Tutorial .

Here is some really simplistic, but fully functional sample code for you. It contains two MBeans:

  • the application (just set active = false in order to quit the application via JMX)
  • the interceptor aspect (singleton instantiation model, (just toggle active = false or active = true as often as you wish in order to change the aspect state via JMX).

Application MBean interface:

package de.scrum_master.app;

public interface ApplicationMBean {
    void setActive(boolean active);
    boolean isActive();
}

Application:

package de.scrum_master.app;

import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

public class Application implements ApplicationMBean {
    private boolean active = true;

    @Override public void setActive(boolean active) { this.active = active; }
    @Override public boolean isActive() { return active; }
    private void doSomething() { System.out.println("Application activity"); }

    public static void main(String[] args) throws Exception {
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        Application application = new Application();
        ObjectName objectName = new ObjectName("de.scrum_master.app:type=Application");
        System.out.println("Registering application in JMX");
        mBeanServer.registerMBean(application, objectName);
        while (application.isActive()) {
            application.doSomething();
            Thread.sleep(3000);
        }
        System.out.println("Application was deactivated, exiting");
    }
}

Interceptor aspect MBean interface:

package de.scrum_master.aspect;

public interface ActivityInterceptorMBean {
    void setActive(boolean active);
    boolean isActive();
}

Interceptor aspect:

package de.scrum_master.aspect;

import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import de.scrum_master.app.Application;

public aspect ActivityInterceptor implements ActivityInterceptorMBean {
    private static boolean active = true;

    public ActivityInterceptor() throws Exception {
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        ObjectName objectName = new ObjectName("de.scrum_master.aspect:type=ActivityInterceptor");
        System.out.println("Registering activity interceptor aspect in JMX");
        mBeanServer.registerMBean(this, objectName);
    }

    @Override public void setActive(boolean active) {
        ActivityInterceptor.active = active;
        System.out.println("Interceptor is now " + (active ? "active" : "inactive"));
    }
    @Override public boolean isActive() { return active; }

    before() : if(active) && execution(void Application.doSomething()) {
        System.out.println("Intercepted activity: " + thisJoinPointStaticPart);
    }
}

Sample output:

Registering application in JMX
Registering activity interceptor aspect in JMX
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Interceptor is now inactive
Application activity
Application activity
Application activity
Interceptor is now active
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Intercepted activity: execution(void de.scrum_master.app.Application.doSomething())
Application activity
Application was deactivated, exiting

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM