Java code protection

Ship Java.
Hide how it works.

Javelin flattens control flow, encrypts strings, remaps members at runtime, and injects decompiler crashers. The JAR still runs the same after you ship it. What a decompiler gives back barely looks like Java.

6Transform categories
35+Protection options
5Naming schemes
1:1ProGuard-style mapping file

The obfuscation pipeline

Six categories of transforms make your Java hard to reverse-engineer. Turn on only what you need.

Renaming

Rename classes, methods, and fields. Flatten packages into one. Pick a naming scheme: Il1, alphabet, hex, Unicode, or your own dictionary. Add mixed case, reserved words, and keep rules.

Strings

Encrypt string constants with an XOR, Base64, AES-like, or Unicode-escape scheme. Inject a decoder call at each use site, and garble resource names.

Control flow

Flatten control flow into a dispatcher, add opaque predicates, split arithmetic, and inject junk blocks. Dial the intensity from light to heavy.

Metadata

Strip line numbers and local-variable tables. Remove or fake the source-file attribute. Drop annotations a decompiler would read.

Protection

Watermark your build, add tamper detection, anti-debug, decompiler crashers, and integrity checks, and set an expiry.

Output

Generate a mapping file, target a Java version, and control directory entries, the manifest, and verbose logging.

Before and after

The same method before and after Javelin: control-flow flattening, string encryption, opaque predicates, dynamic remapping, and crasher injection.

com/acme/demo/Account.java
package com.acme.demo;

import com.acme.demo.util.Formatter;

public class Account {
    private final String owner;
    private double balance;
    private final String id;

    public Account(String owner, double balance) {
        this.owner = owner;
        this.balance = balance;
        this.id = "ACC-" + Integer.toHexString(owner.hashCode());
    }

    public String getOwner()   { return this.owner; }
    public double getBalance() { return this.balance; }

    public void deposit(double amount) {
        if (amount <= 0.0)
            throw new IllegalArgumentException("Deposit must be positive");
        this.balance += amount;
    }

    public void withdraw(double amount) {
        if (amount > this.balance)
            throw new IllegalStateException("Insufficient funds for " + this.owner);
        this.balance -= amount;
    }

    public String toString() {
        return this.owner + " [" + this.id + "]: " + Formatter.money(this.balance);
    }
}
o/I.java  ·  decompiler output
package o;

public final class I {
    private final String Il;
    private double I1;
    private final Object[] lll;
    static final String ox;

    public final void l1(double var1) {
        int var3 = 84117;
        while (true) {
            switch (var3) {
                case 11920: {
                    ll.cr();
                    break;
                }
                case 23904: {
                    throw (IllegalArgumentException)ll.ɪ(63, ox);
                }
                case 48061: {
                    ll.ʀ(this.lll, 17, var1);
                    return;
                }
                case 60733: {
                    this.I1 += var1;
                    var3 = 48061;
                    continue;
                }
                case 84117: {
                    var3 = ll.ø(this) ? 11920 : (var1 > 0.0 ? 60733 : 23904);
                    continue;
                }
            }
            break;
        }
    }

    static {
        ox = ll.ɪ(26, "แఢ੿ᴄଙ༺ᱭ");
    }
}

Pricing

Pay once. Both plans include the Javelin pipeline and free updates.

Standard

$100one-time

For a single developer. Free updates included.

  • Class, method & field renaming
  • String encryption
  • Control-flow obfuscation
  • Metadata stripping
  • Watermark & mapping file