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 a comprehensive caching system for weaved and generated classes to improve performance across JVM restarts. The caching system stores the results of weaving operations and can significantly reduce startup time for applications with many classes.
Main cache management class that handles weaved and generated classes.
public class WeavedClassCache {
public static WeavedClassCache createCache(ClassLoader loader, List<String> aspects,
GeneratedClassHandler existingClassHandler, IMessageHandler messageHandler);
public static void setDefaultCacheFactory(CacheFactory factory);
public static boolean isEnabled();
public static List<WeavedClassCache> getCaches();
public CachedClassReference createGeneratedCacheKey(String className);
public CachedClassReference createCacheKey(String className, byte[] originalBytes);
public GeneratedClassHandler getCachingClassHandler();
public void put(CachedClassReference ref, byte[] classBytes, byte[] weavedBytes);
public CachedClassEntry get(CachedClassReference ref, byte[] classBytes);
public void ignore(CachedClassReference ref, byte[] classBytes);
public void remove(CachedClassReference ref);
public void clear();
public CacheStatistics getStats();
public String getName();
}public static WeavedClassCache createCache(ClassLoader loader, List<String> aspects,
GeneratedClassHandler existingClassHandler, IMessageHandler messageHandler)Creates a cache instance for the specified classloader and aspects.
Parameters:
loader - ClassLoader to create cache foraspects - List of aspect names that will be appliedexistingClassHandler - Handler for generated classes (can be null)messageHandler - Handler for cache messages (can be null)Returns: WeavedClassCache instance for the classloader
public static void setDefaultCacheFactory(CacheFactory factory)Sets a custom cache factory for creating cache implementations.
Parameters:
factory - Custom cache factory implementationpublic static boolean isEnabled()Returns whether caching is enabled system-wide.
Returns: True if caching is enabled
public static List<WeavedClassCache> getCaches()Returns all active cache instances.
Returns: List of all WeavedClassCache instances
public CachedClassReference createGeneratedCacheKey(String className)Creates a cache key for a generated class.
Parameters:
className - Name of the generated classReturns: CachedClassReference for the generated class
public CachedClassReference createCacheKey(String className, byte[] originalBytes)Creates a cache key for a weaved class.
Parameters:
className - Name of the classoriginalBytes - Original class bytes before weavingReturns: CachedClassReference for the class
public void put(CachedClassReference ref, byte[] classBytes, byte[] weavedBytes)Stores weaved class in the cache.
Parameters:
ref - Cache reference for the classclassBytes - Original class bytesweavedBytes - Weaved class bytespublic CachedClassEntry get(CachedClassReference ref, byte[] classBytes)Retrieves a cached class entry.
Parameters:
ref - Cache reference for the classclassBytes - Original class bytes for validationReturns: CachedClassEntry if found, null otherwise
public void ignore(CachedClassReference ref, byte[] classBytes)Marks a class to be ignored by the cache.
Parameters:
ref - Cache reference for the classclassBytes - Class bytespublic void remove(CachedClassReference ref)Removes a class from the cache.
Parameters:
ref - Cache reference to removepublic void clear()Clears all entries from the cache.
public CacheStatistics getStats()Returns cache performance statistics.
Returns: CacheStatistics object with performance metrics
public String getName()Returns the cache name.
Returns: String name identifying the cache
Interface for creating custom cache implementations.
public interface CacheFactory {
CacheKeyResolver createResolver();
CacheBacking createBacking(String scope);
}Creates a cache key resolver.
CacheKeyResolver createResolver()Returns: CacheKeyResolver implementation
Creates a cache backing store.
CacheBacking createBacking(String scope)Parameters:
scope - Scope identifier for the cache backingReturns: CacheBacking implementation
Default implementation of CacheFactory.
public class DefaultCacheFactory implements CacheFactory {
public CacheKeyResolver createResolver();
public CacheBacking createBacking(String scope);
}Utility class for creating simple file-based caches, used internally by the weaver.
public class SimpleCacheFactory {
public static final String CACHE_ENABLED_PROPERTY = "aj.weaving.cache.enabled";
public static final String CACHE_DIR = "aj.weaving.cache.dir";
public static final String CACHE_IMPL = "aj.weaving.cache.impl";
public static SimpleCache createSimpleCache();
public static boolean isEnabled();
}Creates a simple cache instance based on system properties.
public static SimpleCache createSimpleCache()Returns: SimpleCache instance if caching is enabled, null otherwise
Returns whether simple caching is enabled via system properties.
public static boolean isEnabled()Returns: True if simple caching is enabled
Interface for generating and resolving cache keys.
public interface CacheKeyResolver {
CachedClassReference generatedKey(String className);
CachedClassReference weavedKey(String className, byte[] original_bytes);
String keyToClass(String key);
String createClassLoaderScope(ClassLoader loader, List<String> aspects);
String getGeneratedRegex();
String getWeavedRegex();
}Generates a cache key for a generated class.
CachedClassReference generatedKey(String className)Parameters:
className - Name of the generated classReturns: CachedClassReference for the generated class
Generates a cache key for a weaved class.
CachedClassReference weavedKey(String className, byte[] original_bytes)Parameters:
className - Name of the classoriginal_bytes - Original class bytesReturns: CachedClassReference for the weaved class
Converts a cache key back to a class name.
String keyToClass(String key)Parameters:
key - Cache key stringReturns: Class name corresponding to the key
Creates a scope identifier for a classloader and aspects.
String createClassLoaderScope(ClassLoader loader, List<String> aspects)Parameters:
loader - ClassLoader instanceaspects - List of aspect namesReturns: Scope identifier string
Default implementation of CacheKeyResolver.
public class DefaultCacheKeyResolver implements CacheKeyResolver {
// Implementation of all CacheKeyResolver methods
}Interface for cache storage backend.
public interface CacheBacking {
String[] getKeys(String regex);
void remove(CachedClassReference ref);
void clear();
CachedClassEntry get(CachedClassReference ref, byte[] originalBytes);
void put(CachedClassEntry entry, byte[] originalBytes);
}Returns all cache keys matching a regex pattern.
String[] getKeys(String regex)Parameters:
regex - Regular expression pattern to matchReturns: Array of matching cache keys
Retrieves a cache entry.
CachedClassEntry get(CachedClassReference ref, byte[] originalBytes)Parameters:
ref - Cache referenceoriginalBytes - Original class bytes for validationReturns: CachedClassEntry if found, null otherwise
Stores a cache entry.
void put(CachedClassEntry entry, byte[] originalBytes)Parameters:
entry - Cache entry to storeoriginalBytes - Original class bytesDefault file-based cache implementation.
public class DefaultFileCacheBacking extends AbstractFileCacheBacking {
// File-based cache storage
}Flat file cache implementation storing each class in a separate file.
public class FlatFileCacheBacking extends AbstractIndexedFileCacheBacking {
// Flat file storage implementation
}Zipped file cache implementation for compressed storage.
public class ZippedFileCacheBacking extends AbstractIndexedFileCacheBacking {
// Zipped file storage implementation
}Asynchronous file cache for non-blocking cache operations.
public class AsynchronousFileCacheBacking extends AbstractFileCacheBacking {
// Asynchronous file operations
}Reference to a cached class with key information.
public class CachedClassReference {
// Methods for accessing cache key information
}Represents a cached class entry with type information.
public class CachedClassEntry {
// Methods for accessing cached class data
}Statistics tracking for cache operations.
public class CacheStatistics {
// Methods for accessing cache performance metrics
}import org.aspectj.weaver.tools.cache.WeavedClassCache;
import java.util.Arrays;
import java.util.List;
public class BasicCacheExample {
public static void main(String[] args) {
ClassLoader loader = MyClass.class.getClassLoader();
List<String> aspects = Arrays.asList("com.example.LoggingAspect", "com.example.SecurityAspect");
// Create cache for classloader
WeavedClassCache cache = WeavedClassCache.createCache(loader, aspects, null, null);
// Create cache key
byte[] originalBytes = getOriginalClassBytes("com.example.MyClass");
CachedClassReference ref = cache.createCacheKey("com.example.MyClass", originalBytes);
// Check if class is cached
CachedClassEntry entry = cache.get(ref, originalBytes);
if (entry != null) {
System.out.println("Class found in cache");
byte[] cachedBytes = entry.getBytes();
// Use cached bytes
} else {
System.out.println("Class not in cache, need to weave");
// Weave class and store in cache
byte[] wovenBytes = weaveClass("com.example.MyClass", originalBytes);
cache.put(ref, originalBytes, wovenBytes);
}
// Get cache statistics
CacheStatistics stats = cache.getStats();
System.out.println("Cache hits: " + stats.getHits());
System.out.println("Cache misses: " + stats.getMisses());
}
private static byte[] getOriginalClassBytes(String className) {
// Implementation to read original class bytes
return new byte[0];
}
private static byte[] weaveClass(String className, byte[] originalBytes) {
// Implementation to weave class
return originalBytes;
}
}import org.aspectj.weaver.tools.cache.*;
public class CustomCacheExample {
public static void setupCustomCache() {
// Create custom cache factory
CacheFactory customFactory = new CacheFactory() {
@Override
public CacheKeyResolver createResolver() {
return new CustomCacheKeyResolver();
}
@Override
public CacheBacking createBacking(String scope) {
return new CustomCacheBacking(scope);
}
};
// Set as default factory
WeavedClassCache.setDefaultCacheFactory(customFactory);
// Subsequent cache creation will use custom factory
WeavedClassCache cache = WeavedClassCache.createCache(
classLoader, aspects, null, null);
}
private static class CustomCacheKeyResolver implements CacheKeyResolver {
@Override
public CachedClassReference generatedKey(String className) {
// Custom key generation logic
return new CachedClassReference();
}
@Override
public CachedClassReference weavedKey(String className, byte[] original_bytes) {
// Custom weaved key generation
return new CachedClassReference();
}
// Implement other methods...
}
private static class CustomCacheBacking implements CacheBacking {
private final String scope;
public CustomCacheBacking(String scope) {
this.scope = scope;
}
@Override
public CachedClassEntry get(CachedClassReference ref, byte[] originalBytes) {
// Custom retrieval logic
return null;
}
@Override
public void put(CachedClassEntry entry, byte[] originalBytes) {
// Custom storage logic
}
// Implement other methods...
}
}import org.aspectj.weaver.tools.cache.WeavedClassCache;
public class CacheManagement {
public static void manageCaches() {
// Check if caching is enabled
if (WeavedClassCache.isEnabled()) {
System.out.println("Caching is enabled");
// Get all active caches
List<WeavedClassCache> caches = WeavedClassCache.getCaches();
System.out.println("Active caches: " + caches.size());
// Print cache statistics
for (WeavedClassCache cache : caches) {
System.out.println("Cache: " + cache.getName());
CacheStatistics stats = cache.getStats();
System.out.println(" Hits: " + stats.getHits());
System.out.println(" Misses: " + stats.getMisses());
System.out.println(" Hit ratio: " + stats.getHitRatio());
}
} else {
System.out.println("Caching is disabled");
}
}
public static void clearAllCaches() {
List<WeavedClassCache> caches = WeavedClassCache.getCaches();
for (WeavedClassCache cache : caches) {
cache.clear();
System.out.println("Cleared cache: " + cache.getName());
}
}
}Enable caching:
System.setProperty(WeavedClassCache.WEAVED_CLASS_CACHE_ENABLED, "true");Set cache implementation:
System.setProperty(WeavedClassCache.CACHE_IMPL, "custom.CacheFactory");By default, caches are stored in the system temporary directory. Configure with:
System.setProperty("aj.cache.dir", "/path/to/cache/directory");// Enable cache debugging
System.setProperty("aj.cache.debug", "true");Install with Tessl CLI
npx tessl i tessl/maven-org-aspectj--aspectjweaver