Back to catalogue
ValidationPostToolUse· Write|Edit
Google Java Format after write
Java lands Google-style formatted on every save
Runs google-java-format -i on the modified .java file so style is applied silently; remaining formatting errors are reported to the agent immediately.
What does the Google Java Format after write hook do?
Google Java Format after write is a Claude Code PostToolUse hook matching Write|Edit. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Java lands Google-style formatted on every save.
As a PostToolUse hook it runs after the action, reacting to what just happened rather than blocking it. Because it is a deterministic Node.js script, it executes on every matching event without relying on the model to remember — the guarantee that makes agentic workflows safe to automate.
Use cases
- Enforce Google Java Style without a CI round-trip
- Auto-format the moment a file is written
- Keep diffs minimal and reviewable
Tags
#java#format#google-java-format#style#quality#validation
settings.json fragment
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/java-format.mjs",
"type": "command"
}
],
"matcher": "Write|Edit"
}
]
}
}Script · .claude/hooks/java-format.mjs
#!/usr/bin/env node
// @hookstack post-write-java-format
// Formate le fichier .java avec google-java-format après écriture (PostToolUse Write|Edit)
import { execSync } from "node:child_process";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
function defaultExec(cmd) {
return execSync(cmd, { encoding: "utf8", stdio: "pipe", timeout: 20_000 });
}
export function run(input, { exec = defaultExec } = {}) {
const filePath = input.tool_input?.file_path ?? input.tool_input?.path ?? "";
if (!filePath.endsWith(".java")) return null;
try {
exec(`google-java-format -i "${filePath}"`);
return null;
} catch (err) {
// google-java-format absent — non bloquant ; une erreur de parse (stdout/stderr)
// est remontée à l'agent pour être corrigée dans la même boucle.
const output =
(err.stdout ?? err.stderr)?.toString()?.trim() ?? "";
return output ? { message: `[java-format] ${output}\n` } : null;
}
}
/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, "utf8"));
const result = run(input);
if (result?.message) process.stderr.write(result.message);
}