Java, ProGuard, and Ant - How to obfuscate Java class files with ProGuard

Java obfuscator/obfuscation FAQ: How can I obfuscate my Java class files so they can't easily be decompiled? (Or, how do I use ProGuard to obfuscate my Java class files?)

As I've written before in Java decompilers and obfuscators, if you're sharing a Java application with other people, and you don't want them to be able to easily decompile your Java class files, you're going to want to obfuscate your Java class files. One way to obfuscate your class files is with a tool named ProGuard. In this article I'll share how I obfuscate my Hyde application with ProGuard.

Using ProGuard with Ant to obfuscate Java class files

As I mentioned in an earlier article, you can easily decompile Java class files with a tool given the name "Java Decompiler Project". I tested this Java decompiler on my own class files, and it works as advertised, magically turning my Java class files back into Java source code.

If you're selling a Java application, or trying to protect trade secrets while distributing Java class files, the counter measure to this is to obfuscate your Java class files. There are several free projects that help you do this, including one named ProGuard, which I used on my Java application.

There are a number of ways to configure ProGuard, but I choose to create an Ant task to obfuscate my Java class files, as my application is built using Ant, and adding another Ant task made it easy to keep building my application this way.

At the beginning of my Ant build.xml configuration file I added one line like this to specify the default ProGuard Ant properties:

<taskdef resource="proguard/ant/task.properties" classpath="/Users/al/DD/Projects/DesktopShield/build/proguard.jar" />

Later in the Ant build.xml file I created an "obfuscate" task, which would be run immediately after my "create-jar" task. My entire obfuscate task is shown here:

<!-- ANT OBFUSCATE TASK -->  
<target name="obfuscate" depends="create-jar">
  <proguard
    allowaccessmodification="true"
    usemixedcaseclassnames="false"
    defaultpackage=""
    skipnonpubliclibraryclasses="false"
    printseeds="obfuscateseeds.txt"
    printusage="obfuscateusage.txt"
    printmapping="obfuscatemapping.txt">

    <!-- specify which jar files should be obfuscated -->
    <injar name="${jar.dir}/${jar-file-name}"/>
    <injar name="${jar.dir}/truexml.jar"/>
    <injar name="${jar.dir}/truelicense.jar"/>
    <injar name="${jar.dir}/trueswing.jar"/>

    <!-- java libraries my java application depends on -->
    <libraryjar name="${java.home}/../Classes/classes.jar"/>    <!-- rt.jar on other platforms -->
    <libraryjar name="${java.home}/../Classes/ui.jar"/>         <!-- ApplicationAdapter and Co. -->
    <libraryjar name="${java.home}/../Classes/jce.jar"/>        <!-- crypto stuff -->
    <libraryjar name="${jar.dir}/forms-1.0.7.jar"/>
    <libraryjar name="${jar.dir}/quaqua.jar"/>
    <libraryjar name="${jar.dir}/commons-codec-1.4.jar"/>

    <!-- the output jar file that should be created with the obfuscated java class files -->
    <outjar name="${jar.dir}/HydeApp.jar"/>

    <!-- don't obfuscate this method -->
    <keep name="com.devdaily.heidi.Hyde">
      <method name="main"/>
    </keep>
    
    <!-- this class gets serialized, and i don't want it messed with -->
    <keep name="com.devdaily.heidi.DCRuntime">
      <constructor/>
      <method name="get*"/>
      <method name="set*"/>
    </keep>

    <!-- this is a true license class that cannot be obfuscated -->
    <!-- have to keep this one to get this to work with obfuscation -->
    <keep name="de.schlichtherle.license.ftp.LicenseParam">
      <constructor/>
      <method name="*"/>
    </keep>

    <!-- more true license classes that must be left alone -->
    <keep name="de.schlichtherle.license.LicenseContent">
      <constructor/>
      <method name="get*"/>
      <method name="set*"/>
    </keep>
    <keep name="de.schlichtherle.xml.GenericCertificate">
      <constructor/>
      <method name="get*"/>
      <method name="set*"/>
    </keep>
  </proguard>
  
  <!-- delete the "injars" when obfuscation is complete -->
  <delete>
    <fileset dir="${jar.dir}">
      <include name="${jar-file-name}"/>
      <include name="truexml.jar"/>
      <include name="truelicense.jar"/>
      <include name="trueswing.jar"/>
    </fileset>
  </delete>
  
</target>

As you can see from the code, my Ant obfuscate task use the proguard Ant task to do its work. All I have to do is tell ProGuard which jar files to use as input, which jar files are dependencies for my application, and which classes or methods ProGuard should leave alone using the "keep" tag. In my case I had to tell ProGuard to leave a number of classes and methods alone because I used the TrueLicense library to license my Java application, and their documentation mentioned which classes and methods could not be obfuscated because they relied on reflection.

After this Ant obfuscate task is run, I'm left with a jar file given by the name in the "outjar" task, specifically "HydeApp.jar". To verify that the obfuscation process worked properly, I opened this jar file and tried to decompile the Java class files in it, but indeed, they had been obfuscated properly.

Java obfuscation with ProGuard and Ant - summary

Unless there are any questions, I'll leave this article on how to obfuscate your Java class files with ProGuard as is for the time being. If you think it will be helpful to share my entire Ant build file here I'll be glad to do so, but I didn't want to complicate things too much.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值