PACCL is a Java-based framework designed to support dynamic class loading and plugin-based runtime bytecode transformations. This project leverages a custom class loader and a plugin architecture to enable powerful runtime enhancements for Java applications.
Dynamically loads plugins annotated with custom metadata. Manages plugins and associates them with target classes.
Transforms Java class bytecode at runtime using ASM (Java bytecode manipulation library). Supports field access tracking, logging injection, and other runtime enhancements.
Caches classes to improve performance. Integrates seamlessly with plugins for transformation logic.
Simplifies plugin development with @Plugin and @PluginMetadata annotations. Project Structure
src/
├── main/
│ ├── java/
│ │ └── net/
│ │ └── laurus/
│ │ ├── LibraryLoader.java
│ │ ├── MainRunner.java
│ │ ├── PluginAwareCachingClassLoader.java
│ │ ├── PluginManager.java
│ │ ├── cls/
│ │ │ └── plugins/
│ │ └── interfaces/
│ │ ├── Plugin.java
│ │ ├── PluginMetadata.java
│ │ └── TransformerPlugin.java
│ └── resources/
│ └── logback.xml
example/
├── ExamplePlugin.java
├── FieldAccessTrackerPlugin.java
└── LoggingInjectorPlugin.java
plugins/
└── AnyPlugin.jar
main/
└── Target.jar- Caches loaded classes to improve performance.
- Integrates with plugins to apply bytecode transformations during the loading process.
- Handles:
- Reading bytecode from classpath.
- Applying transformations via plugins.
- Verifying cache integrity using hashes.
- Discovers and loads plugins using the Reflections library.
- Validates plugins with @Plugin and @PluginMetadata annotations.
- Maps plugins to their target classes based on metadata.
- Provides runtime access to applicable plugins for specific classes.
- Annotations:
- @Plugin: Marks a class as a plugin.
- @PluginMetadata: Specifies plugin details like name, version, author, description, and target classes.
- Examples:
- ExamplePlugin.java: Demonstrates a no-operation transformation.
- FieldAccessTrackerPlugin.java: Injects tracking logic for field reads and writes.
- LoggingInjectorPlugin.java: Adds logging at method entry and exit points.
- TransformerPlugin: Defines the core contract for plugins, requiring implementation of the transform method.
- Plugin: Annotation to mark a class as a plugin.
- PluginMetadata: Provides metadata for plugins.
- Java Development Kit (JDK) 11 or later.
- Apache Maven for dependency management and project builds.
Clone the repository:
git clone https://github.com/LunarLaurus/paccl.git
cd pacclBuild the project using Maven:
mvn clean installRun the application:
java -jar target/paccl-<version>.jar targetJarFileName targetMainClassFqrnCreate a new class implementing TransformerPlugin. Annotate the class with @Plugin and @PluginMetadata to specify its details and target classes. Compile the plugin and place the JAR file in the plugin directory.
- FieldAccessTrackerPlugin Tracks all field reads and writes in specified target classes.
@Override
public byte[] transform(String className, byte[] classBytes) {
ClassReader reader = new ClassReader(classBytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = new FieldAccessClassVisitor(Opcodes.ASM9, writer);
reader.accept(visitor, 0);
return writer.toByteArray();
}- LoggingInjectorPlugin Adds logging statements at the start and end of methods.
@Override
public byte[] transform(String className, byte[] classBytes) {
ClassReader reader = new ClassReader(classBytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = new LoggingClassVisitor(Opcodes.ASM9, writer);
reader.accept(visitor, 0);
return writer.toByteArray();
}This project is licensed under the LGPLv3 License. See the LICENSE file for more details.