0
# Class Caching
1
2
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.
3
4
## Core Cache Classes
5
6
### WeavedClassCache
7
8
Main cache management class that handles weaved and generated classes.
9
10
```java { .api }
11
public class WeavedClassCache {
12
public static WeavedClassCache createCache(ClassLoader loader, List<String> aspects,
13
GeneratedClassHandler existingClassHandler, IMessageHandler messageHandler);
14
public static void setDefaultCacheFactory(CacheFactory factory);
15
public static boolean isEnabled();
16
public static List<WeavedClassCache> getCaches();
17
public CachedClassReference createGeneratedCacheKey(String className);
18
public CachedClassReference createCacheKey(String className, byte[] originalBytes);
19
public GeneratedClassHandler getCachingClassHandler();
20
public void put(CachedClassReference ref, byte[] classBytes, byte[] weavedBytes);
21
public CachedClassEntry get(CachedClassReference ref, byte[] classBytes);
22
public void ignore(CachedClassReference ref, byte[] classBytes);
23
public void remove(CachedClassReference ref);
24
public void clear();
25
public CacheStatistics getStats();
26
public String getName();
27
}
28
```
29
30
#### Static Methods
31
32
```java { .api }
33
public static WeavedClassCache createCache(ClassLoader loader, List<String> aspects,
34
GeneratedClassHandler existingClassHandler, IMessageHandler messageHandler)
35
```
36
37
Creates a cache instance for the specified classloader and aspects.
38
39
**Parameters:**
40
- `loader` - ClassLoader to create cache for
41
- `aspects` - List of aspect names that will be applied
42
- `existingClassHandler` - Handler for generated classes (can be null)
43
- `messageHandler` - Handler for cache messages (can be null)
44
45
**Returns:** WeavedClassCache instance for the classloader
46
47
```java { .api }
48
public static void setDefaultCacheFactory(CacheFactory factory)
49
```
50
51
Sets a custom cache factory for creating cache implementations.
52
53
**Parameters:**
54
- `factory` - Custom cache factory implementation
55
56
```java { .api }
57
public static boolean isEnabled()
58
```
59
60
Returns whether caching is enabled system-wide.
61
62
**Returns:** True if caching is enabled
63
64
```java { .api }
65
public static List<WeavedClassCache> getCaches()
66
```
67
68
Returns all active cache instances.
69
70
**Returns:** List of all WeavedClassCache instances
71
72
#### Instance Methods
73
74
```java { .api }
75
public CachedClassReference createGeneratedCacheKey(String className)
76
```
77
78
Creates a cache key for a generated class.
79
80
**Parameters:**
81
- `className` - Name of the generated class
82
83
**Returns:** CachedClassReference for the generated class
84
85
```java { .api }
86
public CachedClassReference createCacheKey(String className, byte[] originalBytes)
87
```
88
89
Creates a cache key for a weaved class.
90
91
**Parameters:**
92
- `className` - Name of the class
93
- `originalBytes` - Original class bytes before weaving
94
95
**Returns:** CachedClassReference for the class
96
97
```java { .api }
98
public void put(CachedClassReference ref, byte[] classBytes, byte[] weavedBytes)
99
```
100
101
Stores weaved class in the cache.
102
103
**Parameters:**
104
- `ref` - Cache reference for the class
105
- `classBytes` - Original class bytes
106
- `weavedBytes` - Weaved class bytes
107
108
```java { .api }
109
public CachedClassEntry get(CachedClassReference ref, byte[] classBytes)
110
```
111
112
Retrieves a cached class entry.
113
114
**Parameters:**
115
- `ref` - Cache reference for the class
116
- `classBytes` - Original class bytes for validation
117
118
**Returns:** CachedClassEntry if found, null otherwise
119
120
```java { .api }
121
public void ignore(CachedClassReference ref, byte[] classBytes)
122
```
123
124
Marks a class to be ignored by the cache.
125
126
**Parameters:**
127
- `ref` - Cache reference for the class
128
- `classBytes` - Class bytes
129
130
```java { .api }
131
public void remove(CachedClassReference ref)
132
```
133
134
Removes a class from the cache.
135
136
**Parameters:**
137
- `ref` - Cache reference to remove
138
139
```java { .api }
140
public void clear()
141
```
142
143
Clears all entries from the cache.
144
145
```java { .api }
146
public CacheStatistics getStats()
147
```
148
149
Returns cache performance statistics.
150
151
**Returns:** CacheStatistics object with performance metrics
152
153
```java { .api }
154
public String getName()
155
```
156
157
Returns the cache name.
158
159
**Returns:** String name identifying the cache
160
161
## Cache Factory Interface
162
163
### CacheFactory
164
165
Interface for creating custom cache implementations.
166
167
```java { .api }
168
public interface CacheFactory {
169
CacheKeyResolver createResolver();
170
CacheBacking createBacking(String scope);
171
}
172
```
173
174
#### createResolver
175
176
Creates a cache key resolver.
177
178
```java { .api }
179
CacheKeyResolver createResolver()
180
```
181
182
**Returns:** CacheKeyResolver implementation
183
184
#### createBacking
185
186
Creates a cache backing store.
187
188
```java { .api }
189
CacheBacking createBacking(String scope)
190
```
191
192
**Parameters:**
193
- `scope` - Scope identifier for the cache backing
194
195
**Returns:** CacheBacking implementation
196
197
### DefaultCacheFactory
198
199
Default implementation of CacheFactory.
200
201
```java { .api }
202
public class DefaultCacheFactory implements CacheFactory {
203
public CacheKeyResolver createResolver();
204
public CacheBacking createBacking(String scope);
205
}
206
```
207
208
### SimpleCacheFactory
209
210
Utility class for creating simple file-based caches, used internally by the weaver.
211
212
```java { .api }
213
public class SimpleCacheFactory {
214
public static final String CACHE_ENABLED_PROPERTY = "aj.weaving.cache.enabled";
215
public static final String CACHE_DIR = "aj.weaving.cache.dir";
216
public static final String CACHE_IMPL = "aj.weaving.cache.impl";
217
public static SimpleCache createSimpleCache();
218
public static boolean isEnabled();
219
}
220
```
221
222
#### createSimpleCache
223
224
Creates a simple cache instance based on system properties.
225
226
```java { .api }
227
public static SimpleCache createSimpleCache()
228
```
229
230
**Returns:** SimpleCache instance if caching is enabled, null otherwise
231
232
#### isEnabled
233
234
Returns whether simple caching is enabled via system properties.
235
236
```java { .api }
237
public static boolean isEnabled()
238
```
239
240
**Returns:** True if simple caching is enabled
241
242
## Cache Key Resolution
243
244
### CacheKeyResolver
245
246
Interface for generating and resolving cache keys.
247
248
```java { .api }
249
public interface CacheKeyResolver {
250
CachedClassReference generatedKey(String className);
251
CachedClassReference weavedKey(String className, byte[] original_bytes);
252
String keyToClass(String key);
253
String createClassLoaderScope(ClassLoader loader, List<String> aspects);
254
String getGeneratedRegex();
255
String getWeavedRegex();
256
}
257
```
258
259
#### generatedKey
260
261
Generates a cache key for a generated class.
262
263
```java { .api }
264
CachedClassReference generatedKey(String className)
265
```
266
267
**Parameters:**
268
- `className` - Name of the generated class
269
270
**Returns:** CachedClassReference for the generated class
271
272
#### weavedKey
273
274
Generates a cache key for a weaved class.
275
276
```java { .api }
277
CachedClassReference weavedKey(String className, byte[] original_bytes)
278
```
279
280
**Parameters:**
281
- `className` - Name of the class
282
- `original_bytes` - Original class bytes
283
284
**Returns:** CachedClassReference for the weaved class
285
286
#### keyToClass
287
288
Converts a cache key back to a class name.
289
290
```java { .api }
291
String keyToClass(String key)
292
```
293
294
**Parameters:**
295
- `key` - Cache key string
296
297
**Returns:** Class name corresponding to the key
298
299
#### createClassLoaderScope
300
301
Creates a scope identifier for a classloader and aspects.
302
303
```java { .api }
304
String createClassLoaderScope(ClassLoader loader, List<String> aspects)
305
```
306
307
**Parameters:**
308
- `loader` - ClassLoader instance
309
- `aspects` - List of aspect names
310
311
**Returns:** Scope identifier string
312
313
### DefaultCacheKeyResolver
314
315
Default implementation of CacheKeyResolver.
316
317
```java { .api }
318
public class DefaultCacheKeyResolver implements CacheKeyResolver {
319
// Implementation of all CacheKeyResolver methods
320
}
321
```
322
323
## Cache Backing Store
324
325
### CacheBacking
326
327
Interface for cache storage backend.
328
329
```java { .api }
330
public interface CacheBacking {
331
String[] getKeys(String regex);
332
void remove(CachedClassReference ref);
333
void clear();
334
CachedClassEntry get(CachedClassReference ref, byte[] originalBytes);
335
void put(CachedClassEntry entry, byte[] originalBytes);
336
}
337
```
338
339
#### getKeys
340
341
Returns all cache keys matching a regex pattern.
342
343
```java { .api }
344
String[] getKeys(String regex)
345
```
346
347
**Parameters:**
348
- `regex` - Regular expression pattern to match
349
350
**Returns:** Array of matching cache keys
351
352
#### get
353
354
Retrieves a cache entry.
355
356
```java { .api }
357
CachedClassEntry get(CachedClassReference ref, byte[] originalBytes)
358
```
359
360
**Parameters:**
361
- `ref` - Cache reference
362
- `originalBytes` - Original class bytes for validation
363
364
**Returns:** CachedClassEntry if found, null otherwise
365
366
#### put
367
368
Stores a cache entry.
369
370
```java { .api }
371
void put(CachedClassEntry entry, byte[] originalBytes)
372
```
373
374
**Parameters:**
375
- `entry` - Cache entry to store
376
- `originalBytes` - Original class bytes
377
378
### File-Based Cache Implementations
379
380
#### DefaultFileCacheBacking
381
382
Default file-based cache implementation.
383
384
```java { .api }
385
public class DefaultFileCacheBacking extends AbstractFileCacheBacking {
386
// File-based cache storage
387
}
388
```
389
390
#### FlatFileCacheBacking
391
392
Flat file cache implementation storing each class in a separate file.
393
394
```java { .api }
395
public class FlatFileCacheBacking extends AbstractIndexedFileCacheBacking {
396
// Flat file storage implementation
397
}
398
```
399
400
#### ZippedFileCacheBacking
401
402
Zipped file cache implementation for compressed storage.
403
404
```java { .api }
405
public class ZippedFileCacheBacking extends AbstractIndexedFileCacheBacking {
406
// Zipped file storage implementation
407
}
408
```
409
410
#### AsynchronousFileCacheBacking
411
412
Asynchronous file cache for non-blocking cache operations.
413
414
```java { .api }
415
public class AsynchronousFileCacheBacking extends AbstractFileCacheBacking {
416
// Asynchronous file operations
417
}
418
```
419
420
## Data Types
421
422
### CachedClassReference
423
424
Reference to a cached class with key information.
425
426
```java { .api }
427
public class CachedClassReference {
428
// Methods for accessing cache key information
429
}
430
```
431
432
### CachedClassEntry
433
434
Represents a cached class entry with type information.
435
436
```java { .api }
437
public class CachedClassEntry {
438
// Methods for accessing cached class data
439
}
440
```
441
442
### CacheStatistics
443
444
Statistics tracking for cache operations.
445
446
```java { .api }
447
public class CacheStatistics {
448
// Methods for accessing cache performance metrics
449
}
450
```
451
452
## Usage Examples
453
454
### Basic Cache Usage
455
456
```java
457
import org.aspectj.weaver.tools.cache.WeavedClassCache;
458
import java.util.Arrays;
459
import java.util.List;
460
461
public class BasicCacheExample {
462
public static void main(String[] args) {
463
ClassLoader loader = MyClass.class.getClassLoader();
464
List<String> aspects = Arrays.asList("com.example.LoggingAspect", "com.example.SecurityAspect");
465
466
// Create cache for classloader
467
WeavedClassCache cache = WeavedClassCache.createCache(loader, aspects, null, null);
468
469
// Create cache key
470
byte[] originalBytes = getOriginalClassBytes("com.example.MyClass");
471
CachedClassReference ref = cache.createCacheKey("com.example.MyClass", originalBytes);
472
473
// Check if class is cached
474
CachedClassEntry entry = cache.get(ref, originalBytes);
475
if (entry != null) {
476
System.out.println("Class found in cache");
477
byte[] cachedBytes = entry.getBytes();
478
// Use cached bytes
479
} else {
480
System.out.println("Class not in cache, need to weave");
481
// Weave class and store in cache
482
byte[] wovenBytes = weaveClass("com.example.MyClass", originalBytes);
483
cache.put(ref, originalBytes, wovenBytes);
484
}
485
486
// Get cache statistics
487
CacheStatistics stats = cache.getStats();
488
System.out.println("Cache hits: " + stats.getHits());
489
System.out.println("Cache misses: " + stats.getMisses());
490
}
491
492
private static byte[] getOriginalClassBytes(String className) {
493
// Implementation to read original class bytes
494
return new byte[0];
495
}
496
497
private static byte[] weaveClass(String className, byte[] originalBytes) {
498
// Implementation to weave class
499
return originalBytes;
500
}
501
}
502
```
503
504
### Custom Cache Factory
505
506
```java
507
import org.aspectj.weaver.tools.cache.*;
508
509
public class CustomCacheExample {
510
public static void setupCustomCache() {
511
// Create custom cache factory
512
CacheFactory customFactory = new CacheFactory() {
513
@Override
514
public CacheKeyResolver createResolver() {
515
return new CustomCacheKeyResolver();
516
}
517
518
@Override
519
public CacheBacking createBacking(String scope) {
520
return new CustomCacheBacking(scope);
521
}
522
};
523
524
// Set as default factory
525
WeavedClassCache.setDefaultCacheFactory(customFactory);
526
527
// Subsequent cache creation will use custom factory
528
WeavedClassCache cache = WeavedClassCache.createCache(
529
classLoader, aspects, null, null);
530
}
531
532
private static class CustomCacheKeyResolver implements CacheKeyResolver {
533
@Override
534
public CachedClassReference generatedKey(String className) {
535
// Custom key generation logic
536
return new CachedClassReference();
537
}
538
539
@Override
540
public CachedClassReference weavedKey(String className, byte[] original_bytes) {
541
// Custom weaved key generation
542
return new CachedClassReference();
543
}
544
545
// Implement other methods...
546
}
547
548
private static class CustomCacheBacking implements CacheBacking {
549
private final String scope;
550
551
public CustomCacheBacking(String scope) {
552
this.scope = scope;
553
}
554
555
@Override
556
public CachedClassEntry get(CachedClassReference ref, byte[] originalBytes) {
557
// Custom retrieval logic
558
return null;
559
}
560
561
@Override
562
public void put(CachedClassEntry entry, byte[] originalBytes) {
563
// Custom storage logic
564
}
565
566
// Implement other methods...
567
}
568
}
569
```
570
571
### Cache Management
572
573
```java
574
import org.aspectj.weaver.tools.cache.WeavedClassCache;
575
576
public class CacheManagement {
577
public static void manageCaches() {
578
// Check if caching is enabled
579
if (WeavedClassCache.isEnabled()) {
580
System.out.println("Caching is enabled");
581
582
// Get all active caches
583
List<WeavedClassCache> caches = WeavedClassCache.getCaches();
584
System.out.println("Active caches: " + caches.size());
585
586
// Print cache statistics
587
for (WeavedClassCache cache : caches) {
588
System.out.println("Cache: " + cache.getName());
589
CacheStatistics stats = cache.getStats();
590
System.out.println(" Hits: " + stats.getHits());
591
System.out.println(" Misses: " + stats.getMisses());
592
System.out.println(" Hit ratio: " + stats.getHitRatio());
593
}
594
} else {
595
System.out.println("Caching is disabled");
596
}
597
}
598
599
public static void clearAllCaches() {
600
List<WeavedClassCache> caches = WeavedClassCache.getCaches();
601
for (WeavedClassCache cache : caches) {
602
cache.clear();
603
System.out.println("Cleared cache: " + cache.getName());
604
}
605
}
606
}
607
```
608
609
## Configuration
610
611
### System Properties
612
613
Enable caching:
614
```java
615
System.setProperty(WeavedClassCache.WEAVED_CLASS_CACHE_ENABLED, "true");
616
```
617
618
Set cache implementation:
619
```java
620
System.setProperty(WeavedClassCache.CACHE_IMPL, "custom.CacheFactory");
621
```
622
623
### Cache Directory
624
625
By default, caches are stored in the system temporary directory. Configure with:
626
```java
627
System.setProperty("aj.cache.dir", "/path/to/cache/directory");
628
```
629
630
## Performance Considerations
631
632
1. **Cache Location**: Use fast storage (SSD) for cache directory
633
2. **Cache Size**: Monitor cache size and implement cleanup strategies
634
3. **Concurrent Access**: Cache implementations handle concurrent access
635
4. **Memory Usage**: Large caches may impact memory usage
636
637
## Troubleshooting
638
639
### Common Issues
640
641
1. **Cache Not Working**: Check that caching is enabled and cache directory is writable
642
2. **Performance Issues**: Monitor cache hit ratios and consider cache size limits
643
3. **Disk Space**: Implement cache cleanup for long-running applications
644
645
### Debug Output
646
647
```java
648
// Enable cache debugging
649
System.setProperty("aj.cache.debug", "true");
650
```