Qualcuno ha mai provato a combinare l'uso di google guice con l'offuscamento (in particolare proguard)? La versione offuscata del mio codice non funziona con google guice in quanto guice si lamenta dei parametri di tipo mancanti. Questa informazione sembra essere cancellata dalla fase di trasformazione che proguard fa, anche quando le classi rilevanti sono escluse dall'offuscamento.L'iniezione con google guice non funziona più dopo l'offuscamento con proguard
L'analisi dello stack si presenta così:
com.google.inject.CreationException: Guice creation errors:
1) Cannot inject a Provider that has no type parameter
while locating com.google.inject.Provider
for parameter 0 at de.repower.lvs.client.admin.user.administration.AdminUserCommonPanel.setPasswordPanelProvider(SourceFile:499)
at de.repower.lvs.client.admin.user.administration.AdminUserCommonPanel.setPasswordPanelProvider(SourceFile:499)
while locating de.repower.lvs.client.admin.user.administration.AdminUserCommonPanel
for parameter 0 at de.repower.lvs.client.admin.user.administration.b.k.setParentPanel(SourceFile:65)
at de.repower.lvs.client.admin.user.administration.b.k.setParentPanel(SourceFile:65)
at de.repower.lvs.client.admin.user.administration.o.a(SourceFile:38)
2) Cannot inject a Provider that has no type parameter
while locating com.google.inject.Provider
for parameter 0 at de.repower.lvs.client.admin.user.administration.AdminUserCommonPanel.setWindTurbineAccessGroupProvider(SourceFile:509)
at de.repower.lvs.client.admin.user.administration.AdminUserCommonPanel.setWindTurbineAccessGroupProvider(SourceFile:509)
while locating de.repower.lvs.client.admin.user.administration.AdminUserCommonPanel
for parameter 0 at de.repower.lvs.client.admin.user.administration.b.k.setParentPanel(SourceFile:65)
at de.repower.lvs.client.admin.user.administration.b.k.setParentPanel(SourceFile:65)
at de.repower.lvs.client.admin.user.administration.o.a(SourceFile:38)
2 errors
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:354)
at com.google.inject.InjectorBuilder.initializeStatically(InjectorBuilder.java:152)
at com.google.inject.InjectorBuilder.build(InjectorBuilder.java:105)
at com.google.inject.Guice.createInjector(Guice.java:92)
at com.google.inject.Guice.createInjector(Guice.java:69)
at com.google.inject.Guice.createInjector(Guice.java:59)
Ho cercato di creare un piccolo esempio (senza utilizzare Guice) che sembra riprodurre il problema:
package de.repower.common;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
class SomeClass<S> {
}
public class ParameterizedTypeTest {
public void someMethod(SomeClass<Integer> param) {
System.out.println("value: " + param);
System.setProperty("my.dummmy.property", "hallo");
}
private static void checkParameterizedMethod(ParameterizedTypeTest testObject) {
System.out.println("checking parameterized method ...");
Method[] methods = testObject.getClass().getMethods();
for (Method method : methods) {
if (method.getName().equals("someMethod")) {
System.out.println("Found method " + method.getName());
Type[] types = method.getGenericParameterTypes();
Type parameterType = types[0];
if (parameterType instanceof ParameterizedType) {
Type parameterizedType = ((ParameterizedType) parameterType).getActualTypeArguments()[0];
System.out.println("Parameter: " + parameterizedType);
System.out.println("Class: " + ((Class) parameterizedType).getName());
} else {
System.out.println("Failed: type ist not instance of ParameterizedType");
}
}
}
}
public static void main(String[] args) {
System.out.println("Starting ...");
try {
ParameterizedTypeTest someInstance = new ParameterizedTypeTest();
checkParameterizedMethod(someInstance);
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
Se si esegue questo codice unsbfuscated , l'output è il seguente:
Starting ...
checking parameterized method ...
Found method someMethod
Parameter: class java.lang.Integer
Class: java.lang.Integer
Ma eseguendo la versione offuscata con pro i rendimenti di guardia:
Starting ...
checking parameterized method ...
Found method someMethod
Failed: type ist not instance of ParameterizedType
Queste sono le opzioni che ho usato per l'offuscamento:
-injars classes_eclipse\methodTest.jar
-outjars classes_eclipse\methodTestObfuscated.jar
-libraryjars 'C:\Program Files\Java\jre6\lib\rt.jar'
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontshrink
-printusage classes_eclipse\shrink.txt
-dontoptimize
-dontpreverify
-verbose
-keep class **.ParameterizedTypeTest.class {
<fields>;
<methods>;
}
-keep class ** {
<fields>;
<methods>;
}
# Keep - Applications. Keep all application classes, along with their 'main'
# methods.
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
# Also keep - Enumerations. Keep the special static methods that are required in
# enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Also keep - Database drivers. Keep all implementations of java.sql.Driver.
-keep class * extends java.sql.Driver
# Also keep - Swing UI L&F. Keep all extensions of javax.swing.plaf.ComponentUI,
# along with the special 'createUI' method.
-keep class * extends javax.swing.plaf.ComponentUI {
public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
}
# Keep names - Native method names. Keep all native class/method names.
-keepclasseswithmembers,allowshrinking class * {
native <methods>;
}
# Keep names - _class method names. Keep all .class method names. This may be
# useful for libraries that will be obfuscated again with different obfuscators.
-keepclassmembers,allowshrinking class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String,boolean);
}
Qualcuno ha un'idea di come risolvere questo (a parte la soluzione ovvia per mettere i file in questione in un separato barattolo e non lo offuscare)?
Con i migliori saluti,
Stefan
Wow, questa è una pessima notizia che devi usare i metodi @Provides solo per impedire a ProGuard di rimuovere le dipendenze. Questo richiede uno strumento per aiutare. Presumo che funzionerebbe anche (quasi ugualmente fastidiosamente) attaccare un gruppo di linee di mantenimento nella configurazione di proguard? –
Forse perché aggiungere l'annotazione -keep renderà i refactoring meno efficaci, poiché in jar di uscita dovremo assicurarci che i nomi delle classi siano validi. A mio parere, il funzionamento su un livello Java puro rende il nostro codice più conforme al refactoring (se esiste una cosa simile) – Riduidel