CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-aspectj--aspectjrt

The AspectJ runtime is a small library necessary to run Java programs enhanced by AspectJ aspects during a previous compile-time or post-compile-time (binary weaving) build step.

Pending
Overview
Eval results
Files

join-point-introspection.mddocs/

Join Point Introspection

Core runtime interfaces that provide reflective access to join points - the specific points in program execution where aspects can be applied. Join points represent method calls, method executions, field access, constructor calls, exception handlers, and other program execution events. The introspection API provides access to execution context, arguments, target objects, source location, and signature information.

Capabilities

JoinPoint Interface

The fundamental interface providing reflective access to both the state available at a join point and static information about it. Available in advice using the special form thisJoinPoint.

/**
 * Provides reflective access to both the state available at a join point and
 * static information about it. This information is available from the body
 * of advice using the special form thisJoinPoint.
 */
public interface JoinPoint {
    /**
     * Returns the currently executing object. This will always be
     * the same object as that matched by the this pointcut designator.
     * Returns null when there is no currently executing object available
     * (e.g. static context).
     */
    Object getThis();
    
    /**
     * Returns the target object. This will always be the same object
     * as that matched by the target pointcut designator.
     * Returns null when there is no target object.
     */
    Object getTarget();
    
    /**
     * Returns the arguments at this join point
     */
    Object[] getArgs();
    
    /**
     * Returns the signature at the join point
     */
    Signature getSignature();
    
    /**
     * Returns the source location corresponding to the join point.
     * If there is no source location available, returns null.
     * Returns the SourceLocation of the defining class for default constructors.
     */
    SourceLocation getSourceLocation();
    
    /**
     * Returns a string representing the kind of join point.
     * This string is guaranteed to be interned.
     */
    String getKind();
    
    /**
     * Returns an object that encapsulates the static parts of this join point
     */
    StaticPart getStaticPart();
    
    /**
     * String representation of this join point
     */
    String toString();
    
    /**
     * Returns an abbreviated string representation of the join point
     */
    String toShortString();
    
    /**
     * Returns an extended string representation of the join point
     */
    String toLongString();
}

Usage Examples:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {
    
    @Before("execution(* com.example.service.*.*(..))")
    public void logMethodEntry(JoinPoint joinPoint) {
        System.out.println("Entering: " + joinPoint.getSignature().getName());
        System.out.println("Target: " + joinPoint.getTarget());
        System.out.println("Args: " + Arrays.toString(joinPoint.getArgs()));
        System.out.println("Kind: " + joinPoint.getKind());
        System.out.println("Location: " + joinPoint.getSourceLocation());
    }
}

ProceedingJoinPoint Interface

Extends JoinPoint to expose the proceed() method for around advice in @AspectJ aspects. Allows advice to control whether and how the intercepted join point continues execution.

/**
 * ProceedingJoinPoint exposes the proceed(..) method in order to support
 * around advice in @AJ aspects
 */
public interface ProceedingJoinPoint extends JoinPoint {
    /**
     * Proceed with the next advice or target method invocation
     * @return the result of proceeding
     * @throws Throwable if the invoked proceed throws anything
     */
    Object proceed() throws Throwable;
    
    /**
     * Proceed with the next advice or target method invocation using modified arguments.
     * The proceed(..) call takes arguments in this order:
     * 1. If 'this()' was used in the pointcut for binding, it must be passed first
     * 2. If 'target()' was used in the pointcut for binding, it must be passed next
     * 3. All the arguments expected at the join point, in the order they are supplied
     * 
     * @param args the arguments to proceed with
     * @return the result of proceeding
     * @throws Throwable if the invoked proceed throws anything
     */
    Object proceed(Object[] args) throws Throwable;
}

Usage Examples:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class TimingAspect {
    
    @Around("execution(* com.example.service.*.*(..))")
    public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        
        try {
            // Proceed with original method execution
            Object result = joinPoint.proceed();
            return result;
        } finally {
            long executionTime = System.currentTimeMillis() - startTime;
            System.out.println("Method " + joinPoint.getSignature().getName() + 
                             " executed in " + executionTime + " ms");
        }
    }
    
    @Around("execution(* com.example.service.*.*(String, ..)) && args(firstArg, ..)")
    public Object interceptWithModifiedArgs(ProceedingJoinPoint joinPoint, String firstArg) throws Throwable {
        Object[] args = joinPoint.getArgs();
        
        // Modify the first argument
        args[0] = "Modified: " + firstArg;
        
        // Proceed with modified arguments
        return joinPoint.proceed(args);
    }
}

JoinPoint.StaticPart Interface

Contains only the static information about a join point. Available separately within advice using the special form thisJoinPointStaticPart. Use this for better performance when only static information is needed.

/**
 * This helper object contains only the static information about a join point.
 * If you are only interested in the static information about a join point,
 * you should access it through this type for the best performance.
 */
public interface StaticPart {
    /**
     * Returns the signature at the join point
     */
    Signature getSignature();
    
    /**
     * Returns the source location corresponding to the join point.
     * If there is no source location available, returns null.
     */
    SourceLocation getSourceLocation();
    
    /**
     * Returns a string representing the kind of join point.
     * This String is guaranteed to be interned.
     */
    String getKind();
    
    /**
     * Return the id for this JoinPoint.StaticPart. All JoinPoint.StaticPart
     * instances are assigned an id number upon creation. For each advised type
     * the id numbers start at 0. The id is guaranteed to remain constant
     * across repeated executions but may change if the code is recompiled.
     */
    int getId();
    
    String toString();
    String toShortString();
    String toLongString();
}

Usage Examples:

@Aspect
public class StaticAnalysisAspect {
    
    @Before("execution(* com.example..*.*(..))")
    public void analyzeJoinPoint(JoinPoint.StaticPart staticPart) {
        System.out.println("Join Point ID: " + staticPart.getId());
        System.out.println("Kind: " + staticPart.getKind());
        System.out.println("Signature: " + staticPart.getSignature());
        System.out.println("Location: " + staticPart.getSourceLocation());
    }
}

Join Point Kinds

Constants representing the different types of join points that can be intercepted:

public interface JoinPoint {
    // Method-related join points
    String METHOD_EXECUTION = "method-execution";
    String METHOD_CALL = "method-call";
    
    // Constructor-related join points
    String CONSTRUCTOR_EXECUTION = "constructor-execution";
    String CONSTRUCTOR_CALL = "constructor-call";
    
    // Field-related join points
    String FIELD_GET = "field-get";
    String FIELD_SET = "field-set";
    
    // Initialization join points
    String STATICINITIALIZATION = "staticinitialization";
    String PREINITIALIZATION = "preinitialization";
    String INITIALIZATION = "initialization";
    
    // Exception and synchronization join points
    String EXCEPTION_HANDLER = "exception-handler";
    String SYNCHRONIZATION_LOCK = "lock";
    String SYNCHRONIZATION_UNLOCK = "unlock";
    
    // Advice execution join point
    String ADVICE_EXECUTION = "adviceexecution";
}

EnclosingStaticPart Interface

Marker interface extending StaticPart for enclosing join point information:

/**
 * Marker interface for enclosing static part information
 */
public interface EnclosingStaticPart extends StaticPart {
}

Common Usage Patterns

Basic Join Point Logging

@Aspect
public class BasicLoggingAspect {
    
    @Before("execution(* com.example..*.*(..))")
    public void logEntry(JoinPoint jp) {
        System.out.println("==> " + jp.toShortString());
    }
    
    @AfterReturning(pointcut = "execution(* com.example..*.*(..))", returning = "result")
    public void logExit(JoinPoint jp, Object result) {
        System.out.println("<== " + jp.toShortString() + " returned " + result);
    }
}

Performance Monitoring

@Aspect
public class PerformanceAspect {
    
    @Around("execution(* com.example.service.*.*(..))")
    public Object monitorPerformance(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.nanoTime();
        String methodName = pjp.getSignature().toShortString();
        
        try {
            Object result = pjp.proceed();
            long duration = System.nanoTime() - start;
            System.out.printf("%s completed in %.2f ms%n", 
                            methodName, duration / 1_000_000.0);
            return result;
        } catch (Exception e) {
            long duration = System.nanoTime() - start;
            System.out.printf("%s failed after %.2f ms: %s%n", 
                            methodName, duration / 1_000_000.0, e.getMessage());
            throw e;
        }
    }
}

Argument Validation and Modification

@Aspect
public class ValidationAspect {
    
    @Around("execution(* com.example.service.*.save*(..)) && args(entity, ..)")
    public Object validateAndProceed(ProceedingJoinPoint pjp, Object entity) throws Throwable {
        if (entity == null) {
            throw new IllegalArgumentException("Entity cannot be null for " + 
                                             pjp.getSignature().getName());
        }
        
        // Log the validation
        System.out.println("Validating " + entity.getClass().getSimpleName() + 
                          " for " + pjp.getSignature().getName());
        
        return pjp.proceed();
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-aspectj--aspectjrt

docs

annotation-based-definition.md

aspect-management.md

index.md

join-point-introspection.md

reflection-api.md

runtime-utilities.md

signature-system.md

tile.json