Skip to content

Repository files navigation

JavaCOP

Context-Oriented Programming in Java using reflection, dynamic proxies, and bytecode instrumentation. Includes a custom profiler agent for performance analysis.

Java 11+JavassistPython 3.xAcademic License

AboutFeaturesStepsUsageProfiler


About

JavaCOP demonstrates how to implement Context-Oriented Programming (COP) in Java through a progressive, step-by-step approach. The project simulates a phone application that adapts its behavior based on context (INSIDE, OUTSIDE, MEETING), comparing traditional OOP with COP implementations.

Core Concept

Context + Behavior = Dynamic Adaptation

Instead of hardcoded switch statements, COP uses dynamic proxies and feature composition to adapt behavior at runtime based on the active context.


Features

Metaprogramming Techniques

  • Dynamic Proxies — Runtime interface implementations via java.lang.reflect.Proxy
  • Method Interception — Capturing and routing calls based on context
  • Bytecode Instrumentation — Runtime code injection with Javassist
  • Java Agent — Non-invasive profiling via Instrumentation API

COP Constructs

  • Feature Classes — Modular behavior units (Ring, Mute, Vibrate, etc.)
  • Context Mapping — Dynamic feature activation based on context
  • Proceed Mechanism — Feature chaining similar to aspect-oriented programming
  • Method Caching — Performance optimization for reflection-based dispatch

Implementation Steps

StepDescriptionTechnique
Step 1OOP baseline with switch statementsTraditional Java
Step 2COP via dynamic proxiesjava.lang.reflect.Proxy
Step 3Feature chaining with proceed()Method delegation chain
Step 4Bytecode profiler agentJavassist instrumentation

Step 1: OOP Baseline

Classic implementation using conditional statements:

publicStringgetBackgroundColor() {
switch (Mapping.currentContext) {
caseOUTSIDE: return"White";
caseINSIDE:
caseMEETING: return"Black";
}
}

Step 2: COP via Proxies

Dynamic dispatch through feature classes:

IPhonephone = COP.newCOPInstance(IPhone.class, newPhoneCOP());
// Behavior determined by active features, not switch statements

Step 3: Proceed Mechanism

Feature chaining for cascading behaviors:

publicvoidring() {
System.out.println("🔔 Ring!");
proceed(); // Calls next feature in chain
}

Step 4: Profiler Agent

Bytecode instrumentation for performance metrics:

// Automatically injected around methods:longstart = System.nanoTime();
// ... original method ...longduration = System.nanoTime() - start;

Usage

Prerequisites

  • Java JDK 11+
  • Javassist (included in step4/lib/)
  • Python 3.x (for analysis scripts)

Quick Start

# Run Step 1 (OOP)
make run-step1
# Run Step 2 (COP Proxies)
make run-step2
# Run Step 3 (Proceed)
make run-step3
# Run all with profiler
make profile-all

Manual Execution

# Compile and run a step
javac step1/Main.java step1/reflection/**/*.java
java step1.Main
# With profiler
make build-profiler
java -javaagent:profiler.jar=results.txt step1.Main

Configuration Options

Toggle caching and logging in Main.java:

COP.setUseCache(true); // Enable method cachingCOP.setVerboseLogging(true); // Enable debug output

Profiler

How It Works

The profiler uses Javassist to inject timing and memory measurement code around every method call:

step1.reflection.phone.Phone.ring(): 0.023ms (Memory: 128kb)
step2.reflection.phone.COP.invoke(): 0.156ms (Memory: 256kb)

Running the Profiler

# Build profiler agent
make build-profiler
# Profile all steps
make profile-all
# Results saved to results_profiler/

Analysis Scripts

Python scripts in step4/script_python/ generate performance visualizations:

cd step4/script_python
pip install -r requirements.txt
python plot.py
# Charts saved to Figures/

Repository Structure

JavaCOP/
├── step1/ # OOP baseline implementation
│ ├── Main.java
│ └── reflection/
│ ├── context/Mapping.java
│ └── phone/
├── step2/ # COP with dynamic proxies
│ ├── Main.java
│ └── reflection/
│ ├── phone/COP.java # Proxy factory
│ └── phone/features/ # Feature classes
├── step3/ # Proceed mechanism
│ ├── Main.java
│ └── reflection/
│ └── phone/Feature.java # Base feature with proceed()
├── step4/ # Profiler agent
│ ├── ProfilerAgent.java # Bytecode instrumentation
│ ├── lib/javassist-3.29.0-GA.jar
│ ├── manifest.txt
│ ├── script_python/ # Analysis scripts
│ │ ├── plot.py
│ │ └── Figures/
│ └── README.md # Detailed analysis results
├── results_profiler/ # Profiler output files
├── guideline.pdf # Project specification
├── Makefile # Build automation
├── .gitignore
└── README.md

Author

Mathis DELSART

License

This project is developed for academic purposes as part of university coursework.


Built for LINFO2335 - Programming Paradigms @ UCLouvain (Université catholique de Louvain).

Context is king — let your code adapt

About

Context-Oriented Programming in Java using reflection, dynamic proxies, and bytecode instrumentation. Includes a custom profiler agent.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages