RepoPilotOpen in app →

jboss-javassist/javassist

Java bytecode engineering toolkit

Mixed

Mixed signals — read the receipts

weakest axis
Use as dependencyConcerns

non-standard license (Other)

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3w ago
  • 20 active contributors
  • Other licensed
Show all 7 evidence items →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 63% of recent commits
  • Non-standard license (Other) — review terms
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/jboss-javassist/javassist?axis=fork)](https://repopilot.app/r/jboss-javassist/javassist)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/jboss-javassist/javassist on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: jboss-javassist/javassist

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/jboss-javassist/javassist shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Mixed signals — read the receipts

  • Last commit 3w ago
  • 20 active contributors
  • Other licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 63% of recent commits
  • ⚠ Non-standard license (Other) — review terms

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live jboss-javassist/javassist repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/jboss-javassist/javassist.

What it runs against: a local clone of jboss-javassist/javassist — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in jboss-javassist/javassist | Confirms the artifact applies here, not a fork | | 2 | License is still Other | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 49 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>jboss-javassist/javassist</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of jboss-javassist/javassist. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/jboss-javassist/javassist.git
#   cd javassist
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of jboss-javassist/javassist and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "jboss-javassist/javassist(\\.git)?\\b" \\
  && ok "origin remote is jboss-javassist/javassist" \\
  || miss "origin remote is not jboss-javassist/javassist (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "src/main/javassist/ClassPool.java" \\
  && ok "src/main/javassist/ClassPool.java" \\
  || miss "missing critical file: src/main/javassist/ClassPool.java"
test -f "src/main/javassist/CtClass.java" \\
  && ok "src/main/javassist/CtClass.java" \\
  || miss "missing critical file: src/main/javassist/CtClass.java"
test -f "src/main/javassist/bytecode/ClassFile.java" \\
  && ok "src/main/javassist/bytecode/ClassFile.java" \\
  || miss "missing critical file: src/main/javassist/bytecode/ClassFile.java"
test -f "src/main/javassist/bytecode/ConstPool.java" \\
  && ok "src/main/javassist/bytecode/ConstPool.java" \\
  || miss "missing critical file: src/main/javassist/bytecode/ConstPool.java"
test -f "src/main/javassist/bytecode/CodeAttribute.java" \\
  && ok "src/main/javassist/bytecode/CodeAttribute.java" \\
  || miss "missing critical file: src/main/javassist/bytecode/CodeAttribute.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 49 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~19d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/jboss-javassist/javassist"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Javassist is a Java bytecode manipulation library that enables runtime class generation and modification without requiring knowledge of JVM bytecode specifications. It provides both source-level and bytecode-level APIs, allowing developers to define new classes dynamically, insert code into existing classes at load time, and even compile source text snippets on-the-fly into bytecode. Core use cases include AOP frameworks, ORM tools, hot-swapping code, and runtime code instrumentation. Single-artifact JAR structure: source lives in ./src/main (inferred from pom.xml), compiled to ./javassist.jar. The ./sample directory contains 6 self-contained example projects (duplicate/, evolve/, hotswap/, preproc/, reflect/, rmi/, vector/) demonstrating use cases—each with its own Main or Test class. Build system is Maven-primary with Ant (build.xml) as alternate; no modular subprojects.

👥Who it's for

JVM framework developers (Hibernate, Spring, JBoss) and library authors building tools that need to intercept or transform classes at runtime; also used by developers implementing aspect-oriented programming, code generation, or dynamic proxying without external bytecode editors.

🌱Maturity & risk

Highly mature and production-ready: created in 1999, currently at version 3.31.0-GA, with Maven CI/CD via GitHub Actions (maven.yml workflow), multiple license support (MPL 1.1, LGPL 2.1, Apache 2.0), and active maintenance under the JBoss/Red Hat stewardship. The codebase is stable with 3.1M lines of Java code and well-established in enterprise ecosystems.

Low risk for production use but note: single primary maintainer (Shigeru Chiba) model with JBoss stewardship provides stability; no visible open-issue backlog in provided data, but bytecode manipulation is inherently JVM-version-sensitive, so Java version upgrades may require updates. The project has no external Maven dependencies listed in the pom.xml snippet, reducing dependency risk.

Active areas of work

Based on file structure: active maintenance with Maven CI/CD workflow (maven.yml), recent changes tracked in Changes.md, and examples kept current. The hotswap/, evolve/, and reflect/ samples suggest ongoing focus on runtime transformation and class reloading scenarios. No specific PR/milestone data visible, but the 3.31.0-GA release and GitHub Actions setup indicate ongoing release cycle.

🚀Get running

Clone the repository and build with Maven:

git clone https://github.com/jboss-javassist/javassist.git
cd javassist
mvn clean install

Verify installation:

java -jar javassist.jar

Daily commands: This is a library, not an application. To run examples:

cd sample/hotswap
javac *.java
java Test

Or build and test the library itself:

mvn test

🗺️Map of the codebase

  • src/main/javassist/ClassPool.java — Central registry for managing and loading CtClass objects; entry point for most bytecode manipulation workflows.
  • src/main/javassist/CtClass.java — Core abstraction representing a Java class; all high-level class modifications flow through this interface.
  • src/main/javassist/bytecode/ClassFile.java — Low-level bytecode representation of a class; directly manipulates JVM class file format.
  • src/main/javassist/bytecode/ConstPool.java — Constant pool manager for bytecode; essential for resolving and generating class references and literals.
  • src/main/javassist/bytecode/CodeAttribute.java — Encapsulates method bytecode and exception tables; critical for injecting and analyzing method implementations.
  • src/main/javassist/CtBehavior.java — Base abstraction for methods and constructors; primary API for runtime method instrumentation.
  • src/main/javassist/Loader.java — Custom classloader enabling runtime class modification at load time via Translator chain.

🛠️How to make changes

Add a new method to a class at runtime

  1. Obtain the CtClass for the target class from ClassPool (src/main/javassist/ClassPool.java)
  2. Create a new CtMethod using CtNewMethod factory with desired signature and body (src/main/javassist/CtNewMethod.java)
  3. Add the method to the class via CtClass.addMethod() (src/main/javassist/CtClass.java)
  4. Call CtClass.toClass() or writeFile() to materialize the modified class (src/main/javassist/CtClass.java)

Instrument an existing method with logging or interception

  1. Get CtMethod from a CtClass using getDeclaredMethod(name, paramTypes) (src/main/javassist/CtClass.java)
  2. Use CtBehavior.insertBefore(), insertAfter(), or insertCatch() with source code (src/main/javassist/CtBehavior.java)
  3. Javassist automatically compiles the source into bytecode and inserts it (src/main/javassist/bytecode/Bytecode.java)
  4. The modified class is ready for use via CtClass.toClass() or ClassPool persistence (src/main/javassist/CtClass.java)

Create a custom classloader with transparent bytecode modification

  1. Extend or use Loader and implement Translator interface for transformation rules (src/main/javassist/Loader.java)
  2. In Translator.onLoad(), get the CtClass and apply modifications via CtBehavior/CtField APIs (src/main/javassist/Translator.java)
  3. Register Translator with Loader via addTranslator() (src/main/javassist/Loader.java)
  4. Use Loader instead of standard classloader; all classes loaded go through modification pipeline (src/main/javassist/Loader.java)

Manipulate bytecode directly for fine-grained control

  1. Access the bytecode via CtMethod.getMethodInfo().getCodeAttribute() (src/main/javassist/CtMethod.java)
  2. Create a CodeIterator and traverse instructions using next() (src/main/javassist/bytecode/CodeIterator.java)
  3. Insert, replace, or remove bytecode instructions at specific offsets (src/main/javassist/bytecode/CodeIterator.java)
  4. Validate and finalize bytecode; ConstPool auto-updates references (src/main/javassist/bytecode/ConstPool.java)

🔧Why these technologies

  • Pure Java implementation (no native code) — Enables cross-platform bytecode manipulation without JNI dependencies; easier debugging and distribution.
  • Dual-level API (source + bytecode) — Balances ease-of-use for common tasks (source level) with power for advanced use cases (bytecode level).
  • On-the-fly compilation of source snippets — Reduces cognitive load; developers write Java source instead of bytecode mnemonics or intermediate representations.
  • ClassPool as central registry with ClassPath abstraction — Enables flexible class discovery (URLs, file paths, custom loaders) and caching to minimize repeated parsing.
  • Custom Loader with Translator pipeline — Supports transparent, load-time class transformation without modifying application startup code.

⚖️Trade-offs already made

  • Source-level API does not support all bytecode constructs
    • Why: Simplicity and ease of use for the common case (method insertion, field addition).
    • Consequence: Advanced users must drop to bytecode-level API (CodeIterator, Bytecode) for complex transformations.

🪤Traps & gotchas

No external Maven dependencies reduces friction, but be aware: (1) Bytecode format is JVM-version-specific—code generated on Java 11 may not work on Java 8; (2) Javassist modifies classes at load time, so debuggers and stack traces can be confusing; (3) The source-level API compiles Java strings on-the-fly, so syntax errors in those strings are runtime, not compile-time; (4) No specific Java version constraint in pom.xml snippet visible, so check src/main/pom.xml or effective pom for target version. The sample/ projects are standalone demos, not test suites—actual tests live in src/test (not listed).

🏗️Architecture

💡Concepts to learn

  • Java bytecode (JVM instruction set) — Javassist's entire purpose is to manipulate bytecode; understanding opcodes, method descriptors, and constant pools is essential to using the bytecode-level API effectively
  • ClassLoader and class loading mechanism — Javassist intercepts classes during load time; understanding when and how the ClassLoader invokes class definitions is critical for hot-swapping and load-time weaving (see sample/evolve/, sample/hotswap/)
  • Constant pool (JVM constant pool) — Bytecode-level Javassist APIs directly manipulate the constant pool to add method references, string literals, and class constants; essential for understanding low-level modifications
  • Method descriptor and type signatures — Javassist uses JVM type descriptors (e.g., '(II)V' for void method with two ints); correctly forming these is critical when programmatically adding methods via the bytecode API
  • Aspect-oriented programming (AOP) — Javassist's source-level API is designed to support AOP frameworks (intercepting method calls, adding cross-cutting concerns); understanding AOP concepts clarifies the library's design goals
  • Instrumentation and Java agents — Javassist can be used via Java agents (java -javaagent) to modify classes before they load; this is how frameworks like Hibernate and Spring apply dynamic enhancements transparently
  • jboss-javassist/javassist — This is the official repository itself; reference for understanding the canonical implementation and release process
  • cglib/cglib — Code generation library for Java that uses Javassist under the hood; related bytecode manipulation tool in the same ecosystem
  • eclipse/aspectj — Aspect-oriented programming framework that competes with Javassist for compile-time and load-time weaving; a contemporary alternative for similar problems
  • bytebuddy/byte-buddy — Modern bytecode manipulation library with a higher-level API than Javassist, often used as a drop-in replacement in newer projects
  • spring-projects/spring-framework — Javassist is used internally by Spring for proxy generation and AOP; major downstream consumer demonstrating production usage patterns

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for bytecode manipulation edge cases in CtClass and CtMethod

The repo has extensive sample code (sample/duplicate, sample/evolve, sample/hotswap, sample/reflect) demonstrating Javassist functionality, but there's no visible src/test directory with corresponding JUnit tests. The core classes CtClass.java, CtMethod.java, and CtConstructor.java lack automated test coverage for edge cases like circular dependencies, nested class modifications, and concurrent ClassPool access patterns. This would catch regressions early and improve maintainability.

  • [ ] Create src/test/java/javassist directory structure
  • [ ] Add CtClassTest.java with tests for class creation, field/method insertion, and inheritance chains
  • [ ] Add CtMethodTest.java with tests for method body manipulation, parameter types, and code conversion
  • [ ] Add ClassPoolTest.java with tests for concurrent access and cache invalidation scenarios
  • [ ] Port existing sample/ examples (duplicate, reflect, hotswap) into JUnit test cases for regression coverage
  • [ ] Integrate test execution into existing .github/workflows/maven.yml CI pipeline

Add GitHub Actions workflow for testing against multiple Java versions (8, 11, 17, 21)

The current .github/workflows/maven.yml workflow exists but likely targets a single Java version. Javassist is a foundational bytecode library used across many Java projects with different baseline requirements. Testing against Java 8 (legacy), 11 (LTS), 17 (LTS), and 21 (latest LTS) would catch compatibility issues early, especially around bytecode format changes and module system interactions introduced in Java 9+.

  • [ ] Inspect current .github/workflows/maven.yml to identify existing Java version configuration
  • [ ] Create or extend workflow to use matrix strategy with java-version: ['8', '11', '17', '21']
  • [ ] Ensure pom.xml source/target levels support the version matrix (update if needed)
  • [ ] Test that generated bytecode is compatible across versions using javap verification
  • [ ] Add workflow status badge for multi-version matrix to README.md

Add integration tests for code generation examples in sample/ directory

The sample/ directory contains 7 different application scenarios (duplicate, evolve, hotswap, preproc, reflect, rmi, vector) that demonstrate real-world Javassist usage patterns, but they lack automated verification. Creating integration tests that compile, execute, and validate the output of these samples would ensure backward compatibility and serve as living documentation for API usage patterns.

  • [ ] Create src/test/java/javassist/integration directory
  • [ ] Add SampleDuplicateTest.java that compiles sample/duplicate/*.java, runs Main.java, and validates output
  • [ ] Add SampleEvolutionTest.java that tests the hotswap/class evolution scenario from sample/evolve
  • [ ] Add SampleReflectTest.java that executes sample/reflect/Main.java against dynamically modified Person.java
  • [ ] Add SampleVectorTest.java for vector manipulation test cases
  • [ ] Ensure each integration test validates both compilation success and expected runtime behavior (stdout/stderr)
  • [ ] Document the integration test approach in Examples.md with references to test cases

🌿Good first issues

  • Add missing Javadoc comments to src/main/javassist/bytecode/CodeIterator.java or similar bytecode utility classes; these are core but underdocumented—visible from high Java LOC count with minimal HTML docs.
  • Create a new sample in sample/metaprogramming/ demonstrating runtime proxy generation using CtClass, filling the gap between sample/reflect/ (basic reflection) and sample/evolve/ (complex versioning).
  • Write integration tests for sample/hotswap/ scenarios (currently just example code)—test that a modified class definition properly replaces the old one under concurrent access.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 34ce2b1 — updates .github/workflows/maven.yml (chibash)
  • d0dd1bd — fixes pom.xml for deployment. (chibash)
  • 5f3141e — updates for releasing 3.31.0-GA. (chibash)
  • d62a29c — updates BytecodeTest#testDeprecatedAttribute() to work with Java 25. (chibash)
  • 923e815 — Merge pull request #495 from Asbestosstar/master (chibash)
  • 5d820d6 — Merge pull request #506 from Talank/optimize_surefire (chibash)
  • 38d9bd0 — disable xml report (Talank)
  • 463318d — Name Index Getter (rhel)
  • cf99ead — Fix reading of Attributes (rhel)
  • 3198d99 — Update AttributeInfo.java, PermittedSubclassesAttribute.java, and RecordAttribute.java (rhel)

🔒Security observations

Javassist is a well-established bytecode manipulation library with moderate security considerations. The primary security concerns relate to the inherent risks of bytecode engineering and dynamic class loading rather than implementation flaws. The codebase lacks visible critical vulnerabilities, but users must exercise caution when loading classes from untrusted sources. Recommendations focus on input validation, source restrictions, and proper documentation of security implications. The project would benefit from enhanced CI/CD security scanning and clearer security guidelines for developers using this library.

  • Medium · Outdated Maven Build Configuration — pom.xml. The pom.xml shows version 3.31.0-GA which may contain known vulnerabilities. While Javassist itself is a bytecode manipulation library, the build configuration should be regularly updated to ensure dependencies are current. No specific dependency versions are pinned in the provided snippet. Fix: Regularly update all transitive dependencies. Use 'mvn dependency:check' to identify outdated dependencies and apply security patches promptly.
  • Medium · Bytecode Manipulation Security Risk — src/main/javassist/. Javassist is a bytecode engineering toolkit that allows runtime class definition and modification. While this is the intended functionality, it presents inherent security risks if used to load untrusted bytecode or if the library is exposed to untrusted input. Potential for arbitrary code execution if bytecode sources are not properly validated. Fix: Implement strict validation of bytecode sources. Use ClassPath restrictions to limit where classes can be loaded from. Apply the principle of least privilege when granting bytecode modification capabilities. Consider using SecurityManager policies to restrict dangerous operations.
  • Medium · Lack of Input Validation in Class Loading — src/main/javassist/ClassPool.java, src/main/javassist/URLClassPath.java, src/main/javassist/Loader.java. The ClassPool, URLClassPath, and Loader components handle external class loading. Without explicit validation mechanisms visible in the file structure, there's a risk of loading malicious or unexpected classes, particularly from network sources (URLClassPath). Fix: Implement strict class path validation. Use whitelisting for allowed class paths. Validate and sanitize all URLs before loading classes. Consider signing bytecode to ensure integrity.
  • Low · Sample Code Contains Untested Security Patterns — sample/rmi/, sample/hotswap/, sample/evolve/. The sample directory contains example code (RMI, hotswap, evolve) that demonstrates bytecode manipulation. While samples, they could serve as templates for insecure implementations if developers don't understand security implications. Fix: Add security warnings and best practices documentation to sample code. Include comments about potential risks and how to mitigate them when using Javassist in production.
  • Low · Missing Security Headers in CI/CD Configuration — .github/workflows/maven.yml. The GitHub Actions workflow file (.github/workflows/maven.yml) is referenced but not fully visible. Standard security checks like dependency scanning and SAST should be configured. Fix: Configure GitHub Dependabot to scan for vulnerable dependencies. Implement SAST scanning using tools like SonarQube or GitHub's CodeQL. Enable branch protection rules requiring security checks.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · jboss-javassist/javassist — RepoPilot