A Railway-hostable web app that accepts Java JAR files, performs best-effort detection of common framework metadata, runs ProGuard, rewrites supported launch metadata after class renaming, validates the output, and returns both the obfuscated JAR and a complete build bundle.
- Bukkit / Spigot
plugin.yml - Paper
paper-plugin.yml - BungeeCord
bungee.yml - Velocity
velocity-plugin.json - Fabric
fabric.mod.json - Forge
META-INF/mods.toml - NeoForge
META-INF/neoforge.mods.toml - Executable JAR
Main-Class - Spring Boot
Start-Classmetadata (best-effort for non-nested application classes) - Java
ServiceLoaderresources - Generic Java JARs
The app never enables shrinking or optimization. This makes it substantially safer for arbitrary plugins and mods that use reflection. Strong mode still repackages and renames classes and members.
- Create a new GitHub repository and upload every file in this folder.
- In Railway, choose New Project → Deploy from GitHub repo.
- Select the repository. Railway detects the included
Dockerfile. - Wait for the deployment to finish, then generate a public domain in Railway's networking settings.
Railway injects PORT automatically. No database or volume is required.
| Variable | Suggested value | Purpose |
|---|---|---|
APP_PASSWORD |
A long random password | Protects the site from public use. Leave empty for an open instance. |
MAX_UPLOAD_MB |
100 |
Maximum entire HTTP request size. |
JOB_TTL_MINUTES |
60 |
Deletes completed jobs from temporary storage. |
OBFUSCATION_TIMEOUT_SECONDS |
240 |
Maximum ProGuard runtime per job. |
MAX_PARALLEL_JOBS |
1 |
Simultaneous ProGuard jobs. Keep low on small Railway plans. |
MAX_QUEUED_JOBS |
20 |
Rejects new uploads when too many builds are waiting or running. |
JAVA_MAX_HEAP_MB |
512 |
Maximum Java heap used by ProGuard. |
For a low-memory Railway service, keep MAX_PARALLEL_JOBS=1 and lower JAVA_MAX_HEAP_MB if the container is being terminated for memory use.
A successful job provides:
OriginalName-Obfuscated.jarmapping.txtseeds.txtusage.txtdump.txtgenerated-config.proproguard.logreport.json- A ZIP bundle containing all files above
- Obfuscates classes, methods, and fields.
- Repackages renamed classes into
o. - Renames supported metadata entry classes and rewrites their metadata afterward.
- Repackages renamed classes into a short package while retaining safer JVM-compatible member naming.
- Obfuscates internal code.
- Keeps detected launch/entry classes and all their members unchanged.
- Best for unusual reflection-heavy projects or when no dependency libraries are available.
The form accepts multiple dependency .jar files or .zip files containing JARs. These libraries are passed to ProGuard with -libraryjars; they are not copied into the output.
For a Paper plugin, uploading the matching Paper API JAR generally improves hierarchy analysis. The same applies to Fabric Loader, Forge, NeoForge, Velocity, or custom APIs.
- Set
APP_PASSWORDbefore exposing the service publicly. - Upload processing never uses a shell command containing a user-controlled filename.
- JARs are isolated in random per-job directories.
- Downloads require a random job token.
- Signature files invalidated by obfuscation are removed.
- Temporary files are deleted after the configured TTL.
- Railway's filesystem is ephemeral; restarting the service deletes outstanding jobs.
This is still a resource-intensive file-processing service. Do not operate a public unprotected instance on a paid Railway account.
docker build -t universal-proguard .
docker run --rm -p 8080:8080 -e APP_PASSWORD=test universal-proguardOpen http://localhost:8080.
Install Java 21, Python 3.11+, and ProGuard 7.9.1. Set PROGUARD_CMD to ProGuard's launcher:
Windows:
set PROGUARD_CMD=C:\Tools\proguard-7.9.1\bin\proguard.bat
start-local.batLinux:
export PROGUARD_CMD=/opt/proguard/bin/proguard.sh
./start-local.shpython -m unittest discover -s tests -vJava bytecode can still be decompiled after obfuscation. ProGuard changes names and layout to make the output harder to understand; it does not provide perfect source-code secrecy. Some applications need custom keep rules because reflection can reference classes or members in ways that cannot be detected automatically. The generated configuration and mapping are included so failed projects can be diagnosed and tuned.