2012-09-05 4 views
11

Mi chiedevo se qualcuno avesse qualche esperienza con l'offuscamento dei loro uberjars compilati da leiningen con proguard. Ho fatto del mio meglio per cercare una soluzione su Google, ma non ho potuto trovare una risposta. Mi chiedo se questo è possibile.Offuscamento di uberjar con ProGuard

Ho cercato di offuscare un progetto di lein predefinito. Ecco il file core.clj:

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

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

il file di progetto:

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

e la mia Proguard file di configurazione:

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

Ogni volta che provo a fare funzionare il vaso offuscato ottengo il seguente errori:

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 

Non sono sicuro di cosa sto facendo male qui ... Ho provato a seguire un'esercitazione di proguard mirata per il clojure obfuscating with proguard, tuttavia è Android e ant specifico quindi mi chiedo se il processo è completamente diverso per il desktop applicazioni che usano lein.

Grazie in anticipo.

+0

Non ho esperienza con proguard, ma dallo stacktrace sembra che questo obfuscator abbia escluso il runtime clojure dall'uberjar. Devi mantenere * tutte * le classi da clojure.jar per far funzionare il tuo programma, non solo diversi '__init' come sembra dalla tua configurazione. Prendo un'ipotesi e dico che devi aggiungere clojure.jar alla lista di '-libraryjars'. –

+0

Ehi, grazie per avermi indicato nella giusta direzione! L'intero clojure.jar non ha bisogno di stare fermo. Risponderò alla mia domanda a breve. [EDIT: hmm, immagino di non poterlo fare, dato che la domanda è ancora troppo giovane ...] – deadringer

+0

Dovresti rispondere correttamente alla tua domanda ora che è abbastanza vecchia.Così com'è, con la risposta prima della domanda, è fonte di confusione. – Tom

risposta

13

copiato da sopra:

offuscando uberjars

1. Preparare il file project.clj

Ecco una copia del mio (semplice, progetto di default Lein, con i commenti):

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

Non c'è molto di più qui ... Al quindi assicurati che (:gen-class) sia incluso nelle dichiarazioni del tuo spazio dei nomi.

Costruisci l'uberjar con lein uberjar e siamo al passaggio successivo.

2. Preparazione del file di configurazione ProGuard

Ancora una volta una copia del mio file segue con annotazioni

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

questo è tutto. Ora esegui proguard con il nuovo file di configurazione java -jar proguard.jar @myconfig.pro. Dovresti vedere un mucchio di output a causa del flag -printseeds (che puoi rimuovere se non vuoi vedere quali classi saranno mantenute da proguard).