Issue with AOP and JMX without Spring

爱⌒轻易说出口 提交于 2019-12-11 12:46:18

问题


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>

回答1:


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


来源:https://stackoverflow.com/questions/24014397/issue-with-aop-and-jmx-without-spring

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!