The AspectJ weaver applies aspects to Java classes and can be used as a Java agent for load-time weaving (LTW).
—
The AspectJ Weaver provides programmatic APIs for embedding aspect weaving capabilities directly into applications. This allows developers to weave classes on-demand or integrate weaving into custom class loading mechanisms.
Main adaptor for embedding AspectJ weaving capabilities.
public class WeavingAdaptor {
public WeavingAdaptor(WeavingClassLoader loader);
public WeavingAdaptor(GeneratedClassHandler handler, URL[] classURLs, URL[] aspectURLs);
public void addURL(URL url);
public byte[] weaveClass(String name, byte[] bytes) throws IOException;
public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IOException;
public IMessageHolder getMessageHolder();
public String getContextId();
}public WeavingAdaptor(WeavingClassLoader loader)Creates a weaving adaptor with a weaving class loader.
Parameters:
loader - Class loader implementing WeavingClassLoader interfacepublic WeavingAdaptor(GeneratedClassHandler handler, URL[] classURLs, URL[] aspectURLs)Creates a weaving adaptor with explicit URLs and class handler.
Parameters:
handler - Handler for generated classes during weavingclassURLs - URLs containing classes to be wovenaspectURLs - URLs containing aspect definitionspublic void addURL(URL url)Adds a URL to the weaving classpath.
Parameters:
url - URL to add to classpathpublic byte[] weaveClass(String name, byte[] bytes) throws IOExceptionWeaves a class using the configured aspects.
Parameters:
name - Fully qualified class name (e.g., "com.example.MyClass")bytes - Original class bytesReturns: Woven class bytes or original bytes if no weaving applied
Throws: IOException if weaving fails
public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IOExceptionWeaves a class with optional forced weaving.
Parameters:
name - Fully qualified class namebytes - Original class bytesmustWeave - If true, forces weaving even if no aspects matchReturns: Woven class bytes
Throws: IOException if weaving fails
public IMessageHolder getMessageHolder()Returns the message holder for weaving messages and warnings.
Returns: IMessageHolder instance containing weaving messages
public String getContextId()Returns the context identifier for this weaving adaptor.
Returns: String identifier for the weaving context
Extended weaving adaptor with classloader-specific functionality.
public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
// Additional classloader-specific methods
}Generic preprocessor interface for separating AspectJ weaving from JVMTI interfaces.
public interface ClassPreProcessor {
void initialize();
byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader,
ProtectionDomain protectionDomain);
void prepareForRedefinition(ClassLoader loader, String className);
}Initializes the preprocessor.
void initialize()Preprocesses class bytes, applying weaving transformations.
byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader,
ProtectionDomain protectionDomain)Parameters:
className - Name of class being processedbytes - Original class bytesclassLoader - ClassLoader defining the classprotectionDomain - Security protection domainReturns: Processed class bytes
Prepares for class redefinition during hotswap scenarios.
void prepareForRedefinition(ClassLoader loader, String className)Parameters:
loader - ClassLoader containing the classclassName - Name of class being redefinedMain preprocessor implementation adapting between the preprocessor interface and AspectJ weaver.
public class Aj implements ClassPreProcessor {
public Aj();
public Aj(IWeavingContext context);
public void initialize();
public byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader,
ProtectionDomain protectionDomain);
}public Aj()Creates an Aj preprocessor with default weaving context.
public Aj(IWeavingContext context)Creates an Aj preprocessor with custom weaving context.
Parameters:
context - Custom weaving context for multi-classloader environmentsimport org.aspectj.weaver.tools.WeavingAdaptor;
import java.io.FileInputStream;
import java.io.IOException;
public class BasicWeavingExample {
public static void main(String[] args) throws IOException {
// Create weaving adaptor
WeavingAdaptor adaptor = new WeavingAdaptor(
null, // GeneratedClassHandler
new URL[]{new URL("file:///path/to/classes/")}, // Class URLs
new URL[]{new URL("file:///path/to/aspects/")} // Aspect URLs
);
// Read original class bytes
byte[] originalBytes = readClassBytes("com.example.MyClass");
// Weave the class
byte[] wovenBytes = adaptor.weaveClass("com.example.MyClass", originalBytes);
// Use the woven bytes (e.g., save to file or define class)
saveWovenClass("com.example.MyClass", wovenBytes);
// Check for weaving messages
IMessageHolder messages = adaptor.getMessageHolder();
if (messages.hasAnyMessage(IMessage.ERROR)) {
System.err.println("Weaving errors occurred");
}
}
private static byte[] readClassBytes(String className) throws IOException {
// Implementation to read class bytes from file system
String path = className.replace('.', '/') + ".class";
return Files.readAllBytes(Paths.get(path));
}
private static void saveWovenClass(String className, byte[] bytes) throws IOException {
// Implementation to save woven bytes
String path = "woven/" + className.replace('.', '/') + ".class";
Files.write(Paths.get(path), bytes);
}
}import org.aspectj.weaver.tools.WeavingAdaptor;
public class WeavingClassLoader extends URLClassLoader {
private final WeavingAdaptor weavingAdaptor;
public WeavingClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
this.weavingAdaptor = new WeavingAdaptor(this);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
// Get original class bytes
byte[] originalBytes = getClassBytes(name);
// Weave the class
byte[] wovenBytes = weavingAdaptor.weaveClass(name, originalBytes);
// Define the woven class
return defineClass(name, wovenBytes, 0, wovenBytes.length);
} catch (IOException e) {
throw new ClassNotFoundException("Failed to weave class: " + name, e);
}
}
private byte[] getClassBytes(String name) throws IOException {
String resourceName = name.replace('.', '/') + ".class";
InputStream is = getResourceAsStream(resourceName);
if (is == null) {
throw new IOException("Class not found: " + name);
}
return is.readAllBytes();
}
}import org.aspectj.weaver.loadtime.Aj;
import org.aspectj.weaver.loadtime.ClassPreProcessor;
public class CustomPreprocessorExample {
private final ClassPreProcessor processor;
public CustomPreprocessorExample() {
this.processor = new Aj();
processor.initialize();
}
public byte[] processClass(String className, byte[] originalBytes,
ClassLoader loader) {
return processor.preProcess(className, originalBytes, loader, null);
}
public void handleClassRedefinition(ClassLoader loader, String className) {
processor.prepareForRedefinition(loader, className);
}
}import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessageHolder;
public class WeavingDiagnostics {
public static void checkWeavingResults(WeavingAdaptor adaptor) {
IMessageHolder messages = adaptor.getMessageHolder();
// Check for errors
if (messages.hasAnyMessage(IMessage.ERROR)) {
System.err.println("Weaving errors:");
for (IMessage message : messages.getMessages(IMessage.ERROR, true)) {
System.err.println(" " + message.getMessage());
}
}
// Check for warnings
if (messages.hasAnyMessage(IMessage.WARNING)) {
System.out.println("Weaving warnings:");
for (IMessage message : messages.getMessages(IMessage.WARNING, true)) {
System.out.println(" " + message.getMessage());
}
}
// Check for info messages
if (messages.hasAnyMessage(IMessage.INFO)) {
System.out.println("Weaving info:");
for (IMessage message : messages.getMessages(IMessage.INFO, true)) {
System.out.println(" " + message.getMessage());
}
}
}
}WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE: Enable verbose weaving outputWeavingAdaptor.SHOW_WEAVE_INFO_PROPERTY: Show detailed weave informationWeavingAdaptor.TRACE_MESSAGES_PROPERTY: Enable message tracing// Enable verbose output
System.setProperty(WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE, "true");
// Create adaptor with verbose settings
WeavingAdaptor adaptor = new WeavingAdaptor(classLoader);// Enable debug output
System.setProperty("org.aspectj.weaver.showWeaveInfo", "true");
System.setProperty("aj.weaving.verbose", "true");Install with Tessl CLI
npx tessl i tessl/maven-org-aspectj--aspectjweaver