how to keep private members in pro-guard rules - java

I am trying to use Proguard to keep my private fields, but it won't work.
I stole most of this from Proguard keep classmembers because that question is similar to what I'm asking, and also followed this link How to tell ProGuard to keep private fields without specifying each field
But it still doesn't work.
I want to make a library for another company and still keep my access level modifiers fields and methods.
Proguard:
-keepclassmembers class com.example.mylibrary.Bedika {
private <fields>;
}
-keep class com.example.mylibrary.Bedika {
*;
}
My AAR library
public class Bedika {
private String stam;
public Bedika(String stam) {
this.stam = stam;
}
public void print() {
System.out.println(stam);
}
}
output after Proguard:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.example.mylibrary;
public class Bedika {
public String stam;
public Bedika(String var1) {
this.stam = var1;
}
public void print() {
System.out.println(this.stam);
}
}

It seems like R8 is causing this issue and not Proguard.
Go into gradle.properties, and set android.enableR8=false. Next time you build, it will use Proguard.
R8 is Google's answer to Proguard and in the recent versions of The Android Gradle Plugin (3.4.0+) it defaults to R8's code shrinker/obfuscator. There are some pros and cons to using Google's version instead of Guardsquare's technology.
For more information, look at the documentation

You can usually add the #Keep annotation above the class or object (in Java or Kotlin). This is pretty self-explanatory, and will work.

Related

Proguard does not remove Log.d in internal classes?

I use
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
public static java.lang.String getStackTraceString(java.lang.Throwable);
}
However when I decompile, I see the one and only custom string I used in a Log.d line in decompiled jar file. How can that be possible? Doesn't Proguard remove Log.d lines completely?
This is relevant if proguard optimization is enabled i.e. your proguard.config is this
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
Just for clarification, it's my understanding optimisation 'has' to been enabled for the log calls to be stripped.
You could try using a Log wrapper class (like this one) to wrap android.util.Log. I used this approach due to a note from Eric (a.k.a Mr Proguard) in this answer about how Proguard inspects the code. So this ends up with a simpler call to Log.d(tag, string) rather than Log.d(tag, string + value+ String)
Or use DexGuard IIRC is has some explicit function for log removal. --
[update: sorry my bad it's not a explicit function DexGuard uses the same config as you noted. I guess I was thinking the fact the decompiled code is more mangled with DexGuard.]

UnsatisfiedLinkError: Native method not found (NOT caused by the common cause for this error)

I am trying to use a library that uses JNI.
I've tried the sample app provided by the developers and it works. So I know it's not a bug in the library.
I assume I'm doing something wrong in the process of importing the library:
copy the .so file into my libs folder (its called libjniRTSP.so)
copy the the jniRTSP.java (summarized below) into my project:
public class jniRTSP {
private volatile static jniRTSP libRTSP = null;
public static jniRTSP getInstance() {
if(null == libRTSP) {
synchronized(jniRTSP.class) {
if(null == libRTSP) {
libRTSP = new jniRTSP();
libRTSP.InitProductList();
// DEBUG
libRTSP.SetDebugView(1);
}
}
}
return libRTSP;
}
static {
try {
System.loadLibrary("jniRTSP");
} catch (Exception e) {
e.printStackTrace();
}
}
public native int GetBrandEnableRecorder();
public native int GetBrandEnableLocal();
public native int GetBrandEnableRemote();
...
then in my onCreate() I try to call one of the methods:
jniRTSP.getInstance().Init(.....)
Which returns the error:
UnsatisfiedLinkError: Native method not found com.myuniquepackage.jniRTSP.InitProductList:()I
UPDATE (FIX): instead of just copying the jniRTSP java file, I copied the whole package that contained it, keeping the same package name. I'm not sure if this fixed it because the package name was the issue, or if because it needed one of the other java files that were in that package. Although I'm pretty sure if it was a missing file, it would complain at compile time.
Fairly certain the package declarations have to be the same inside the C code as the Java code.
So the class jniRTSP should be in the com.myuniquepackage package in Java and have the native method InitProductList declared and the C code should have method declared as Java_com_myuniquepackage_jniRTSP_InitProductList
By moving the class you are probably breaking the link, change the package declaration in Java to match the demo project and see if it works, if it does you can change it back and then change it in the C code which is a bit more time consuming but easy enough.

Refactor and obfuscate all variable names in java

I tried ProGuard with NetBeans to obfuscate the class. After decompiling I see that it's only renaming local variables names.
Can anyone help explain to me how to refactor all variables names including public members. I can do that myself in NetBeans but it'll take forever. Also, ProGuard is obfuscating everything, even the libraries; I want to obfuscate only my classes. It doesn't matter if libraries are obfuscated or not.
For example, my global class contains variables like this:
public class D {
public static boolean doneSplash = false;
public static boolean bossActive = false;
.....
Is there a way to make it like ...
public class D {
public static boolean asdsa6d = false;
public static boolean xgrrret7 = false;
.....
Can anyone help?
use proguard gui and uncheck following option
skip non public library class
skip non public library class members

Java (Eclipse) - Conditional compilation

I have a java project that is referenced in j2me project and in android project.
In this project i would like to use conditional compilation.
Something like...
//#if android
...
//#endif
//if j2me
...
//#endif
I have been reading about this but i did not find anything useful yet.
You could use Antenna (there is a plugin for Eclipse, and you can use it with the Ant build system).
I'm using it in my projects in a way you've described and it works perfectly :)
EDIT: here is the example related to #WhiteFang34 solution that is a way to go:
In your core project:
//base class Base.java
public abstract class Base {
public static Base getInstance()
{
//#ifdef ANDROID
return new AndroidBaseImpl();
//#elif J2ME
return new J2MEBaseImpl();
//#endif
}
public abstract void doSomething();
}
//Android specific implementation AndroidBaseImpl.java
//#ifdef ANDROID
public class AndroidBaseImpl extends Base {
public void doSomething() {
//Android code
}
}
//#endif
//J2ME specific implementation J2MEBaseImpl.java
//#ifdef J2ME
public class J2MEBaseImpl extends Base {
public void doSomething() {
// J2Me code
}
}
//#endif
In your project that uses the core project:
public class App {
public void something {
// Depends on the preprocessor symbol you used to build a project
Base.getInstance().doSomething();
}
}
Than if you want to build for the Android, you just define ANDROID preprocessor symbol or J2ME if you want to do a build for a J2ME platform...
Anyway, I hope it helps :)
Perhaps you should consider creating interfaces around the logic that's specific to a profile (J2ME, Android or other in the future). Then create concrete implementations of your interface for each profile. Any common parts you could split out into an abstract base class for both implementations to extend. This way your logic for each profile is nicely separated for different concerns. For each profile just build the appropriate set of classes (you could separate them by package for example). It'll be easier to maintain, debug, test and understand in the long run.
Eclipse MTJ project provides preprocessing support as documented . This support was mainly targeted for tackling fragmentation problems on JavaME. I have not tested the preprocessing support together with the Android tooling but it may just work.

java proguard: library doesnt work after optimization

i am optimizing a jar with proguard, but it crashes after optimization.
here is my proguard task:
<proguard>
-injars ${dist}/${jarname}
-outjars ${dist}-proguard/${jarname}
-target 5
-libraryjars '${java.home}/lib/rt.jar'
-dontobfuscate
-optimizationpasses 4
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
-keep public class * {
public static void main(java.lang.String[]);
}
</proguard>
as soon as i put in the -dontoptimize option, it works.
according to the stack of the exception it crashes when accessing a static public member of a class with a nullpointer. here is the code:
public static Texture ring, dust, spikering, thinring, crystal, clouds;
public static void init() {
Field [] fields = TexturePool.class.getDeclaredFields();
for (Field field : fields) {
if(field.getType() == Texture.class) {
field.set( null, /*imagine new object here*/ );
}
}
}
thanks!
ok, i just found out myself. i think the optimization completely optimized that classmembers away, since they are not directly accessed in this class. if i specify the option:
-keepclassmembers public class com.package.** {
public static * ;
}
it works even with optimization.
According to Best Java Obfuscation Application For Size Reduction:
"I was always able to fix the problem by not using the Proguard argument "-overloadaggressively"."
Perhaps you should try the same?
EDIT: The problem could easily be that an assignment is optimized away. The initializations happening in the source code, where a field is defined, is actually done by the compiler in a static code blokc. Appears that the optimizations tinker with that. What happens with fewer optimization passes?
I had the same issue with ProGuard optimizing away class fields that were modified using reflection API only. However, the suggested answer didn't work for me as there were too many classes scattered throughout the code base to specify class filter.
Instead, disabling field optimization did the trick for me:
-optimizations !field/*

Categories

Resources