The first AI-slop linter for the JVM. Every existing "AI-slop detector" is Python or JavaScript. sloplint is built for the Java world - where AI-assisted coding is now colliding with enterprise quality gates.
When an LLM writes your Java code, it leaves a specific set of fingerprints that human review often misses because they don't look wrong at a glance:
YOUR_API_KEY_HEREas a string literal - never replaced.throw new UnsupportedOperationException("TODO")in a class that ships.catch (Exception e) { e.printStackTrace(); }- the error is now invisible.@Test void x() { assertTrue(true); }- a test that will pass forever, asserting nothing.- A real GitHub personal access token pasted into a
Stringliteral. System.out.println("debug")left in aServiceclass.https://example.com/fooas an API base URL.
Traditional Java linters (SpotBugs, Checkstyle, Error Prone) don't check for any of these. sloplint does.
| Code | Rule | Default | What it catches |
|---|---|---|---|
| SL001 | hardcoded-api-secret |
ERROR | AWS, OpenAI, Anthropic, GitHub, Stripe, Google API keys and PEM private keys committed to source |
| SL002 | placeholder-marker |
ERROR | YOUR_..._HERE, <REPLACE_ME>, CHANGE_ME, password123, xxxxxxxx scaffolds |
| SL003 | placeholder-url |
WARNING | example.com, your-domain.com, mysite.com, foo.bar — reserved or invented domains |
| SL004 | todo-throw |
WARNING | UnsupportedOperationException("TODO") and its cousins — stub methods that pretend to work |
| SL005 | silent-catch |
WARNING | Empty catches and catches that only call e.printStackTrace() |
| SL006 | stray-println |
WARNING | System.out.println / System.err.println outside a main method |
| SL007 | trivial-test |
WARNING | @Test methods with empty bodies, assertTrue(true), assertEquals(1, 1) |
Every rule is either false-positive-safe or has a documented way to suppress.
sloplint ships as a standalone jar. No project changes required.
Download from the latest release:
curl -L -o sloplint.jar \
https://github.com/bibekmhj/sloplint/releases/latest/download/sloplint-cli.jarOr from Maven Central once 0.1.0 is published:
<dependency>
<groupId>io.github.bibekmhj</groupId>
<artifactId>sloplint</artifactId>
<version>0.1.0</version>
</dependency>java -jar sloplint.jar src/main/javaSample output on a sloppy file:
src/main/java/example/PaymentService.java:12:22: ERROR [SL001 hardcoded-api-secret] hardcoded secret matching a known provider format: sk_liv…KLmn
| private String stripeKey = "sk_live_51KabcXYZabcdefghijKLmn";
src/main/java/example/PaymentService.java:14:22: ERROR [SL002 placeholder-marker] placeholder marker not replaced: YOUR_WEBHOOK_SECRET_HERE
| private String webhook = "YOUR_WEBHOOK_SECRET_HERE";
src/main/java/example/PaymentService.java:25:9: WARNING [SL005 silent-catch] catch calls only e.printStackTrace()
| catch (Exception e) { e.printStackTrace(); }
src/main/java/example/PaymentServiceTest.java:8:5: WARNING [SL007 trivial-test] test testCharge() asserts only assertTrue(true)
| @Test void testCharge()
scanned 12 files in 340ms - 2 errors, 2 warnings
- name: Run sloplint
run: |
java -jar sloplint.jar --format sarif --output sloplint.sarif src/
- name: Upload SARIF to Code Scanning
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: sloplint.sarif# .pre-commit-config.yaml
- repo: local
hooks:
- id: sloplint
name: sloplint
language: system
entry: java -jar tools/sloplint.jar --fail-on error
files: '\.java$'
pass_filenames: falseusage:
sloplint [options] <path>...
options:
--format text|json|sarif output format (default: text)
--enable SL001,SL002,... run only these rules
--disable SL001,SL002,... never run these rules
--exclude 'glob,glob,...' skip files matching (globs relative to root)
--fail-on error|warning exit non-zero on findings at this level (default: error)
--output PATH write report to file instead of stdout
--no-color disable ANSI colors in text output
--list-rules print the rule catalog and exit
-h, --help this help
You should - and we may ship those integrations later. sloplint exists as a standalone tool because:
- Zero-config. No project changes, no plugin registration, no dependency graph.
- Runs on any source tree, even without a build. Great for reviewing an AI-generated PR from someone whose local build you don't have.
- SARIF-first output. Drops directly into GitHub Code Scanning without wrappers.
- The rules are opinionated for the AI-generated-code case. They'd be a poor fit for a general-purpose linter's rule set.
Coexists with SpotBugs, PMD, Checkstyle, and Error Prone. Nothing overlaps.
| Component | Supported |
|---|---|
| Java (runtime) | 17, 21, 22, 23 |
| Java (analyzed) | 8 through 23 |
| Build tool | Any — sloplint scans source files |
Kotlin scanning is a v0.2 goal. See issues.
- v0.2 - Maven plugin, Gradle plugin, Kotlin source support,
// sloplint:disableinline suppression,.sloplint.tomlconfig file. - v0.3 - Rules for hallucinated imports (needs classpath resolution), suspiciously generic Javadoc, duplicated boilerplate methods.
- v1.0 - Stable rule IDs, semver on the CLI flags, published Maven Central release with GPG signatures.
Rules are the fun part. If you have a specific AI-generated Java pattern that keeps slipping past code review, file an issue with the offending snippet and a proposed fix. Rule PRs need:
- A test file demonstrating a true positive and a true negative.
- A one-sentence rule description.
- A default severity with rationale.
See CONTRIBUTING.md for the full flow.
Apache 2.0. See LICENSE.