How to exclude specific methods from a "keep" rule in ProGuard? - proguard

I'm running ProGuard on a library. To keep public methods and attributes from shrinkage and obfuscation, I'm using this rule:
-keep public class com.company.project.** {
public protected <fields>;
public protected <methods>;
}
I need to make a few exceptions to this rule - methods that I actually need to be shrinked/obfuscated regularly by ProGuard. Is that possible? What would be the syntax for that?

Related

Proguard obfuscationdictionary not working

What I'm trying to achieve is to avoid my method paramaters having the names like String paramString or int paramInt. I am trying to use -obfuscationdictionary but it's not working (at least it's not doing what I presume it should, which is use my dictionary words instead of paramString etc)
I have the following Proguard config files in place, but my list of dictionary words are not being used. (I checked that it is finding the dictionary file by renaming the file it looks for, and it didn't compile, stating it couldn't find my dictionary).
# ==========================
# ===== GENERIC CONFIG =====
# ==========================
# Logging
-verbose
# Java Runtime
-libraryjars <java.home>/lib/rt.jar
# don't think I use this
# Preserve native methods
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# don't think I use this
# Preserve special enum methods
-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Preserve some source so it can be retraced
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable,!LocalVariableTable,!LocalVariableTypeTable
# Specific config
-useuniqueclassmembernames
-dontusemixedcaseclassnames # think this is only for unpacking on Windows machines, so shouldn't be applicable
-repackageclasses
#-dontshrink
#-dontoptimize
-obfuscationdictionary proguardDictionary.txt
# ==============================
# ===== APPLICATION CONFIG =====
# ==============================
# Preserve application entry point
#-keep public class MY.MAIN.CLASS.PACKAGE.MyGame {
# public static void main(java.lang.String[]);
#}
# Only obfuscate proprietary code
#-keep class !MY.GAME.PACKAGE.HERE.** { *; }
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.
# Optimizations: If you don't want to optimize, use the proguard-android.txt configuration file
# instead of this one, which turns off the optimization flags.
# Adding optimization introduces certain risks, since for example not all optimizations performed by
# ProGuard works on all versions of Dalvik. The following flags turn off various optimizations
# known to have issues, but the list may not be complete or up to date. (The "arithmetic"
# optimization can be used if you are only targeting Android 2.0 or later.) Make sure you test
# thoroughly if you go this route.
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
-optimizationpasses 5
-allowaccessmodification
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
# Preserve some attributes that may be required for reflection.
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod
#-keep public class com.google.vending.licensing.ILicensingService
#-keep public class com.android.vending.licensing.ILicensingService
#-keep public class uk.co.russellwheeler.matcg.android.dfgcvb.ILicensingService
#-dontnote com.android.vending.licensing.ILicensingService
#-dontnote com.google.vending.licensing.ILicensingService
#-dontnote uk.co.russellwheeler.matcg.android.dfgcvb.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# Keep setters in Views so that animations can still work.
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick.
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# Preserve annotated Javascript interface methods.
-keepclassmembers class * {
#android.webkit.JavascriptInterface <methods>;
}
# The support libraries contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontnote android.support.**
-dontwarn android.support.**
# Understand the #Keep support annotation.
-keep class android.support.annotation.Keep
-keep #android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <init>(...);
}
# =========================
# ===== LIBGDX CONFIG =====
# =========================
# Don't warn about necessary libs
-dontwarn com.badlogic.gdx.utils.GdxBuild
-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild
-dontwarn com.badlogic.gdx.jnigen.BuildTarget*
-dontwarn com.badlogic.gdx.jnigen.**
-dontwarn de.matthiasmann.twlthemeeditor.fontgen.**
-dontwarn org.lwjgl.**
-dontwarn org.objectweb.asm.**
-dontwarn org.slf4j.**
-keepnames class com.badlogic.gdx.backends.android.AndroidInput*
-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {<init>(...);}
# LibGDX | Box2D World
#-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
# boolean contactFilter(long, long);
# void beginContact(long);
# void endContact(long);
# void preSolve(long, long);
# void postSolve(long, long);
# boolean reportFixture(long);
# float reportRayFixture(long, float, float, float, float, float);
#}
-verbose
-dontwarn android.support.**
-dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication
-dontwarn com.badlogic.gdx.utils.GdxBuild
-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild
-dontwarn com.badlogic.gdx.jnigen.BuildTarget*
-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {
<init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
}
-keepclassmembers class uk.co.russellwheeler.matcg.android.** {
<init>(...);
}
-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
boolean contactFilter(long, long);
void beginContact(long);
void endContact(long);
void preSolve(long, long);
void postSolve(long, long);
boolean reportFixture(long);
float reportRayFixture(long, float, float, float, float, float);
}
-keep class javax.activation.* { *; }
-dontwarn javax.activation.**
# Crashlytics 2.+
-keep class com.crashlytics.** { *; }
-keep class com.crashlytics.android.**
-keepattributes SourceFile, LineNumberTable, *Annotation*, !LocalVariableTable,!LocalVariableTypeTable
# If you are using custom exceptions, add this line so that custom exception types are skipped during obfuscation:
-keep public class * extends java.lang.Exception
# For Fabric to properly de-obfuscate your crash reports, you need to remove this line from your ProGuard config:
-printmapping mapping.txt
AFAIK, Proguard does not "obfuscate" parameter names in the same way as other names, it just strips them (because unlike field and class names, parameter names are stored in optional debugging symbols). "Parameter names", that you see in decompiler (paramInt, arg0 etc.), are just made up names, autogenerated by decompiler itself. There is no support for applying obfuscation dictionary to parameter names, — you can either strip them completely or keep them (provided that your binaries had them in the first place).
You can try to preserve original parameter names via -keepattribute LocalVariableTable, but that might not work unless you -keep entire class, — Proguard's handling of local variables in modern classfiles is kinda buggy. If you don't do anything, Proguard will default to removing them.
As the other answer already correctly said, ProGuard will not use the obfuscation dictionary for method parameters. Either they are removed or kept with their original names.
In order to keep them, you have to add the following:
-keepparameternames

Do we need interfaces for dependency injection?

I have an ASP.NET Core application. The application has few helper classes that does some work. Each class has different signature method. I see lot of .net core examples online that create interface for each class and then register types with DI framework. For example
public interface IStorage
{
Task Download(string file);
}
public class Storage
{
public Task Download(string file)
{
}
}
public interface IOcr
{
Task Process();
}
public class Ocr:IOcr
{
public Task Process()
{
}
}
Basically for each interface there is only one class. Then i register these types with DI as
services.AddScoped<IStorage, Storage>();
services.AddScoped<IOcr,Ocr>();
But i can register type without having interfaces so interfaces here look redundant. eg
services.AddScoped<Storage>();
services.AddScoped<Ocr>();
So do i really need interfaces?
No, you don't need interfaces for dependency injection. But dependency injection is much more useful with them!
As you noticed, you can register concrete types with the service collection and ASP.NET Core will inject them into your classes without problems. The benefit you get by injecting them over simply creating instances with new Storage() is service lifetime management (transient vs. scoped vs. singleton).
That's useful, but only part of the power of using DI. As #DavidG pointed out, the big reason why interfaces are so often paired with DI is because of testing. Making your consumer classes depend on interfaces (abstractions) instead of other concrete classes makes them much easier to test.
For example, you could create a MockStorage that implements IStorage for use during testing, and your consumer class shouldn't be able to tell the difference. Or, you can use a mocking framework to easily create a mocked IStorage on the fly. Doing the same thing with concrete classes is much harder. Interfaces make it easy to replace implementations without changing the abstraction.
Does it work? Yes. Should you do it? No.
Dependency Injection is a tool for the principle of Dependency Inversion : https://en.wikipedia.org/wiki/Dependency_inversion_principle
Or as it's described in SOLID
one should “depend upon abstractions, [not] concretions."
You can just inject concrete classes all over the place and it will work. But it's not what DI was designed to achieve.
No, we don't need interfaces. In addition to injecting classes or interfaces you can also inject delegates. It's comparable to injecting an interface with one method.
Example:
public delegate int DoMathFunction(int value1, int value2);
public class DependsOnMathFunction
{
private readonly DoMathFunction _doMath;
public DependsOnAFunction(DoMathFunction doMath)
{
_doMath = doMath;
}
public int DoSomethingWithNumbers(int number1, int number2)
{
return _doMath(number1, number2);
}
}
You could do it without declaring a delegate, just injecting a Func<Something, Whatever> and that will also work. I'd lean toward the delegate because it's easier to set up DI. You might have two delegates with the same signature that serve unrelated purposes.
One benefit to this is that it steers the code toward interface segregation. Someone might be tempted to add a method to an interface (and its implementation) because it's already getting injected somewhere so it's convenient.
That means
The interface and implementation gain responsibility they possibly shouldn't have just because it's convenient for someone in the moment.
The class that depends on the interface can also grow in its responsibility but it's harder to identify because the number of its dependencies hasn't grown.
Other classes end up depending on the bloated, less-segregated interface.
I've seen cases where a single dependency eventually grows into what should really be two or three entirely separate classes, all because it was convenient to add to an existing interface and class instead of injecting something new. That in turn helped some classes on their way to becoming 2,500 lines long.
You can't prevent someone doing what they shouldn't. You can't stop someone from just making a class depend on 10 different delegates. But it can set a pattern that guides future growth in the right direction and provides some resistance to growing interfaces and classes out control.
(This doesn't mean don't use interfaces. It means that you have options.)
I won't try to cover what others have already mentioned, using interfaces with DI will often be the best option. But it's worth mentioning that using object inheritance at times may provide another useful option. So for example:
public class Storage
{
public virtual Task Download(string file)
{
}
}
public class DiskStorage: Storage
{
public override Task Download(string file)
{
}
}
and registering it like so:
services.AddScoped<Storage, DiskStorage>();
Without Interface
public class Benefits
{
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : Benefits
{
private readonly Benefits BT;
public Teacher(Benefits _BT)
{ BT = _BT; }
public void TeacherBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
public class Student : Benefits
{
private readonly Benefits BS;
public Student(Benefits _BS)
{ BS = _BS; }
public void StudentBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
here you can see benefits for Teachers is accessible in Student class and benefits for Student is accessible in Teacher class which is wrong.
Lets see how can we resolve this problem using interface
With Interface
public interface IBenefitForTeacher
{
void BenefitForTeacher();
}
public interface IBenefitForStudent
{
void BenefitForStudent();
}
public class Benefits : IBenefitForTeacher, IBenefitForStudent
{
public Benefits() { }
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : IBenefitForTeacher
{
private readonly IBenefitForTeacher BT;
public Teacher(IBenefitForTeacher _BT)
{ BT = _BT; }
public void BenefitForTeacher()
{
BT.BenefitForTeacher();
}
}
public class Student : IBenefitForStudent
{
private readonly IBenefitForStudent BS;
public Student(IBenefitForStudent _BS)
{ BS = _BS; }
public void BenefitForStudent()
{
BS.BenefitForStudent();
}
}
Here you can see there is no way to call Teacher benefits in Student class and Student benefits in Teacher class
So interface is used here as an abstraction layer.

Interceptor on super method in CDI 1.0/JEE6

In the following case,
public class Base {
#Transactional
public void doSave() {
// ...
}
}
public class Inherited extends Base {
public void someMethod() {
super.doSave();
}
#Override
public void doSave() {
super.doSave();
}
}
If I add the #Transactional annotation to Inherited.someMethod, the interceptor gets called without issue.
However, without the annotation on the inherited class, the interceptor does not get involved in the call to the super class from Inherited.someMethod().
Furthermore, calling Inherited.doSave() does not seem to get the interceptor invoked either. I would have expected the annotation on the superclass to be also valid on the subclass. Is this not the expected behaviour?
I am using Apache DeltaSpike for the #Transactional annotation and this is being deployed as a war in an ear (technically as a jar in a war in an ear). However, this may not be relevant as trying with a custom interceptor shows the same behaviour.
This is JBoss EAP 6.3.0 Alpha in case its relevant.
This is expected. Interceptors are only applied if the object is managed. When you you write it this way with inheritence, it's not applied as it's not part of a call stack that CDI is aware of. You would need to inject Base into your class and call Base.doSave

don't keep super class's public method in proguard

I have class A , and class B extends class A.
My proguard config is :
-keep public class B {
public <methods>;
}
I just want to keep the public methods in B , but proguard keep the public methods in A too.
Does anyone know how to reslove it ?
thanks ~
You'll have to enumerate the methods. Semantically, public methods of super classes are public methods in their subclasses too, so ProGuard keeps them if you use a wildcard..

In Object oriented programming when do we need abstraction?

I read many posts about the "Interface" and "Abstract Class"
Basically, we use "Abstract Class" when we talking about the characteristic of the Object.
And we use "Interface" when we taling about what the object capable can do.
But it still confuse so I make up an example for myself to practice.
so now I thinking of a Object 'Cargo;
public abstract class cargo {
protected int id;
public abstract int getWidth(int width);
public abstract int setWidth(int width);
public abstract int setHeight(int h);
public abstract int getHeight(int h);
public abstract int setDepth(int d);
public abstract int getDepth(int d);
public abstract int volume(int w,int h,int d);
public int getId(){
return this.id;
}
public abstract int setId();
public abstract void setBrand();
public abstract void getBrand( );
.....so on , still have a lot of characteristic of a cargo
}
//in the other class
public class usaCargo extends cargo{
....
private
}
So here is few Question about my design.
1.So in the real programming project world, are we actually doing like above? for me i think it's ok design, we meet the basic characteristic of cargo.
if we setup "private id" , then we actually can't use "id" this variable in any subclass because it's private, so is that mean every variable we defined in abstract class must be either public/ protected?
can someone give some suitable example so my cargo can implement some interface?
public interface registration{
public void lastWarrantyCheck();
}
But seems not suitable here...
we dont usually define variable inside interface, do we ??
I try to gain more sense on OOP . Forgive my long questions.
You would define variables in the Abstract class so that methods defined in the abstract class have variables to use. The scope of those variables depend on how you want concrete classes to access those variables:
private should be used when you want to force a concrete class to go through a getter or setter defined in the abstract class.
protected should be used when you want to give the concrete class direct access to the variable.
public should be used when you want the variable to be accessible by any class.
A reasonable interface that a Cargo object might implement could be Shippable as in how to move the cargo from a source to a destination. Some cargo may be shipped via freight train, some might be shippable by airplane, etc. It is up to the concrete class to implement Shippable and define just how that type of cargo would be shipped.
public interface Shippable {
public void ship();
}
Lastly a variable defined in an interface must be public static and final meaning it would be a constant variable.
Hope this clears it up for you!
Abstract classes can contain implementation, so they can have private variables and methods. Interfaces on the other hand cannot.
You can find some examples on how to implement interfaces here. However, I included how you would implement your registration example below.
public class Cargo implements Registration{
public void lastWarrantyCheck(){
System.out.println("Last warranty check");
}
}
Interface variables are possible, but they should only include constant declarations (variable declarations that are declared to be both static and final). More information about this can be found here.
Variables in an abstract class may be declared as protected, and they will only be available within it and any extending classes. Private variables are never accessible inside extending classes.
Interfaces provide a list of functions that are required by the classes that implement them. For example, you might use an interface hasWarranty to define all the functions that an object would need to handle warranty-related activities.
public interface hasWarranty {
public void lastWarrantyCheck();
public void checkWarranty();
}
Then, any objects that need to perform warranty-related activities should implement that interface:
// Disclaimer: been away from Java for a long time, so please interpret as pseudo-code.
// Will compile
public class Car implements hasWarranty {
public void lastWarrantyCheck() {
... need to have this exact function or program won't compile ...
}
public void checkWarranty() {
... need to have this exact function or program won't compile ...
}
}
// Missing one of the required functions defined in hasWarranty
public class Bus implements hasWarranty {
public void lastWarrantyCheck() {
... need to have this exact function or program won't compile ...
}
}
Only constants, really, as variables declared in an interface are immutable and are shared by all objects that implement that interface. They are implicitly "static final".