native-obfuscator: turning a Java jar into C++ that a protector can work on
Java .class to .cpp converter for use with JNI
At a glance
- What is it?
- native-obfuscator transpiles Java bytecode into C++ sources and a jnionly loader jar, so that a commercial protector such as VMProtect or Themida can operate on native code rather than on class files. The README is blunt about the limits: only Java 8 is fully supported, and the tool is a transpiler rather than an obfuscator in its own right.
- Who is it for?
- native-obfuscator suits a developer who ships a Java application and has hit the limit of what class-file obfuscators can do, and who wants to hand native code to VMProtect, Themida or obfuscator-llvm instead.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 37 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A transpiler that hands native code to a protector
The repository is described as a Java .class to .cpp converter for use with JNI, and the README sets the expectation immediately. This tool does not particularly obfuscate your code, it just transpiles it to native, and you should remember to use protectors like VMProtect, Themida, or obfuscator-llvm in case of clang usage. That is the whole pitch in three sentences. Commercial protectors for Java work on class files, and class files are comparatively easy to pick apart. If the protected artefact is native code instead, the protector has a different kind of input to work with, and that is the gap this tool fills. The tool is written in Java, the licence is GPL-3.0, and the README's first line about support is blunt: currently, fully supports only Java 8, with Java 9+ and Android support entirely experimental. The topics list names bytecode, cpp, java and obfuscator, which is an accurate summary of what sits between the two.
What you need installed before anything else
The tool's own requirements are listed in detail, and the list is the first thing to read because it is longer than a modern CLI would ask for. You need JDK 8, and the README recommends Oracle JDK 8 on Windows, noting that you need login credentials on Oracle, or for Linux and macOS that you search for your distro install jdk 8 and install the required packages. You need CMake, from the CMake site on Windows or the distro package elsewhere, with apt/yum/brew install cmake given as the default. And you need a C++ or C compiler toolchain, either the freeware MSVS from Microsoft with the Visual C++ compiler option selected, or mingw if you have experience with it, and on Linux and macOS a search for your distro install g++. The JDK 8 requirement is the one that constrains everything else, because a project that must still build on a modern JDK cannot use this pipeline without a separate legacy build.
The command line and its three platform targets
The usage output is complete in the README, and the interesting part is the platform flag. The tool takes a jar file and an output directory, and -p selects the JVM platform. Three options are available. hotspot will use HotSpot JVM internals and should work with most obfuscators, even with stack trace checking. std_java will use only minor JVM internals that must be available on all JVMs. android is the method to use when building a library for Android, and it uses no JVM internals and no DefineClass for hidden methods, which means obfuscators that rely on the stack for string or name obfuscation will not work, because some methods will not be hidden. The choice is a real trade-off, not a preference: hotspot gives the protector the most material to work with, and android is the only option that runs on a device with no HotSpot internals. The remaining flags cover the library directory, the custom library directory for LoaderUnpack, the plain library name for LoaderPlain, annotation processing, and the debug mode that produces a non-executable jar.
Whitelist and blacklist are the ones you will actually use
The README's warning is the first line of the document and it sets the operating procedure: blacklist or whitelist usage is recommended because this tool slows down code significantly, with the example given being do not obfuscate a full Minecraft jar. A transpiler that rewrites every class into C++ and then recompiles it produces a much slower program, so the practical workflow is to convert the parts that matter and leave the rest as bytecode. The selection is done with -w and -b, each taking a path to a .txt file of classes and methods, and the format uses internal class names and method descriptors:
<class>
<class>#<method name>#<method descriptor>
mypackage/myotherpackage/Class1
mypackage/myotherpackage/Class1#doSomething!()V
mypackage/myotherpackage/Class1$SubClass#doOther!(I)VThe README notes you can read more about it by googling java internal class names or java method descriptors. Wildcards work too, and the two matcher forms are described precisely: a single asterisk matches a single entry, divided by a slash, in the class or package name, and a double asterisk matches all entries. The examples cover the plain package case, a package with nested classes, a class inside a package, and a class name prefix. Writing these lists is the work of adopting the tool, and it is the part most likely to be underestimated.
Annotations as an alternative to file lists
There is a second way to decide what gets transpiled, and it is the one that scales better in a real codebase. The -a flag enables annotation processing, and to use annotations for black or whitelisting methods and classes as native you add the com.github.radioegor146.native-obfuscator:annotations:master-SNAPSHOT library to your project, which also requires adding JitPack to your repositories. Once that is in place you can add a @Native annotation to include classes or methods in the native obfuscation process and a @NotNative annotation to ignore methods in classes marked as @Native. The precedence rule is the part to remember: whitelist and blacklist has higher priority than annotations. That ordering is the sensible one, because the file lists are the deliberate, reviewed decision for a release, while annotations are embedded in the source and travel with it. The dependency is a master-SNAPSHOT artifact built through JitPack, which is worth knowing before you put it into a build, since a snapshot dependency is not pinned to a fixed version.
The build pipeline after transpiling
The basic usage is a six-step sequence, and it is worth reading as a whole because it explains what the tool does and does not do. You transpile your code with java -jar native-obfuscator.jar with the input jar and the output directory. You run cmake . in the result cpp directory. You add changes to the .cpp code if necessary, which is a real step and not a formality, since the transpiled output is meant to be edited. You run cmake --build . --config Release in the same directory to build the .so or .dll file. You copy the result from build/libs/ to the path specified in the previous paragraph. And you run the created jar with java -jar. The native libraries are named by target and the README lists the exact file names to add to the output directory, which is by default native0/ or custom if --custom-lib-dir is present:
x64-windows.dll
x64-linux.so
x86-windows.dll
x64-macos.dylib
arm64-linux.so
arm64-windows.dllSo the tool produces a jar and a directory of native libraries, and the jar loads those libraries at runtime. If you ship your jar separately from the native libraries, or you use it for Android, --plain-lib-name lets you specify the name of the native library the jar will search for.
Building the tool and running its tests
The tool itself is a Gradle project, and the README's build instructions are one line: run gradlew assemble to force Gradle not to run tests after the build. The repository layout matches, with a build.gradle at the root, a settings.gradle, a gradle directory and wrapper scripts, and the source split into an obfuscator directory and a separate annotations directory, which is the annotation library from the previous section packaged as its own module. The test section has a prerequisite that is easy to miss. You need Krakatau installed to your PATH, because the test suite uses krak2 for some tests, and then you run gradlew build to assemble and run the full test suite. The tests themselves come from the huzpsb/JavaObfuscatorTest project, which is a reasonable way to test a transpiler: rather than inventing cases, the suite reuses a third party's corpus of obfuscation scenarios. The releases are 3.5.5r on 2026-09-16, 3.5.4r on 2024-07-09 and 3.5.3r on 2024-02-05, and the last push to the repository was on 2026-09-16, so the version line has been stable across two years with a recent update. The GPL-3.0 licence is the other fact to weigh, since a tool that sits inside your build pipeline has licensing consequences for a closed-source product.
Editorial conclusion
native-obfuscator suits a developer who ships a Java application and has hit the limit of what class-file obfuscators can do, and who wants to hand native code to VMProtect, Themida or obfuscator-llvm instead. It is the wrong tool if you need obfuscation on its own, since the README states plainly that the tool does not particularly obfuscate your code and just transpiles it to native, and it is the wrong tool if you are on Java 9 or later, where support is described as entirely experimental. Verify first that your code is Java 8 compatible, that the JDK 8, CMake and C++ toolchain are the ones named in the README, and that you have a whitelist or blacklist ready, because the tool slows down code significantly and the README recommends restricting it rather than transpiling everything.
Frequently asked questions
Which Java versions does native-obfuscator support?
The README states it currently fully supports only Java 8, and that Java 9+ and Android support is entirely experimental. The tool also requires JDK 8 to run.
Does native-obfuscator obfuscate my code on its own?
No. The README says the tool does not particularly obfuscate your code and just transpiles it to native, and you should use protectors like VMProtect, Themida or obfuscator-llvm in case of clang usage.
How do I choose which classes and methods get transpiled?
With -w and -b, each taking a .txt file of classes and methods in internal name and method descriptor form, or with the -a flag and the @Native and @NotNative annotations from the annotations module. Whitelist and blacklist entries have higher priority than annotations.
What is the difference between the hotspot, std_java and android platform options?
hotspot uses HotSpot JVM internals and should work with most obfuscators, std_java uses only minor JVM internals available on all JVMs, and android uses no JVM internals and no DefineClass for hidden methods, which means stack-based string or name obfuscators will not work there.
What do I need installed to run native-obfuscator?
JDK 8, CMake and a C++ or C compiler toolchain. The README gives Windows and Linux or macOS instructions for each, and warns that the tool slows code down significantly, so whitelist or blacklist usage is recommended.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/radioegor146-native-obfuscator)Was this useful?