What are the proper ProGuard rules for Smack 4.1 when building an Android release apk?
Currently, I'm using the rules from aSmack 4.0.x from the README.asmack file on the aSmack github repository which is outdated (references old class names, and intended for 4.0.x). I could not find any references to what the proper proguard rules to use for 4.1.x are, could anyone shed light on this?
What are the proper Proguard rules for Smack 4.1 when building an
Android release apk?
Depends on what "proper" means for you.
The easiest way is likely to tell ProGuard to keep all classes and interfaces of Smack.
-keep class org.jivesoftware.smack.** { *; }
-keep class org.jivesoftware.smackx.** { *; }
Alternatively you can configure ProGuard so that it only keeps those parts of Smack that you actually use, and let ProGuard strip everything else. But to do so, you'll need a good understanding how your App uses Smack. See for example the ProGuard configuration of MAXS's Transport XMPP: https://bitbucket.org/projectmaxs/maxs/src/75efeba8d8470b89da8cd8551304bb00648e4945/transport-xmpp/proguard-project.txt?at=master#cl-20
Note that if you don't know exactly what are you doing, then Smack could behave unexpectedly or even crash. Only fine tune ProGuard if you know what you are doing!
Actually, my experience suggests you may actually need an additional line if you are also using proguard and have minify enabled. If you get the error
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
Then the following config is needed instead:
-keepattributes Signature
-keep class org.jivesoftware.smack.** { *; }
-keep class org.jivesoftware.smackx.** { *; }
See: smack for android fails when using proguard for more details.
Related
I have two modules - core and auth. In auth module I am trying to integrate Google Sign In to Firebase. All dependencies resolving correctly, but not a GoogleSignInClient. I don't want use dagger for this entity to provide this client somewhere. I want to use it only in this class. But dagger shows me an error :
class file for com.google.android.gms.auth.api.signin.GoogleSignInClient not found
Consult the following stack trace for details.
com.sun.tools.javac.code.Symbol$CompletionFailure: class file for com.google.android.gms.auth.api.signin.GoogleSignInClient not found
e: D:\Projects\<project path>\build\tmp\kapt3\stubs\internalProductionDebug\<class path>\di\components\AppComponent.java: error:
[ComponentProcessor:MiscError] dagger.internal.codegen.ComponentProcessor was unable to process this interface because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.
Unfortunately it wasn't dagger problem. It happens with using several Android modules when you use api and implementation in gradle incorrectly.
I don't know why, but when I fixed my dependencies in Gradle - all become working.
this is my first time using a obfuscator (ProGuard) for obfuscation of my code. I have two J2EE projects EJB and webProject. Currently I am obfuscating only my EJB.jar project and it is also hosting webservices but before i reach that part i am getting an error
I successfully generated the output jar using ProGuard GUI app, but when I deploy that jar on my server (wildfly) it gave me this exception:
org.hibernate.AnnotationException: No identifier specified for entity: com.metadatatool.b.a
This b.a is the obfuscated code original names were different.
This exception is basically being invoked on a entity i.e. a View and it has a #Id identifier it works normal if I don't obfuscate my code but when I do it gives me this error.
I am using the -keep attributes feature of ProGuard but still i am getting this error
EJB uses reflection and requires that some classes keep their original names, methods and annotations when they go through obfuscation. To fix your problem, you need add a couple of rules such as:
-keepattributes RuntimeVisibleAnnotations
-keep #javax.persistence.* class * {
*;
}
to make ProGuard not strip annotations and not touch classes annotated with #Id.
Having proguard issues since last update. (project and sdk, API 19)
First, com.android.dex.DexException: Multiple dex files define Lcom/google/gson/JsonSerializer;
OK, visiting bin/proguard and unjarring obfuscated.jar I do see com/google/gson/JsonSerializer declared there. Why? It should be in the lib only.
That is the crux of the question, why is Proguard copying in classes from the libs jars into ""?
And what is "" anyways? Progaurd fails saying the class is defined in gcm and "". What is ""? The class in only defined in libs/gcm.jar and nowhere else before I run the build.
Longer version, I add this to my proguard config:
-libraryjars libs(!gson-2.1.jar,!RSAMobileSDK-1.01.jar;)
Can't see it does anything. Following other questions and answers on StackOverflow, I edit the android build.xml.
I do this: (because it turns out the -libraryjars in the config file is not being passed throug)
-libraryjars ${project.target.classpath.value};libs/gson-2.1.jar
Still it says the file is multiply defined. If I could get proguard to ignore it then it would not be defined there. So, I try this in the build.xml:
Replace this:
-injars ${project.all.classes.value}
with this:
-injars bin\proguard\original.jar
What happens then?
It works!
So, why do I have to spefify these in the < proguard > element in the android build.xml, and how are I supposed to be able to do this with a config file?
-injars <b>bin\proguard\original.jar</b>
-libraryjars ${project.target.classpath.value}<b>;libs/gson-2.1.jar</b>
Don't specify additional input with -injars or -library jars in any configuration files; the build process already specifies these options for you. You'll only get lots of warnings about duplicate class files.
ProGuard indeed processes your own code together with the libraries. This is how it can significantly reduce the size of the application's code.
I'm developing a JavaFX application using IntelliJ IDEA as the IDE.
So far, everything runs smoothly, I have all my external libs configured and my JavaFX artifact being correctly created.
Now I would like to integrate obfuscation (using Proguard) when the artifact is created.
IntelliJ have a 'Pre-processing' and 'Post-processing' option in artifact's properties where I can define an Ant task to be runned.
But I have no idea how to create that task and tell the compiler my obfuscation options.
Thank you very much in advance for any clues,
Best regards
There are 3 basic ways you do it:
Create a normal proguard.cfg file, and reference it from ant
Put your proguard settings directly inside ant using XML notation
Put your proguard settings directly inside ant using the proguard.cfg format
Here's a basic example of using Proguard with Ant with the 3rd approach:
http://www.reviewmylife.co.uk/blog/2007/10/20/proguard-eclipse-ant-buildxml/
The important thing to remember about Proguard is that everything you want to obfuscate has to be inside a JAR file, and you'll need to explicitly tell it not to obfuscate certain things (like your program entry point, things you access via reflection, etc).
JavaFX creates a file used as an entry point you want to prevent obfuscating:
-keepclasseswithmembers public class com.javafx.main.Main {
public *; public static *;
}
Make sure to include Java/JavaFX libs
-libraryjars "${java.home}/lib/rt.jar"
-libraryjars "${java.home}/lib/ant-javafx.jar"
-libraryjars "${java.home}/lib/jfxrt.jar"
If you're using FXML files, you'll want to make sure your FXML files are renamed similarly to their respective controller file:
-adaptresourcefilecontents **.fxml
Anything annotated with #FXML is accessed through reflection, so don't obfuscate them:
-keepclassmembernames class * {
#javafx.fxml.FXML *;
}
The Proguard website has a lot of information, but it can be difficult to grok.
Honestly, there are plenty of examples on the web that show you how to do this. Just google javafx proguard, and you'll probably find some good complete examples.
Edit: as far as how IntelliJ passes information to Ant.. I don't know. There are probably some variables it passes in that you reference like a normal Ant propertly. I'm sure JetBrains website has info on that on their website if you can't find it on the net.
If it was me, I'd just create an ant script to compile my application without obfuscation, then add in proguard once you've got that squared away.
Just some complementing information, regarding running an Ant task in idea's 'post-processing'.
Make sure you have a 'default' target. Else the task wont execute. Example of build.xml:
<?xml version="1.0"?>
<project name="ant_task" default="obfuscate" basedir=".">
<target name="obfuscate">
<taskdef resource="proguard/ant/task.properties"
classpath="/opt/proguard5.2.1/lib/proguard.jar" />
<proguard configuration="proguard.cfg"/>
</target>
</project>
My Proguard config file uses the following to remove log statements:
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** e(...);
}
Apparently this only takes effect when optimizations are turned on, so I reference proguard-android-optimize.txt in my project properties file, instead of proguard-android.txt.
Is this a inconsequential change to make? proguard-android-optimize.txt says "Adding optimization introduces certain risks, since for example not all optimizations performed by
ProGuard works on all versions of Dalvik" What exactly does this mean, and can I possibly not use proguard-android-optimize.txt and instead add just the optimization statements that are necessary to my own config file so that log removal takes effect?
Thanks. Total Proguard novice.
You can indeed only remove logging if optimization is enabled.
Optimization should be pretty stable in current versions of ProGuard. You can replace <android.sdk>/tools/proguard/lib/proguard.jar with the latest version if you wish. For instance, version 4.9 has improvements to remove traces of logging from the code, compared to version 4.7 in the Android SDK at this time of writing (indicated by the output of "java -jar proguard.jar").