2012-09-05 177 views
11

我想知道是否有人用proguard混淆他們的leiningen編譯uberjars的經驗。我已盡全力在Google上尋找解決方案,但無法真正找到答案。我想知道這是否可能。用ProGuard混淆clojure uberjars

我一直在試圖混淆默認lein項目。這裏的core.clj文件:

(ns proguard.core 
(:gen-class)) 

(defn -main 
    "I don't do a whole lot." 
    [& args] 
    (println "Hello, World!")) 

項目文件:

(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) 

和我的ProGuard配置文件:

-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*(...); 
} 

每當我嘗試運行混淆的JAR,我得到以下錯誤:

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 

我真的不確定我在做什麼錯在這裏...我試着遵循一個clojure有針對性的proguard教程obfuscating with proguard,但它是android和ant的特定,所以我想知道如果這個過程是完全不同的桌面使用lein的應用程序。

在此先感謝。

+0

我沒有使用proguard的經驗,但從堆棧跟蹤看起來這個混淆器已經從uberjar中排除了clojure運行時。你必須保留clojure.jar中的* all *類以使程序正常工作,而不僅僅是幾個'__init'類似於你的配置。我猜測並說您必須將clojure.jar添加到'-libraryjars'列表中。 –

+0

嘿,謝謝你指點我正確的方向!整個clojure.jar確實需要保持放置。我會很快回答我自己的問題。 [編輯:嗯,我想我不能這樣做,因爲這個問題還太年輕...] – deadringer

+0

你應該現在回答你自己的問題,現在它已經夠大了。就問題而言,問題之前的答案是令人困惑的。 – Tom

回答

13

從上面複製:

進行模糊uberjars

1.準備您的project.clj文件

這裏是我的一個副本(簡單,默認雷音項目,評論):

(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"]] 
    :main proguard.core 
    ;;; Make sure everything is aot compiled 
    :aot :all 
    ;;; Remove source .clj files from the resulting jar 
    :omit-source true 
) 

這裏沒有太多的東西了...... Al所以請確保(:gen-class)包含在您的名稱空間聲明中。

lein uberjar構建uberjar,我們即將進入下一步。

2.準備你的ProGuard配置文件

再次我的文件的副本與註解

# Our uberjar 
-injars clojure/proguard/target/proguard-0.1.0-SNAPSHOT-standalone.jar 
# Our output direcotry 
-outjars clojure/obfuscated 

# Link to rt.jar. I'm on a Mac so your path may differ 
-libraryjars /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/rt.jar 

# ProGuard options. Detailed explanation here http://proguard.sourceforge.net/index.html#manual/usage.html 
-dontskipnonpubliclibraryclassmembers 
-dontnote 
-printseeds 

# What we will be doing is obfuscating, shrinking and optimizing the jar. 
# If you experience any problems start out with obfuscation and add the 
# -dontoptimize and the -dontshrink flags and see if it works. 

# Tell proguard to leave the clojure runtime alone 
# You would need to add any other classes that you wish to preserve here. 
-keep class clojure.** { *; } 

# Keep our core__init class 
-keep class proguard.core__init { 
    public static void load(); 
} 

# Keep classes that contain a main method (otherwise we won't be able to run the jar) 
-keepclasseswithmembers public class * { 
    public static void main(java.lang.String[]); 
} 

那它遵循。現在用你的新配置文件java -jar proguard.jar @myconfig.pro運行proguard。由於-printseeds標誌(你當然可以刪除,如果你不想看看proguard保存哪些類),你應該會看到一堆輸出。