0

In Android, I have proguard with the following settings.

-dontpreverify

# Hold onto the mapping.text file, it can be used to unobfuscate stack traces in the developer console using the retrace tool
-printmapping mapping.txt

# Keep line numbers so they appear in the stack trace of the develeper console
-keepattributes SourceFile,LineNumberTable 

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

# Activities, services and broadcast receivers are specified in the manifest file so they won't be automatically included
-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 

# Custom view components might be accessed from your layout files
-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*(...);
}

# event handlers can be specified in the layout files e.g. android:onClick="nextButton_onClick", I borrowed this method name notation from .NET
-keepclassmembers class * extends android.app.Activity {
    public void *_*(android.view.View);
}

# Parcelable implementations are accessed by introspection
-keepclassmembers class * implements android.os.Parcelable {
    static android.os.Parcelable$Creator CREATOR;
}

# You might want to keep your annotations
-keepattributes *Annotation*

# I use Google Guava in my app
# see http://code.google.com/p/guava-libraries/wiki/UsingProGuardWithGuava
-libraryjars libs/google/jsr305-1.3.9.jar;libs/pinyin4j/pinyin4j-2.5.0.jar
-dontwarn sun.misc.Unsafe

-keepclasseswithmembers class com.google.common.base.internal.Finalizer{
    <methods>;
}

Some of my library, are directly imported from Java SE (Contains JApplet for example)

How I can exclude them from proguard? Note, I have pinyin4j-2.5.0.jar library in -libraryjars. I thought that's the way to tell proguard, "Hey, this is a library. Don't do anything on it, OK?" But, seems like proguard still trying to process pinyin4j-2.5.0.jar

I'm getting the following errors.

Note: there were 125 duplicate class definitions.
Warning: demo.Pinyin4jAppletDemo: can't find superclass or interface javax.swing.JApplet
Warning: demo.Pinyin4jAppletDemo$1: can't find superclass or interface java.awt.event.WindowAdapter
Warning: demo.Pinyin4jAppletDemo$2: can't find superclass or interface java.awt.event.ActionListener
Warning: demo.Pinyin4jAppletDemo$3: can't find superclass or interface java.awt.event.ActionListener
Warning: org.jasypt.encryption.pbe.PBEBigDecimalCleanablePasswordEncryptor: can't find superclass or interface org.jasypt.encryption.pbe.PBEBigDecimalEncryptor
Warning: org.jasypt.encryption.pbe.PBEBigIntegerCleanablePasswordEncryptor: can't find superclass or interface org.jasypt.encryption.pbe.PBEBigIntegerEncryptor
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyDescriptor
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyDescriptor
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyEditor
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyEditor
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyEditor
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyEditorManager
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyDescriptor
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.IntrospectionException
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyEditor
Warning: au.com.bytecode.opencsv.bean.CsvToBean: can't find referenced class java.beans.PropertyDescriptor
...
...
Warning: org.jasypt.normalization.Normalizer: can't find referenced class com.ibm.icu.text.Normalizer$Mode
      You should check if you need to specify additional program jars.
Warning: there were 333 unresolved references to classes or interfaces.
         You may need to specify additional library jars (using '-libraryjars').
Warning: there were 6 unresolved references to program class members.
         Your input classes appear to be inconsistent.
         You may need to recompile them and try again.
         Alternatively, you may have to specify the option 
         '-dontskipnonpubliclibraryclassmembers'.
Error: Please correct the above warnings first.

Some of you may comment that for library jars which contain Java SE only methods (like Applet, Swing, ...) cannot be used in Android. Nope. In fact, they run perfectly fine, as long as you consume their non-Java SE-only methods.

The full error log can be downloaded from here : https://www.dropbox.com/s/dns62f7gp6unusg/error-log.txt

Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
  • Android does not have those classes, and therefore you cannot use them anyway in your Android app. – CommonsWare Jan 15 '13 at 17:48
  • i'd assume you include this as a library, therefor you need to append it to `-libraryjars`, but i don't really see what you are trying to do here. These classes won't work on android. – njzk2 Jan 15 '13 at 18:13
  • All of them are library. In fact, they (pinyin4j-2.5.0.jar -> demo.Pinyin4jAppletDemo for example) work perfectly before I introduce proguard. The reason they work is, I only consume methods from libraries, which doesn't involve Java SE only methods. The problem now is, ProGuard seems want to take care of all my lib jars. – Cheok Yan Cheng Jan 16 '13 at 01:11
  • @njzk2 The classes with error are all libraries. Hence, I thought by telling proguards that, "Hey, these're libraries!". Thing will be better. In fact, it doesn't help. – Cheok Yan Cheng Jan 16 '13 at 01:20

3 Answers3

6

If you are sure that these Java SE classes are not used, you can indeed ignore the warnings (as you have found in your own answer). An easier way to specify this:

-dontwarn java.beans.**
-dontwarn java.awt.**
-dontwarn javax.swing.**

See ProGuard manual > Troubleshooting > Warning: can't find referenced class

Similar questions with always the same answer:

Community
  • 1
  • 1
Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
1

Example to keep java runtime (rt.jar)

<libraryjar file="${java.home}/lib/rt.jar" />

It seems that your line

-libraryjars libs/google/jsr305-1.3.9.jar;libs/pinyin4j/pinyin4j-2.5.0.jar

is not complete. Update But since the needed classes do not exist on android, you have to ignore these warnings. But do not generally ignore obfuscation warnings, we had a serious bug (using an obfuscation.map in file), because we ignored all warnings.

AlexWien
  • 28,470
  • 6
  • 53
  • 83
  • I already include `libs/pinyin4j/pinyin4j-2.5.0.jar` in -libraryjars, but still, there is error for demo.Pinyin4jAppletDemo (It is found in pinyin4j-2.5.0.jar) – Cheok Yan Cheng Jan 16 '13 at 01:13
  • you have to include the runtime, too. android.jar? i dont know android well. – AlexWien Jan 16 '13 at 01:18
  • In fact, I don't really understand what is the use of -libraryjars after reading their documentation. We tell proguard that "they are libraries". OK, if they are libraries, what proguard is going to do with these libraries? – Cheok Yan Cheng Jan 16 '13 at 01:23
  • it does not obfuscate them! they stay external. when using injar command then all that libs are obfuscated and merged into the one outjar. but the jars in libraryjars stay untouched. usually the system runtime lib (rt.jar ) and all jars that are LGPL which are nitvallowed to be obfuscated. – AlexWien Jan 16 '13 at 01:24
  • thx for info. u have idea why, even I specific pinyin4j library in -libraryjars, I'm still getting proguard warning on pinyin4j? seems like proguard is trying to "touch" it. – Cheok Yan Cheng Jan 16 '13 at 01:35
  • no read the whole error message in line of pinyin4j, it states that it does not find javax.Swing. find out in which jar swing is located (rt.jar?) and add that to -libraryjars. and as first step ignore the warning, look at the errors – AlexWien Jan 16 '13 at 02:21
  • Adding a library jar would indeed be a clean way to solve the warning, but it doesn't solve the root issue that these Java SE classes are not present on Android. Since the questioner reports that the application works okay in practice, he can explicitly ignore the warnings with -dontwarn. – Eric Lafortune Jan 18 '13 at 01:36
0

I merely avoid the error by

-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
-dontwarn javax.swing.**
-dontwarn java.awt.**
-dontwarn org.jasypt.encryption.pbe.**
-dontwarn java.beans.**
-dontwarn org.joda.time.**
-dontwarn com.google.android.gms.**
-dontwarn org.w3c.dom.bootstrap.**
-dontwarn com.ibm.icu.text.**
-dontwarn demo.**

Here's the complete proguard configuration

-optimizationpasses 1
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

#-dontobfuscate

-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
-dontwarn javax.swing.**
-dontwarn java.awt.**
-dontwarn org.jasypt.encryption.pbe.**
-dontwarn java.beans.**
-dontwarn org.joda.time.**
-dontwarn com.google.android.gms.**
-dontwarn org.w3c.dom.bootstrap.**
-dontwarn com.ibm.icu.text.**
-dontwarn demo.**

# Hold onto the mapping.text file, it can be used to unobfuscate stack traces in the developer console using the retrace tool
-printmapping mapping.txt

# Keep line numbers so they appear in the stack trace of the develeper console 
-keepattributes *Annotation*,SourceFile,LineNumberTable

-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }

# https://sourceforge.net/p/proguard/discussion/182456/thread/e4d73acf
-keep class org.codehaus.** { *; }

-assumenosideeffects class android.util.Log {
  public static int d(...);
  public static int i(...);
  public static int e(...);
  public static int v(...);  
}

-keepclasseswithmembernames class * {
    native <methods>;
}

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

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

-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
}

# I use Google Guava in my app
# see http://code.google.com/p/guava-libraries/wiki/UsingProGuardWithGuava
-libraryjars libs/google/jsr305-1.3.9.jar

-keepclasseswithmembers class com.google.common.base.internal.Finalizer{
    <methods>;
}

It doesn't work completely out of box yet as I still experience crash in "after proguard generated" APK.

Is pretty hard for me to find out why it crashes, as the code is obfuscate.

If I specific dontobfuscate, I will get another set of problem during generation. A message "Conversion to Dalvik format failed with error 1" pop up without additional information. But, that's another set of different problem.

Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875