How to extract the source code of a Java application ☕

If you write Java applications, you may already know that, in order to be able to easily use your application on another computer, you need to compile its source code. With Gradle, one of the commands that do this is gradle assemble. Once compiled, an executable Jar file is created (like APPLICATION.jar).

If you open this file, you will see that the file is incomprehensible to you, unless you are a robot. 🤖

Unfortunately, if you think your source code is completely opaque, you are mistaken. 😟 Effectively, the Jar file is in reality a simple Zip file with another extension. 🤡

If you rename the file as APPLICATION.zip and extract the archive, you should see a few folders there, which contain a lot of interesting files.

Quickly, you may find:

  • the framework and its version: Spring-Boot-Version: 2.4.4
  • the list of dependencies along with their respective version
  • and the structure of your application with its files as *.class format

Ouch!, you weren't expecting to see these files, right? At least, they're still unusable, for now...

If you look at the same file with your IDE , some of them, like Intellij IDEA, can even decompile this type of file for you! 😮

If you look at the following images, you will see that there is not much difference between the original source code and its decompiled version. All comments have been removed along with some final keywords. Do you see any other differences? 🤨

The decompiled version

Comparaison of the original source code with its decompiled version in Intellij IDEA.

Even if you don't have an IDE that can decompile a class file for you, there are other solutions that allow you to achieve this goal. I tried one of them in the second part of this post, but the results seems to vary from project to project...

So, if you really want to protect your intellectual property, I suggest you to choose another language and above all, to host your application yourself. 🙃

Procedure

Warning : decompiling, or reverse engineering, a part of an application seems to fall into gray areas , depending of the jurisdiction.

I suggest you to do this only it if it is your application or if you have the author's permission. Otherwise, you should only do this if it is necessary to ensure software interoperability.

You can check out the additional links at the end of the post for more information on the topic.

Install jd-core-java

# Clone the repository
git clone https://github.com/orangecms/jd-core-java.git

# Build the application
cd jd-core-java && ./gradlew assemble && cd ..

# Move the JAR file to the current directory
mv jd-core-java/build/libs/jd-core-java-1.2.jar jd-core-java-1.2.jar

# Delete the directory containing the application source code
rm -rf jd-core-java

Decompile the JAR files

# Copy the JAR files to decompile to that directory
cp ../johnDoeProject/*.jar .

# Iterate over all JAR files
for JAR in *.jar; do
  # Get the filename
  FOLDER="${JAR%.*}"

  # Decompile the JAR file into its proper directory
  java -jar jd-core-java-1.2.jar $JAR $FOLDER
done

# Remove decompiled JAR files
rm -rf *.jar

Additional links

32