Skip to content

Usage Guide

This guide walks through protecting a JAR with Nativify. For the exhaustive flag and feature lists, see the CLI reference and Configuration & features.

Quick start

# Build the tool (outputs to dist/) — see Building from Source
./build.sh                       # Windows: build.bat

# Protect @Nativify-annotated methods for one platform
dist/bin/nativify \
  -i input.jar \
  -o output.jar \
  -compileFor windows-x86_64

This will:

  1. Scan input.jar for methods marked with @Nativify.
  2. Compile those methods to native code (applying any obfuscation you enabled).
  3. Build native libraries for Windows x64.
  4. Write a protected output.jar with the libraries embedded and the loader wired in.

Run the result like any other JAR — see Running the protected JAR.

Marking methods to protect

With the @Nativify annotation

Add the nativify-annotations dependency and annotate the methods you want compiled:

import dev.haedus.nativify.annotation.Nativify;

public class Example {

    @Nativify
    public static int fibonacci(int n) {
        if (n <= 1) return n;
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

Methods may be static or instance methods with any visibility. They cannot be abstract, constructors (<init>), or static initializers (<clinit>). The annotation is stripped from the final JAR. See Configuration → the @Nativify annotation.

Without annotations

To protect every eligible method without annotating anything, enable disable-annotation-check:

dist/bin/nativify -i input.jar -o output.jar \
  -compileFor windows-x86_64 \
  -enable disable-annotation-check

Choosing platforms

-compileFor takes one or more os-arch targets, or a bare os that expands to all common architectures. To ship one JAR to several platforms, list them together:

-compileFor linux-x86_64,linux-aarch64,windows-x86_64

See CLI reference → Target platforms.

Enabling obfuscation

A plain run compiles your methods to native code without extra hardening. Turn on obfuscation passes explicitly with -enable:

dist/bin/nativify -i input.jar -o output.jar \
  -compileFor linux-x86_64 \
  -enable native-llvm-passes-bogus-control-flow,native-llvm-passes-substitution,native-llvm-passes-string-encryption

The full catalog of passes and features is in Configuration & features.

GUI headless mode

The GUI can run headless for automation and CI/CD, exposing all of its processors from the command line.

dist/bin/nativify-gui --headless --input input.jar --output output.jar --processor "Remove Attributes"

Options

Option Description Required
--headless Run without the GUI Yes
--input <jar> Input JAR Yes
--output <jar> Output JAR No
--processor <name> Add a processor by name (repeatable) Yes
--verbose Verbose logging No
--json Machine-readable JSON output No
--list-processors List available processors and exit No
--help Show help No

List the available processors

dist/bin/nativify-gui --headless --list-processors

See the Processor reference for what each one does.

Chain multiple processors

Specify --processor more than once; they run in the order given:

dist/bin/nativify-gui --headless \
  --input input.jar --output output.jar \
  --processor "Remove Attributes" \
  --processor "Remove Unnecessary"

JSON output

dist/bin/nativify-gui --headless \
  --input app.jar --output app-processed.jar \
  --processor "Native Code Obfuscation" \
  --json
{
  "success": true,
  "message": "Completed 1/1 processors successfully",
  "logEntries": 15
}

Notes on the Native Code Obfuscation processor

In headless mode:

  • Annotation processing is disabled by default@Nativify-marked methods aren't auto-selected unless you enable annotation processing in the processor config.
  • Complexity analysis is disabled by default — methods aren't auto-selected by complexity.

For annotation-based selection, use the CLI tool instead:

dist/bin/nativify -i input.jar -o output.jar -compileFor windows-x86_64

Finding method descriptors

To identify a method's JVM descriptor, use javap:

javap -s -p com.example.MyClass
public static int add(int, int);
  descriptor: (II)I

Next steps