Case study 01 / 03
Smart Duplicate Detector
- Java
- Maven
- Node.js
- npm
A static-analysis tool that finds duplicated logic in Java code. It compares the shape of each method, not its text, so renamed variables and reformatting don't hide a copy.
- Role
- Lead developer (35 of the project's 40 commits)
- Year
- 2026
- Team
- 3 engineers, course project
- Stack
- Java 17, JavaParser, Weighted Levenshtein, Swing + FlatLaf, Javalin, Maven, Node.js CLI wrapper


Problem
Duplicated business logic creeps into Java projects through copy-paste, AI-generated code and parallel implementations. The copies drift apart, so a bug fixed in one stays live in the other. Text-based duplicate finders either miss these copies, because names and formatting changed, or flood you with false positives from getters, setters and imports.
Constraints
- Java 17 and an object-oriented design were course requirements.
- It had to work both for a developer at a terminal and for someone who prefers a window and buttons.
- Every method is compared with every other method, so cost grows with the square of the method count.
Architecture
Project scanner
finds every .java file
AST parser
JavaParser → node-type tokens
Similarity engine
weighted Levenshtein
Reports
desktop app · CLI · Javalin API
Each method becomes a list of AST node types (IfStmt, ForStmt, MethodCallExpr…). Names never enter the comparison, which is why renaming a variable doesn't hide a duplicate.
Key decisions
Trade-off 1
I chose comparing AST node types over comparing source text or tokens, because names and formatting change between copies, but the structure of the logic doesn't.
Trade-off 2
I chose a weighted edit distance (control flow ×10, method calls ×2) over plain Levenshtein, because a different if or loop changes what a method does far more than an extra variable declaration.
Trade-off 3
I chose shipping the JAR inside an npm package with a small Node.js launcher over a Maven-only release, because `npm i -g` is one command most developers already have, and the launcher checks for Java 17 first with a clear error.
What I built
- The scanning and detection pipeline: file discovery, AST extraction with JavaParser, and the weighted similarity algorithm.
- A filter that skips methods with fewer than three statements, which removes getters and setters from the results.
- A Swing desktop app with a FlatLaf dark theme, an adjustable similarity threshold and background scanning via SwingWorker.
- A CLI (`sdd --path . --threshold 0.75`), published to npm as `smart-duplicate-detector`, plus a small Javalin API.
- Unit tests for the scoring and an end-to-end integration test that scans real files in a temporary directory.
Result
- Published on npm in July 2026; 207 downloads from July to October 2026, according to npm's public download stats.
What I'd do next
- Group methods by size and structure hash before comparing, so large projects avoid the all-pairs cost.
- Output SARIF so results show up inline in GitHub code scanning and IDEs.
- Add a refactoring hint for each pair: the shared logic that could be extracted.