Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

trying to -keep entire library & its...

Help
2011-01-05
2012-12-17
  • Larry Hamel
    Larry Hamel
    2011-01-05

    How can I exclude an entire jar from obfuscation?  I'm trying the following config , copied from the bottom of my proguard config file.  The manual indicates that "-keep" should do the trick without needing a redundant "-keepclassmembers", but I'm trying everything I can find with no luck.

    # proguard config excerpt:
    -keep class com.j256.**
    -keepclassmembers class com.j256.**
    -keep enum com.j256.**
    -keepclassmembers enum com.j256.**
    -keep interface com.j256.**
    -keepclassmembers interface com.j256.**

    In the stacktrace below, note that some of the ormlite methods HAVE been obfuscated/renamed (the trace has been run through retrace-search "SourceFile" and "ormlite" ).  The library in question is ormlite ( http://ormlite.sourceforge.net/ ), which uses reflection extensively.

    thanks,

    larry

    stacktrace:
          01-04 19:46:42.739: ERROR/AndroidRuntime(30226): FATAL
    EXCEPTION: main
                  java.lang.NoSuchFieldError: UNKNOWN
                  at java.lang.reflect.Method.getDefaultValue(Native
    Method)
                  at
    java.lang.reflect.Method.getDefaultValue(Method.java:341)
                  at
    org.apache.harmony.lang.annotation.AnnotationFactory.getElementsDescription(AnnotationFactory.java:
    77)
                  at
    org.apache.harmony.lang.annotation.AnnotationFactory.<init>(AnnotationFactory.java:
    117)
                  at
    org.apache.harmony.lang.annotation.AnnotationFactory.createAnnotation(AnnotationFactory.java:
    99)
                  at
    java.lang.reflect.Field.getDeclaredAnnotations(Native Method)
                  at
    java.lang.reflect.Field.getDeclaredAnnotations(Field.java:188)
                  at
    java.lang.reflect.AccessibleObject.getAnnotations(AccessibleObject.java:
    188)
                  at
    java.lang.reflect.AccessibleObject.getAnnotation(AccessibleObject.java:
    196)
                  at
    com.j256.ormlite.field.FieldType.createFieldType(SourceFile:504)
                  at
    com.j256.ormlite.table.DatabaseTableConfig.extractFieldTypes(SourceFile:
    122)
                  at
    com.j256.ormlite.table.DatabaseTableConfig.fromClass(SourceFile:111)
                  at
    com.j256.ormlite.dao.BaseDaoImpl.<init>(SourceFile:115)
                  at
    com.j256.ormlite.dao.BaseDaoImpl.<init>(SourceFile:83)
                  at com.j256.ormlite.dao.BaseDaoImpl
    $1.<init>(SourceFile:409)

     
  • Eric Lafortune
    Eric Lafortune
    2011-01-05

    The following line keeps all matching classes and their class members:

    -keep class com.j256.** {
       *;
    }
    

    Eric.

     
  • Larry Hamel
    Larry Hamel
    2011-01-06

    This stack trace (without retrace remapping) makes it more obvious that the ormlite classes, while keeping their class name, are having their members obfuscated:

    01-05 20:11:48.710: ERROR/mbot:bk(1390): Unable to create databases
            java.lang.NoSuchFieldError: UNKNOWN
            at java.lang.reflect.Method.getDefaultValue(Native Method)
            at java.lang.reflect.Method.getDefaultValue(Method.java:341)
            at org.apache.harmony.lang.annotation.AnnotationFactory.getElementsDescription(AnnotationFactory.java:77)
            at org.apache.harmony.lang.annotation.AnnotationFactory.<init>(AnnotationFactory.java:117)
            at org.apache.harmony.lang.annotation.AnnotationFactory.createAnnotation(AnnotationFactory.java:99)
            at java.lang.reflect.Field.getDeclaredAnnotations(Native Method)
            at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:188)
            at java.lang.reflect.AccessibleObject.getAnnotations(AccessibleObject.java:188)
            at java.lang.reflect.AccessibleObject.getAnnotation(AccessibleObject.java:196)
            at com.j256.ormlite.field.DatabaseFieldConfig.a(SourceFile:233)
            at com.j256.ormlite.field.FieldType.a(SourceFile:504)
            at com.j256.ormlite.table.DatabaseTableConfig.a(SourceFile:122)
            at com.j256.ormlite.table.DatabaseTableConfig.a(SourceFile:114)
            at com.j256.ormlite.table.TableUtils.a(SourceFile:56)
            at bm.b(SourceFile:83)

    -----------------------------------

    the entire config file is:

    #
    # This ProGuard configuration file for amood
    # Usage:
    #     java -jar proguard.jar @proguardConfig.txt
    #

    # java 1.6
    -target 1.6
    -optimizationpasses 2

    # windows build
    -dontusemixedcaseclassnames

    # provide for stack traces
    -renamesourcefileattribute SourceFile
    -keepattributes SourceFile,LineNumberTable

    -dontpreverify
    -repackageclasses ''
    -allowaccessmodification

    # The -optimizations option disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle.
    -optimizations !code/simplification/arithmetic
    -keepattributes *Annotation*

    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Application
    -keep public class * extends android.app.Service
    -keep public class * extends android.content.BroadcastReceiver
    -keep public class * extends android.content.ContentProvider

    -keep public class * extends android.view.View {
        public <init>(android.content.Context);
        public <init>(android.content.Context, android.util.AttributeSet);
        public <init>(android.content.Context, android.util.AttributeSet, int);
        public void set*(…);
    }

    -keepclasseswithmembers class * {
        public <init>(android.content.Context, android.util.AttributeSet);
    }

    -keepclasseswithmembers class * {
        public <init>(android.content.Context, android.util.AttributeSet, int);
    }

    -keepclassmembers class * implements android.os.Parcelable {
        static android.os.Parcelable$Creator CREATOR;
    }

    -keepclassmembers class **.R$* {
        public static <fields>;
    }

    # Preserve all native method names and the names of their classes.

    -keepclasseswithmembernames class * {
        native <methods>;
    }

    # Preserve the special static methods that are required in all enumeration
    # classes.

    -keepclassmembers class * extends java.lang.Enum {
        public static ** values();
        public static ** valueOf(java.lang.String);
    }

    # Explicitly preserve all serialization members. The Serializable interface
    # is only a marker interface, so it wouldn't save them.
    # You can comment this out if your application doesn't use serialization.
    # If your code contains serializable classes that have to be backward
    # compatible, please refer to the manual.

    -keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        static final java.io.ObjectStreamField serialPersistentFields;
        private void writeObject(java.io.ObjectOutputStream);
        private void readObject(java.io.ObjectInputStream);
        java.lang.Object writeReplace();
        java.lang.Object readResolve();
    }

    -adaptresourcefilenames    **.properties,**.gif,**.jpg
    -adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF

    # Your application may contain more items that need to be preserved;
    # typically classes that are dynamically created using Class.forName:

    # ormlite uses reflection
    -keep class com.j256.**
    -keepclassmembers class com.j256.**
    -keep enum com.j256.**
    -keepclassmembers enum com.j256.**
    -keep interface com.j256.**
    -keepclassmembers interface com.j256.**

    # admob already shrunk
    -keep class com.admob.**

    # keep all constructors
    #-keepclassmembers class com.codeguild.** {
    #    <init>(…);
    #}

    # GLOBAL Optimization settings !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    -keepattributes
    -dontoptimize
    #-dontshrink
    #-dontobfuscate
    #-dontskipnonpubliclibraryclasses

    -----------------------------------

    Here are some warnings for the ormlite library:

      Note: com.j256.ormlite.misc.JavaxPersistence accesses a method 'nullable()' dynamically
      Note: com.j256.ormlite.misc.JavaxPersistence accesses a method 'unique()' dynamically
            Maybe this is program method 'com.j256.ormlite.field.DatabaseField { boolean unique(); }'

     
  • Larry Hamel
    Larry Hamel
    2011-01-06

    Thanks, Eric, that did the trick.  (I saw your post a little late, sorry)

    Consider adding an "optionally" into the wording in the manual, at  http://proguard.sourceforge.net/index.html#/manual/refcard.html , where it says:

        -keep  class_specification Preserve the specified classes and class members.

    which I interpreted to mean that a simple class specification would preserve class members.  If it read:
            " …classes and (optionally) class members."

    I think that would give a better indication.

     
  • Eric Lafortune
    Eric Lafortune
    2011-01-06

    "the specified classes and class members" is intended to mean "the specified classes and the specified class members" (which is not exactly the same as "optionally"). The word "class_specification" might be confusing though; the word "class_and_class_member_specification" would be more accurate. I'll have to think about it.

    Eric.

     
  • Larry Hamel
    Larry Hamel
    2011-01-06

    Yes, I see what you mean.  Either change to the manual would seem beneficial from my newbie perspective.

    BTW, do you think A. and B. below should be equivalent?

    A.

    -keep class com.j256.**
    -keepclassmembers class com.j256.**

    B.

    -keep class com.j256.**  {
         *;
    }

     
  • Eric Lafortune
    Eric Lafortune
    2011-01-07

    A and B are not equivalent. It's again a matter of specifying the class members in the second line of A:

    -keep class com.j256.**
    -keepclassmembers class com.j256.** {
        *;
    }
    

    ProGuard should probably print out a warning that -keepclassmembers won't match anything if you don't specify any class members.

    Eric.