The package line names the employer
Java is the language where anonymizing pays off fastest, because the very first line is the giveaway. package com.acme.billing.service; follows a convention that exists precisely to identify the organization. Everything after it compounds: entity classes named after the data model, repository methods that read like the reporting requirements, a constant with the SLA threshold, string literals carrying Slack channels and customer names, comments carrying ticket ids.
The tool rewrites the package chain to com.pkg1.pkg2.pkg3, and every import from your own packages goes with it. Generic roots like com, org and country TLD segments stay as words, they say nothing on their own.
The round trip in practice
Paste a class, get the same class with your names replaced, share it, and feed the answer back through restore names to read it in your own vocabulary. The mapping sits in a key in your browser and grows with every paste, so a service pasted on Monday and its test pasted on Thursday share placeholders, and one answer covering both restores cleanly. Nothing is uploaded at any step, the whole engine is JavaScript running in the tab.
That covers the ChatGPT review, the Stack Overflow question, the bug report to a library maintainer, and the consultant who has not signed anything yet.
Spring and the JDK stay readable
Whether a name survives is decided by its origin. java.*, jakarta.*, Spring, JPA, Lombok, JUnit, SLF4J, Jackson and a long list of common libraries are recognized on their import lines, so LocalDate.now().minusDays(...), @Service and findById all remain what they are. Method names the language or a framework dictates, toString, equals, onCreate, doFilter, stay as well even when your class declares them, since declaring an override does not make the name yours.
Everything else is treated as yours: classes, interfaces, records, enums, methods, fields, parameters, generics you defined, and the annotation types your project declares. The result still reads unmistakably as a Spring service with constructor injection and a repository call, which is exactly the level of context a useful answer needs.
Placeholders follow Java conventions
Renamed code should still look like Java, so the placeholders keep the casing grammar reviewers parse without thinking. Types become Class1, methods method2, fields field3, locals var4, parameters param5, and a screaming-case constant becomes CONST_6, so GRACE_DAYS is still recognizably a constant after the fact. Text blocks keep their line breaks with the content masked, char literals stay, and string literals that work as syntax, date patterns like yyyy-MM-dd, charsets, HTTP methods, String.format directives, are kept and reported as kept.
Numbers are never rewritten, a placeholder would either break compilation or lie about the value. Long ones get flagged under the output instead, because ids and account numbers look exactly like that.
The key file for a colleague
The key panel lists every mapping with its role and usage count, and exports as plain JSON. Send the anonymized class through an unencrypted channel and the key file through a trusted one, and the receiver can restore your naming on this same page. Import merges entries you are missing. A key from a different browser that assigned your placeholder numbers to other names cannot be merged honestly, so it replaces the current key and the panel says so.
Reset takes two clicks, because a forgotten key means every anonymized snippet still out there stays anonymous forever, for you too.
What stays visible
The heuristics read token roles, not a full parse, so an exotic construct can occasionally file a name under the wrong role. The round trip is unaffected, mappings are exact regardless of role labels.
Structure remains. A dunning service is recognizable as a scheduled loop over overdue things whatever the names say, and an architecture that is itself confidential should stay home. One more Java-specific habit worth keeping: check exception messages before sharing logs, they concatenate live data into prose that no identifier pass can classify for you.
Enterprise Java and outside help
Can I share my employer's code with ChatGPT?
That is a policy question before it is a technical one, and at most companies the written answer is no, source code is confidential information under your employment contract. What policy usually aims at is the disclosure, the names, the domain terms, the comments. A snippet reduced to neutral placeholders discloses dramatically less, which puts many review and debugging questions back inside what a careful reading of the rules allows. When in doubt, ask, and ask with the anonymized snippet in hand.
Is it safe to paste a Java stack trace into ChatGPT?
A stack trace is a list of your package names, class names and method names in call order, plus file names and often the exception message with live data in it. It maps your internals as effectively as source code. Anonymize it like source, the frames keep their shape and the frameworks stay recognizable.
What does a Java package name reveal?
The convention is the company domain reversed, so com.acme.billing.service literally spells out who and which system. It is the single loudest name in the file.
Does anonymizing break annotations like @Service or @Autowired?
Framework annotations are library vocabulary and survive, which matters because @Transactional or @Entity often is the bug. Only annotations your project defines are replaced.
Is ProGuard the same as anonymizing source code?
No, different layer and different goal. ProGuard and R8 shrink and obfuscate compiled bytecode so shipped apps are hard to decompile, and the renaming is not meant to be read by anyone. Source anonymizing keeps readable Java for a human or a model to review, and it is reversible through the key. Also worth knowing, a ProGuard mapping.txt is itself sensitive for the same reason our key is.
How do I build a minimal reproducible example from proprietary code?
Cut the code down until removing anything more makes the bug disappear, replace your entities with two or three fields that preserve the failing relationship, and strip identifiers last so you can still navigate while cutting. The anonymizer handles that final pass and keeps a way back, which turns out to matter, half the time the answer to a good repro has to be mapped onto the full codebase again.
Do getters and setters need anonymizing too?
Yes. getCompanyName carries the field name it wraps. They are replaced like any other method of your classes.
Will anonymized Java still compile?
The placeholders are valid identifiers applied consistently, imports of the JDK and known libraries are untouched, so a self-contained snippet compiles. Masked string literals change runtime values, so behavior tests belong on the restored version.