Asking further:
but it is packaged by jlink into modules file
Excellent point! You're absolutely right to bring this up. My previous answer was too general. When you use B4J's
Standalone Package (jlink) option, the situation becomes more complex and offers significantly better protection against
casual decompilation.
Let's dive into the specifics of what happens with jlink and how it changes the decompilation landscape.
What jlink Does Differently
Instead of creating a simple JAR file, the jlink option:
- Creates a Custom JRE: It uses the jlink tool from the JDK to create a minimal, customized Java Runtime Environment (JRE) that contains only the Java modules your application actually needs.
- Packages into a Runtime Image: Your application's code and all its dependencies (libraries, B4J runtime, etc.) are packaged into this custom runtime image.
- Uses JIMAGE Format: The core of this custom JRE is stored in the lib/modules file. This file is not a simple archive like a JAR; it's a special, highly efficient container format (JIMAGE) used by the Java runtime to store modules.
So, Can It Still Be Decompiled?
Yes, but it's much harder and requires extra steps compared to a standard JAR file.
The primary obstacle is no longer just the decompiler itself, but
first extracting your code from the custom runtime image.
Here’s what an attacker would need to do:
Step 1: Locate and Extract the Application Code from the Runtime Image
The attacker cannot simply point a decompiler at the modules file. They need specialized tools to unpack the JIMAGE format.
- Tool Needed: The standard JDK includes a tool called jimage for this purpose.
- Process: They would run a command like:
bash
jimage extract <path-to-standalone-package>/lib/modules --output ./extracted_modules
This command extracts the contents of the modules file into a directory.
Step 2: Find the Relevant JAR/Class Files
After extraction, the attacker will find a folder structure containing the modules of the custom JRE (like java.base) and, crucially, your application code.
- Your application is typically contained in a module or JAR file, often named something identifiable (e.g., b4j/your-app-name.jar or within a module path).
- They need to browse the extracted folders to find the JAR file or the directory containing the .class files for your application, not the standard Java modules.
Step 3: Decompile the Class Files
Once they have isolated your application's JAR or class files, they can use a standard Java decompiler (like JD-GUI) as described in the previous answer.
Level of Difficulty and Protection
Aspect | Standard Package (JAR) | Standalone Package (jlink) |
---|
Accessing Code | Trivial. Double-click the JAR in a decompiler. | Moderate. Requires knowledge of command-line tools (jimage) and navigating an extracted file structure. |
Barrier to Entry | Very low. Any novice can do it. | Higher. Requires someone with Java platform knowledge. |
Protection Level | Very Low. Effectively no protection. | Moderate. Protects against casual users and adds significant steps for attackers. It's security through obscurity. |
The Role of Obfuscation is Still Critical
Even with jlink, obfuscation remains your most important defense.
- jlink provides obscurity: It hides your code inside a binary container, deterring casual inspection.
- Obfuscation provides resilience: It makes the code meaningless even after it is extracted and decompiled.
The most secure approach is to combine both:
- Use the Standalone Package (jlink) to make initial access harder.
- Enable obfuscation in your B4J build configuration to ensure that if someone does extract your code, the decompiled output is gibberish.
Practical Example for You to Try
To see the difference yourself:
- Create a simple B4J app.
- Compile it twice:
- Once as a Release Package (creates a JAR).
- Once as a Standalone Package (jlink).
- Try to decompile both:
- The JAR from the Release Package will open directly in JD-GUI.
- For the Standalone Package, you'll need to first find your app's JAR within the package (often in the app folder or similar—B4J might package it accessibly) or use jimage extract on the lib/modules file to get the core modules.
Conclusion
You are correct. Using the
Standalone Package (jlink) significantly raises the bar compared to a simple JAR file. It moves your application from "trivially decompilable" to "requires specific technical knowledge to extract the code first."
However, it is
not a substitute for obfuscation. A determined reverse-engineer with Java platform knowledge can still extract and decompile your code. Therefore, for any project where protecting your intellectual property is important, you should
always use obfuscation, regardless of whether you deploy as a JAR or a jlink package.