I have an Android App which consists on different modules. The Main module is using some libs like Google's GSON or the v4.support.package. A custom build script with the right proguard.cfg will build it, too.
Now I must integrate another "Android-Library" which uses partly the same libs (GSON support.v4). Beside from getting a lot of Notes like
Note: duplicate definition of program class [com.google.gson.Gson]
I get also some Notes like
[proguard] Note: com.google.gson.UnsafeAllocator: can't find dynamically referenced class sun.misc.Unsafe
[proguard] Note: the configuration refers to the unknown class 'sun.misc.Unsafe'
that I find strange cause i have some 'keeps' in my Proguard.cfg especially for that:
-keepattributes Signature, Annotation
-keep class com.google.gson.** {*;}
-keep class sun.misc.Unsafe { *; }
which works well on my project without referencing the module-library inside it.
I'm on the Latest SDK and Tools, and added a custom proguard.cfg to the module-library, which works well on the module-lib itself (if build in standalone-mode).
It seems to me, that the build is not depending on custom proguard.cfg inside library-projects. Any idea on what to try highly appreciated
I finally found a solution for it myself:
with the last Android Tools (16), every Android-Library gets compiled on its own first.
So when the lib has not a "standart" build and defines some custom build script including proguard --keeps, and this --keeps are defined on the same Project (excluding Android SDK classes, as thei're not compiled) it leads to an proguard error.
The Solution was do remove proguard out of the lib and copy the --keeps inside the main App
Related
I have a project that is using the new RenderScript support library and is also using proguard for obfuscation.
Proguard was working great on the code when using the normal RenderScript SDK (android.renderscript.*). And the code is working great with the RenderScript support library when compiled in a non-release build where proguard does not run.
But, bring the two together and the result is this:
Warning: android.support.v8.renderscript.RenderScript: can't find referenced class android.os.SystemProperties
Warning: android.support.v8.renderscript.RenderScript: can't find referenced class android.os.SystemProperties
Warning: android.support.v8.renderscript.RenderScriptThunker: can't find referenced method 'android.renderscript.RenderScript create(android.content.Context,int)' in class android.renderscript.RenderScript
You should check if you need to specify additional program jars.
Warning: there were 2 unresolved references to classes or interfaces.
You may need to specify additional library jars (using '-libraryjars').
Warning: there were 1 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'.
I know just enough about proguard to be dangerous. One thing I have learned is that the suggestions in the warning/error messages tend not to necessarily point at the actual cause of the issue. This time is no different: implementing the suggested changes in the warnings results in no change of the output.
Can the RenderScript support library be used with proguard? And if so, is there some magic that I need to add to my proguard config to make it work?
-dontwarn android.support.v8.**
actually encountered this yesterday...
For androidX
-keep class androidx.renderscript.** { *; }
Combining the previous two ansers, in any modern app that uses Renderscript, you should add the follwing to your proguard-rules.pro file.
# Render Script
-keep class android.support.v8.renderscript.** { *; }
-keep class androidx.renderscript.** { *; }
This will take care of both apps that use the Android support library, or Android X
My app is able to run without any issues during testing etc. But when I export out apk compiled with ProGuard, there are issues like random crashing and some features not working as expected.
I not sure is it due to the external jar libraries I have included in the project which is not properly configured in Proguard.
I have included the following in the proguard-android.txt file. I have two libraries so I added these:
-keep class org.apache.commons.net.** { *; }
-keep class org.jsoup.** { *; }
Is it the correct way? Is there any other way?
To add libraries just add -libraryjars ../libs/<libname>
After that you may need to keep classes and interfaces based on the errors you receive
I have a libgdx android project in eclipse which I've added scala and AndroidProguardScala natures to. This was working great, but suddenly eclipse has started giving me the warning "More than one Scala library found on the build path". I can still build and install the project on a device, but it exits immediately with NoClassDefFoundError: scala.Tuple2$mcZZ$sp, so it looks like the Scala library isn't being included at all.
My project seems to have the Scala library both under "Scala Library [2.10.1]" (as "scala-library.jar") and under "Android Dependencies" (as "scala_library.min.jar") so I guess that the Proguard output is conflicting with the original library, but I have no idea why this has happened or how to fix it.
At this point I could just make a new project and copy the source files over, but it would be great if anyone could shed some light on this.
Edit: After some experimentation it turns out that this code (from within a method of a trait) seems to be causing the problem.
acckeys match {
case (true, false) => acceleration.set(0, accel).rotate(rotation)
case (false, true) => acceleration.set(0, -accel).rotate(rotation)
case _ => acceleration.set(0, 0)
}
(where acckeys is a function returning a tuple and acceleration is a vector)
The multiple libraries warning is still there, so I guess that isn't related to to the problem. Luckily, I don't actually need to reference this code from the android version of the project, but it would still be useful to know why this code compiles but fails to run.
I know exactly what issue you are having. This has to do with the AndroidProgaurdScala not recognizing the class files you have in your main project. The result is, any classes which are defined in the android project are included, but any 'new' ones, such as your tuple, will be missing and because of that you get the wonderful NoClassDefFoundError. I haven't encountered the warning with "More than one Scala library found on the build path", but it probably means you added the scala nature to the project and also added the library.jar on top of it as well. Try to undo your configuration and follow what I have below; otherwise, set up a new project with the steps below and copy your source over.
I found the Scala Nature and Android Proguard Scala are a bit of a pain to fix after they have run a muck. I'm not 100% sure you will be able to salvage an existing project, but we can try and see what happens. First, remove all scala related natures from your projects and get them back into their initial state they would be in for just a plain old Java project.
Let's walk through setting up libGDX with Scala and see where things went wrong:
Make sure your environment is setup correctly. (Note: you will need to get the latest versions)
Set up the libGDX project as normal. (Or use an existing project in your case)
Right-click the android project, "Add Scala nature" then "Add AndroidProgaurdScala nature"
Right-click the main project, "Add Scala nature"
Right-click the desktop project, "Add Scala nature"
Now, this is probably where you have gotten to already, but there is still the issue of AndroidProgaurdScala not knowing what classes you have in your main project. It appears to overlook included projects and doesn't add them to the scala_library.min.jar. To fix this I have found one solution that works well:
Right-click Android Project > Properties > Java Build Path
Go to Projects tab, remove the main project. I know this is counterintuitive, but trust me.
Go to source tab > Link Source...
Navigate and select the "src" folder from your main project
Press OK
Clean and rebuild the projects.
This setup I have tested and used extensively without any issues. Both Android and Desktop versions are happy and work without any complaints with Scala or mixed code. The android project is now fully aware of all the Scala classes you are using in the main project because the source is now copied into the build for the android project. (i.e. No NoClassDefFoundError should appear with anything Scala related).
I've gotten a similar message when my Proguard configuration file has a problem. You might check:
Is Proguard being run
Your config file has: -keep public class **.YourPackage.** or something like it
Your config file is modified for the Scala libraries, eg.
## SCALA SETTINGS
-dontwarn **$$anonfun$*
-dontwarn scala.android.**
-dontwarn scala.beans.ScalaBeanInfo
-dontwarn scala.collection.generic.GenTraversableFactory
-dontwarn scala.collection.immutable.RedBlack$Empty
-dontwarn scala.concurrent.forkjoin.**
-dontwarn scala.reflect.**
-dontwarn scala.sys.process.**
-dontwarn scala.tools.**,plugintemplate.**
#(org.xml.sax.EntityResolver)Class.forName(variable).newInstance()
-dontnote org.xml.sax.EntityResolver
#(org.apache.james.mime4j.storage.StorageProvider)Class.forName(variable).newInstance()
-dontnote org.apache.james.mime4j.storage.DefaultStorageProvider
-dontnote scala.android.app.Activity
-keep class scala.android.package**
-keep class * extends scala.android.app.Activity
## Fixes ==> Warning: ... can't find referenced class sun.misc.Unsafe
-libraryjars D:\Program Files\Apache\m2\repository\com\google\code\findbugs\jsr305\2.0.1\jsr305-2.0.1.jar
-dontwarn sun.misc.Unsafe
-keep class * extends scala.runtime.MethodCache {
public ;
}
-keepclassmembers class * {
** MODULE$;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool {
long eventCount;
int workerCounts;
int runControl;
scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack;
scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread {
int base;
int sp;
int runState;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask {
int status;
}
-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue {
scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head;
scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail;
scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe;
}
I'm trying to build an Android release with Ant and ProGuard. I uncommented the following line in project.properties, despite the comment in said file noting that you shouldn't modify it ;):
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
When obfuscating, I get the following notes:
[proguard] Note: the configuration refers to the unknown class 'com.google.vending.licensing.ILicensingService'
[proguard] Note: the configuration refers to the unknown class 'com.android.vending.licensing.ILicensingService'
I do understand why this is happening. These lines can be found in the default ProGuard config file (${sdk.dir}/tools/proguard/proguard-android.txt):
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
I'm not using the Google Licensing Service, so the classes are indeed unknown. I found a solution to get rid of these notes by updating the proguard-project.txt:
-dontnote **ILicensingService
My question: Is this the correct way of handling this? It seems to me that these classes shouldn't be kept by default anyway, since that lib isn't mandatory for an android project. The only way I can think of to achieve this is by copying the default config file to my project, removing the -keep lines and ignoring the default config file in the SDK completely. Which doesn't seem as the proper way to go either. Or am I missing something?
The setting "-dontnote com.google.vending.licensing.ILicensingService" is fine. In fact, it could have been part of the default configuration file.
The -keep option may be necessary for projects that use the library.
The -dontnote option may be nice to suppress the note about the -keep option, for projects that don't use the library. The note is just a gentle reminder that the configuration file could contain a typo, because the specified class doesn't seem to exist. It doesn't affect the processing.
I'm using a jar of which I don't have the source code. I started using the proguard tool and some of the functionality of the implementation of this jar stop working, so I tried changing the proguard configuration by adding (As seen in another question):
-keep class com.myexternaljar.** { public protected *; }
But it still doesn't behave as it should. So I'm guessing that this jar uses some other external classes that are being modified by the proguard tool.
Is there any configuration that can keep all the classes in a certain jar and all the classes that aren't in the jar itself but that are used by it?