2012-09-05 6 views
11

Ich frage mich, ob irgendjemand irgendwelche Erfahrung mit Verschleierung ihrer Leiningen kompilierten Uberjars mit Proguard hat. Ich habe mein Bestes versucht, nach einer Lösung bei Google zu suchen, konnte aber keine Antwort finden. Ich frage mich, ob das überhaupt möglich ist.Obwuscating Clojure Uberjars mit ProGuard

Ich habe versucht, ein Standard-Lein-Projekt zu verschleiern. Hier ist die core.clj Datei:

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

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

die Projektdatei:

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

und meine proguard Konfigurationsdatei:

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

Jedes Mal, wenn ich versuche, den verschleierten jar ich folgendes ausführen Fehler:

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 

Ich bin mir nicht wirklich sicher, was ich hier falsch mache ... Ich habe versucht, einem Clojure Targeted Proguard Tutorial obfuscating with proguard zu folgen, aber es ist Android und Ameise spezifisch, also frage ich mich, ob der Prozess für den Desktop völlig anders ist Anwendungen, die lein verwenden.

Vielen Dank im Voraus.

+0

Ich habe keine Erfahrung mit Proguard, aber aus dem Stacktrace sieht es so aus, dass dieser Obfuscator Clojure Runtime vom Uberjar ausgeschlossen hat. Sie müssen * alle * Klassen von clojure.jar behalten, damit Ihr Programm funktioniert, nicht nur einige '__init'-Einsen, wie es von Ihrer Konfiguration aus aussieht. Ich nehme an und sage, dass Sie clojure.jar zur Liste der 'libraryjars' hinzufügen müssen. –

+0

Hey, danke, dass du mich in die richtige Richtung gelenkt hast! Das ganze clojure.jar muss also bleiben. Ich werde meine Frage kurz beantworten. [EDIT: hmm, ich schätze ich kann das nicht, da die Frage immer noch zu jung ist ...] – deadringer

+0

Du solltest deine eigene Frage jetzt richtig beantworten, dass sie alt genug ist.So wie es aussieht, mit der Antwort vor der Frage, ist es verwirrend. – Tom

Antwort

13

von oben kopiert:

Verschleiern uberjars

1. Vorbereiten project.clj Datei

Hier ist eine Kopie von mir (einfach, Standard-lein-Projekt, mit Kommentaren):

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

Es gibt nicht viel mehr hier ... Al Stellen Sie also sicher, dass (:gen-class) ist in Ihren Namespace-Deklarationen enthalten).

Bauen Sie den Überar mit lein uberjar und wir gehen zum nächsten Schritt.

2. Datei Ihre ProGuard Config vorbereiten

Wieder einmal eine Kopie meiner Datei folgt mit Anmerkungen

# 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[]); 
} 

Thats it. Führen Sie nun die neue Konfigurationsdatei java -jar proguard.jar @myconfig.pro aus. Sie sollten eine Reihe von Ausgaben aufgrund der -printseeds Flagge sehen (die Sie natürlich entfernen können, wenn Sie nicht sehen wollen, welche Klassen von prouard gehalten werden).