I was wondering if anybody has any experience with obfuscating their leiningen compiled uberjars with proguard. I’ve tried my best to look for a solution on Google but couldn’t really find an answer. I’m wondering if this is at all possible.
I’ve been trying to obfuscate a default lein project. Here’s the core.clj file:
(ns proguard.core
(:gen-class))
(defn -main
"I don't do a whole lot."
[& args]
(println "Hello, World!"))
the project file:
(defproject proguard "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]]
:aot :all
:main proguard.core)
and my proguard config file:
-injars clojure/proguard/target/proguard-0.1.0-SNAPSHOT-standalone.jar
-outjars clojure/test-project
-libraryjars /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/rt.jar
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-dontpreverify
-dontnote
-printseeds
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
-keep class clojure.core__init { public static void load(); }
-keep class clojure.core_proxy__init { public static void load(); }
-keep class clojure.core_print__init { public static void load(); }
-keep class clojure.genclass__init { public static void load(); }
-keep class clojure.core_deftype__init { public static void load(); }
-keep class clojure.core.protocols__init { public static void load(); }
-keep class clojure.gvec__init { public static void load(); }
-keep class clojure.java.io__init { public static void load(); }
-keep class clojure.lang__init { public static void load(); }
-keep class proguard.core__init {
public static void load();
}
-keep class proguard.core {
public *** super*(...);
}
Whenever I try to run the obfuscated jar I get the following errors:
Exception in thread "main" java.lang.ExceptionInInitializerError
at clojure.lang.ve.<init>(Unknown Source)
at clojure.lang.ve.c(Unknown Source)
at clojure.lang.yf.a(Unknown Source)
at proguard.core.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: clojure.lang.PersistentList, compiling:(clojure/core.clj:20)
at clojure.lang.at.a(Unknown Source)
at clojure.lang.at.b(Unknown Source)
at clojure.lang.at.a(Unknown Source)
at clojure.lang.bj.a(Unknown Source)
at clojure.lang.at.a(Unknown Source)
at clojure.lang.at.b(Unknown Source)
at clojure.lang.at.a(Unknown Source)
at clojure.lang.at.a(Unknown Source)
at clojure.lang.at.a(Unknown Source)
at clojure.lang.xh.a(Unknown Source)
at clojure.lang.xh.a(Unknown Source)
at clojure.lang.xh.b(Unknown Source)
at clojure.lang.xh.d(Unknown Source)
at clojure.lang.xh.c(Unknown Source)
at clojure.lang.xh.<clinit>(Unknown Source)
... 4 more
Caused by: java.lang.ClassNotFoundException: clojure.lang.PersistentList
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at clojure.lang.ec.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at clojure.lang.xh.h(Unknown Source)
at clojure.lang.bp.b(Unknown Source)
at clojure.lang.bp.a(Unknown Source)
at clojure.lang.bq.a(Unknown Source)
... 19 more
I’m not really sure what I’m doing wrong here… I’ve tried to follow a clojure targeted proguard tutorial obfuscating with proguard, however it is android and ant specific so I’m wondering if the process is entirely different for desktop applications that use lein.
Thanks in advance.
Copied from above:
Obfuscating uberjars
1. Preparing your project.clj file
Here’s a copy of mine (simple, default lein project, with comments):
There isn’t much more to it here… Also make sure that (
:gen-class)is included in your namespace declarations.Build the uberjar with
lein uberjarand we are off to the next step.2. Preparing your ProGuard config file
Once again a copy of my file follows with annotations
Thats it. Now run proguard with your new configuration file
java -jar proguard.jar @myconfig.pro. You should see a bunch of output due to the-printseedsflag (which you of course can remove if you don’t want to see which classes will be kept by proguard).