Skip to content

mathisdelsart/JavaCOP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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+ Javassist Python 3.x Academic 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

Step Description Technique
Step 1 OOP baseline with switch statements Traditional Java
Step 2 COP via dynamic proxies java.lang.reflect.Proxy
Step 3 Feature chaining with proceed() Method delegation chain
Step 4 Bytecode profiler agent Javassist instrumentation

Step 1: OOP Baseline

Classic implementation using conditional statements:

public String getBackgroundColor() {
    switch (Mapping.currentContext) {
        case OUTSIDE: return "White";
        case INSIDE:
        case MEETING: return "Black";
    }
}

Step 2: COP via Proxies

Dynamic dispatch through feature classes:

IPhone phone = COP.newCOPInstance(IPhone.class, new PhoneCOP());
// Behavior determined by active features, not switch statements

Step 3: Proceed Mechanism

Feature chaining for cascading behaviors:

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

Step 4: Profiler Agent

Bytecode instrumentation for performance metrics:

// Automatically injected around methods:
long start = System.nanoTime();
// ... original method ...
long duration = 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 caching
COP.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.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors