Why proguard processes AndroidManifest.xml - java

I see some unexplained Proguard behaviour.
AFAIK proguard does not pay attention to android manifest. Also, in my proguard.cfg I have no mention of BroadcastReceiver related classes. So I assume that those should be stripped out.
However I see something strange in bin/proguard.txt:
# view AndroidManifest.xml #generated:784
-keep class com.fiksu.asotracking.InstallTracking { <init>(...); }
and that class (descendand of BroadcastReceiver) does not get stripped. Reason does not say anything meaningful to me:
[proguard] com.fiksu.asotracking.InstallTracking
[proguard] is kept by a directive in the configuration.
If class is not mentioned in manifest, it gets stripped.
Would be great to know why.

The build process runs the tool aapt to automatically create the configuration file bin/proguard.txt, based on AndroidManifest.xml and other xml files. The build process then passes the configuration file to ProGuard. So ProGuard itself indeed doesn't consider AndroidManifest.xml, but aapt+ProGuard do.

Related

What causes this error in Proguard: "Method must be overridden in [proguard.optimize.peephole.ClassMerger] if ever called"?

I am running Proguard via the Maven Plugin, you can see my configuration here: https://github.com/sanity/tahrir/blob/proguard-debug/pom.xml#L61
You can see the complete output of "mvn -DskipTests assembly:assembly" here: https://gist.github.com/ee1081179496e11916cb
Despite quite a bit of searching I cannot find any explanation of what causes this error, nor now I can fix it?
Your input contains a library class that depends on a program class. ProGuard warns about it and doesn't allow it, unless you specify -dontwarn. You should remove that option and check ProGuard's warnings for details.
See the ProGuard manual > Introduction
See the ProGuard manual > Troubleshooting > Warning: library class ... depends on program class ...
For me, having
proguard.config=proguard-project.txt
caused the same error.
Correcting to include both sdk and my config file like below fixed it.
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

not able to configure cofoja on eclipse

Eclipse is up to date, cofoja too, and so are java jre/jdk.
ASM should be included in cofoja, but I downloaded the 3.3 just in case.
I followed all the procedures I could find in internet, but the first error eclipse is giving never changed from the first step: "Syntax error, insert "EnumBody" to complete BlockStatements".
The code is very basic:
import java.io.whatever;
import java.net.whatever;
import com.google.java.contract.Requires;
public class ManageSocketServerExplicit{
[...]
public ManageSocketServerExplicit(String p_ipAddress, int p_port){
#Requires("p_port >= 0")
this(p_ipAddress,p_port,10,1000);
[...]
}
}
The error is obviously at the end of the Require.
Configuration
There are several projects in the directory. Let's say that I want to use cofoja just on one of them.
The base directory is C:\svn_java\Progetti_NET, in which there is the project I want to use cofoja on, which is 'Malu'. Into it there are multiple source directories, not just a generic 'src', but the main is called 'Code', and it's the principal.
So the paths are (tried them with both slashes, nothing changes):
classoutput C:\svn_java\Progetti_NET\Malu\bin
classpath C:\svn_java\cofoja-1.1-r146.jar
sourcepath C:\svn_java\Progetti_NET\Malu\Code
Eclipse understands the namespace of cofoja, by the way: I can see the objects listed if I auto-complete them.
So 'Annotation Processing' is all set, and 'Factory Path' again contains "c:\svn_java\cofoja-1.1-r146.jar". The workspace automatically updates when there are changes, and both asmn and cofoja are in the libraries of the 'Java Build Path'.
I tried to add also the -vm command in eclipse.ini to use the jdk (C:/Program Files (x86)/Java/jdk1.7.0_21/bin), but again nothing changed.
Since the configuration is pretty simple it shouldn't be so hard to fix it, but I don't know how.
i used Cofoja with eclipse and i used this link to configure it.
However it has a missing factory path. You need to state the sourcepath too as shown in my image.
If you run it using eclipse, you have to set the run configurations of the file and add the following VM arguements
-javaagent:PATH TO JAR/cofoja.jar
And #Requires and #Ensures are method-level contracts.
You cant write it within the method. Instead you need to write it as follows
public class ManageSocketServerExplicit{
[...]
#Requires("p_port >= 0") // CONTRACT
public ManageSocketServerExplicit(String p_ipAddress, int p_port){
this(p_ipAddress,p_port,10,1000);
[...]
} }
Hope it helps :D
Ok, I understood what was wrong: after adding the source code of cofoja to the project I understood I placed the #Requires in the wrong place... The annotation #Ensures gave me this error, but I forgot about it.
:(
a very well realized tutorial: http://webcourse.cs.technion.ac.il/236700/Spring2013/ho/WCFiles/Contracts%20for%20Java.pdf

Android, Proguard & XmlPullParser: NoSuchMethodError

I am using XmlPullParser and when the app pass throught the Proguard, and the apk is running on device, it give me the following error:
08-06 17:10:26.717: E/AndroidRuntime(2527):
Caused by: java.lang.NoSuchMethodError: org.xmlpull.v1.XmlPullParser.d
I have added -ignorewarnings in my proguard.cfg or otherwise there is no way to pass the Proguard.
Here is a link to my proguard.cfg file.
You obfuscated away a method you shouldn't have. You need to keep the pull parser code intact. Add:
-keep public class org.xmlpull.**
to your proguard.cfg file.
what you want in your proguard config file is -keep instead of -ignorewarnings
-keep class org.xmlpull.** { *; }
See the following url for some more details
http://android-developers.blogspot.com/2010/09/proguard-android-and-licensing-server.html
But Wait, My App is Crashing Now
Most crashes happen because Proguard has obfuscated away something that your application needs,
such as a class that is referenced in the AndroidManifest or within a
layout, or perhaps something called from JNI or reflection. The
Proguard configuration provided here tries to avoid obfuscating most
of these cases, but it’s still possible that in edge cases you’ll end
up seeing something like a ClassNotFoundException.
You can make edits to the procfg.txt file to keep classes that have
been obfuscated away. Adding:
-keep public class * [my classname]
should help. For more information about how to prevent Proguard from
obfuscating specific things, see the Proguard manual. Specifically,
the keep section. In the interest of security, try to keep as little
of your application unobfuscated as possible.
The standard settings provided in procfg.txt will be good for many
applications, and will catch many common cases, but they are by no
means comprehensive. One of the things that we’ve done is had Proguard
create a bunch of output files in the obf directory to help you debug
these problems.
The mapping.txt file explains how your classes have been obfuscated.
You’ll want to make sure to keep this around once you have submitted
your build to Market, as you’ll need this to decipher your stack
traces.

Proguard issues with jar files, how to find the missing jar?

When I try to export my apk with Proguard I get a lot of errors (over 400) similar to:
Warning: org.codehaus.jackson.jaxrs.JsonMappingExceptionMapper: can't find superclass or interface javax.ws.rs.ext.ExceptionMapper
and
org.codehaus.jackson.xc.DataHandlerJsonDeserializer$1: can't find superclass or interface javax.activation.DataSource
I am using the Jackson Json library, and the errors seem related to that.
Researching this error I found the following from Proguards FAQ:
If there are unresolved references to classes or interfaces, you most likely forgot to specify an essential library. For proper processing, all libraries that are referenced by your code must be specified, including the Java run-time library. For specifying libraries, use the -libraryjars option.
Searching around on SO I found a lot of unanswered questions related to this, but the general sense was that the jar file I am using (in this case Jackon JSON) is relying on more libraries and they need to be added to Proguard's config file some how.
However, I can't figure out how to determine what jars are needed and where they are. The warnings mention a lot of different packages such as javax.ws.rs.ext, org.joda.time, org.codehaus.stax2, javax.xml.stream, etc.
How do I determine what jars contain those packages? For example, what jar is required for the javax.ws.rs.ext.** classes?
How do I figure out where those jars are and what path would be used with -libraryjars in Proguard?
Thanks much
Edit: I should also mention that I am using an Android Library Project setup. The jars are in the main Library project, and the actual working project has their build paths including the jars in the Library project. Don't know if that makes a difference but thought I should mention it.
Update Just to test, I completely removed the jackson far from the build path and from my code and now Proguard completes successfully. The questions still remain... What is the correct approach for handling these errors?
Does the Android export wizard in Eclipse automatically add the /lib/ jars to proguard or do they all have to be added manually in the proguard config file like this:
-libraryjars C:/Project/lib/somjar.jar
I did try that for the jackson one but it didn't make any difference. Does this mean I also have to find all of the jars that are needed for the classes mentioned in the warnings and add those? Would they be in the sdk or in the java installation?
Sorry if these are stupid questions, but I have been trying to figure this out for the last couple hours and have no idea what to do.
Thanks again
Update Again
So more searching, combined with Benjamin's suggestion, I found some of the missing classes were in rt.jar, which is in the jdk's lib folder. So I ended up adding
-libraryjars <java.home>/lib/rt.jar
To the proguard.cfg file and brought the warnings from 485 down to 204. Hey I guess that's something... The remaining warnings describe classes that I cannot find at all. The app works just fine without running proguard, so these classes must be somewhere right? Or are these warnings that I should use -dontwarn with?
The remaining classes are in these packages:
org.joda.time.
org.codehaus.stax2.
javax.ws.rs.
So now I just need a way to figure out:
What jars have these classes
Where are these jars so I can include them in the proguard config file
I've had similar problems with Proguard and similar errors I was using an osmdroid.jar which built OK unobfuscated. This jar must have had external dependencies which my application didn't need. Fortunately the authors listed the jars needed and once I downloaded them and told Proguard via the -libraryjars option, the Proguard build was OK.
Re your missing jars (which you probably don't really need, but Proguard thinks you might!), you should find them at:
org.joda.time
(The jar's inside the zip)
org.codehaus.stax2.
javax.ws.rs.
I only can provide an answer for the first part:
Give
http://www.findjar.com
a try, there you might find the names of the needed jar files
like so
You don't need to include the libraries for Proguard; you need to instead instruct Proguard to keep the class names and some other stuff. I toyed around with it a bit myself, and I ended up with something similar to this discussion:
-keepnames class org.codehaus.** { *; }
-keepattributes *Annotation*,EnclosingMethod
-dontwarn org.codehaus.jackson.**
If you're still experiencing crashes—and I would suggest testing vigorously!—you might want to keep Jackson completely intact with:
-keep class org.codehaus.** { *; }
-keepattributes *Annotation*,EnclosingMethod
-dontwarn org.codehaus.jackson.**
(Note that the latter produces a larger file.)

Netbeans Obfuscation

I'm very new to obfuscation and don't have a lot of experience with ant. Come someone provide me a way to obfuscate a regular Java application with ProGuard (or any other open source obfuscator). Currently I'm using NetBeans 6.5.1, and only see the obfuscation ability if I create a JAVA ME, and not a Java Application like I have. I've looked at http://wiki.netbeans.org/DevFaqModuleObfuscation, but don't understand what they're saying.
Thanks for any input.
The FAQ you point to is for obfuscating NetBeans modules. This is quite a complicated use case, so I will assume that it is not the regular application you are interested in.
Very briefly: the obfuscation process changes the names of classes, methods and fields to make it more difficult to reverse engineer your application.
This causes some issues:
the JVM requires your application to have a public static void main( String args[] ) in a public class, so you must tell proguard not to change this name
if you are using any sort of introspection, you have to protect the relevant names from being changed
other cases, as explained in the manual
Additionally, proguard strips out unused code. If you have any classes that are used but not referenced directly, you have to -keep them as well.
The proguard documentation includes an example of how to obfuscate a simple application. Here is the example explained (with some less confusing names):
-injars application.jar # obfuscate all the classes in the named jars
-outjars obfuscated.jar # save all the obfuscated classes to the named jar
-libraryjars <java.home>/lib/rt.jar # these are all the libraries that the application uses
-printmapping obfuscation.map # save a file linking the original names to the obfuscated ones
# this helps understanding stack traces from the obfuscated application
# we need to keep our main class and the application entry point
-keep public class com.mycompany.Application {
public static void main(java.lang.String[]);
}
Unless you specify -dontshrink, proguard will remove any code not kept or not referenced from any kept code. So in the above configuration, any code not referenced (indirectly) by the main method will be removed.
Proguard includes an Ant task that can be used to integrate with the NetBeans workflow. I would suggest experimenting manually first though, without Ant, as that takes one of the complicating factors out of the process. Build your application jar with NetBeans and then try to obfuscate with the above configuration (fleshed out if necessary). Make sure to test the obfuscated application, as innumerable things can go awry. Once you have a working proguard configuration, try adding an Ant task to your build file to automate the obfuscation process within NetBeans.
Another solution than -dontskipnonpubliclibraryclasses is to use the same JDK for running proguard as you used for compiling the code in the JAR file.
For example, instead of
java -jar ../proguard3.8/lib/proguard.jar
use
/usr/local/jdk1.5.0/bin/java -jar ../proguard3.8/lib/proguard.jar
Jacob

Categories