proguard+springboot plugin -> no classes in jar - proguard

I have to obfuscate lib and application. Lib - simple lib with two classes. Obfuscation done well. Application(with obfuscated lib in dependencies) builded with springboot plugin, works well.
When I try to obfuscate application jar I have got jar without *.classes of my app.
here is proguard conf:
-verbose
-dontwarn
-dontoptimize
-dontpreverify
-printmapping out.map
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keepdirectories
-keep class org.springframework.******* { *;}
-keep public class * extends RequestEntity { *;}
-keep public class * extends ResponseEntity { *;}
-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepnames class * implements java.io.Serializable {*; }
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
classes:
public class TestEntity {
private Integer fieldInt;
private String fieldStr
--cut--- (set* get*)
public class TestActions {
private TestEntity entity;
Gson gson = new Gson();
--cut---(set* get*)
import my.act.TestActions;
public class App {
public static void main(String[] args) {
TestActions testActions=new TestActions();
testActions.doPrintEntity();
}
}
out.map:
my.App -> my.App:
6:6:void <init>() -> <init>
8:10:void main(java.lang.String[]) -> main
org.springframework.boot.loader.ExecutableArchiveLauncher -> org.springframework.boot.loader.ExecutableArchiveLauncher:
org.springframework.boot.loader.archive.Archive archive -> archive
37:44:void <init>() -> <init>
--cut---
rows about spring...
and I have got test_app1.jar without my.App, only empty folder:
test_app1.jar\BOOT-INF\classes\my\
Any ideas? Help please...

If you use proguard maven plugin for a springboot application. Don't forget to add spring package plugin as well.

Related

How to keep method arguments names from obfuscation by ProGuard

For given class:
class KeepMe(val keepThisArgument: Int) {
fun keepMethod(keepThisArgument: Int) {
println(keepThisArgument)
}
}
and proguard configuration:
-keep class com.KeepMe { *; }
following code is produced by proguard:
public final class KeepMe {
private final int keepThisArgument;
public final void keepMethod(int paramInt) {
System.out.println(paramInt);
}
public final int getKeepThisArgument() {
return this.keepThisArgument;
}
public KeepMe(int paramInt) {
this.keepThisArgument = paramInt;
}
}
constructor and method argument names is changed from "keepThisArgument" to "paramInt". Is there a way to keep it from happening? I use net.sf.proguard gradle plugin, version 6.2.2.
Turns out there is separate configuration to keep all argument names in all classes that are kept from obfuscating:
-keepparameternames

Is there a way to keep Kotlin annotations only for public functions/members when obfuscating with proguard?

I am trying to obfuscate a library written in Kotlin using Proguard.
In the library I use default and named arguments. In order for these to work when including the obfuscated jar as a lib I need the flag -keepattributes RuntimeVisibleAnnotations in the Proguard file.
With this flag all private functions are no longer obfuscated, because the annotations for them contain the plain names. Is there a possibility to apply this flag only to public functions and members and to delete the annotations for private functions and members?
This is probably also connected to the fact that public members of an interface only work with the above-mentioned flag. Is there a solution that solves the problem with both the interface and the classes?
current Proguard file:
-dontwarn
-dontoptimize
-keepparameternames
-keepattributes Signature, InnerClasses, Exceptions
-keepattributes RuntimeVisibleAnnotations
-keep class custom.package.** {
!private <fields>;
!private <methods>;
}
-keep interface custom.package.** {
!private <fields>;
!private <methods>;
}
obfuscation result with this config:
public class ExampleClass {
private val clearNameAttr: kotlin.String /* compiled code */
private fun clearPrivateMethod (namedParam: kotlin.String) : kotlin.Boolean { /* compiled code */ }
public fun clearPublicMethod (namedParam: kotlin.String) : kotlin.Boolean { /* compiled code */ }
}
desired obfuscation result:
public class ExampleClass {
private String a
private boolean a (String var1) { /* compiled code */ }
public boolean clearPublicMethod (String namedParam) { /* compiled code */ }
}

How to get reference to static class of Java super class in Kotlin

I've got sample third party Java code:
public class ApiClass extends PackagePrivateClass {
}
abstract class PackagePrivateClass {
public static class StaticClass {
}
}
So only ApiClass and StaticClass are public. In Java I can get reference to StaticClass with: ApiClass.StaticClass. For the same code in Kotlin I got Unresolved reference: StaticClass. I can't also get reference via PackagePrivateClass, because it's package private (captain obvious). Is there any hack to get reference to StaticClass (it's third party code so I can't simply make PackagePrivateClass public)?
I understand that it's probably 'by design', however it forbids me from using 3p code
It seems the only solution is to build Java wrapper class that your kotlin class can access to.
public class ApiClass extends PackagePrivateClass {
}
abstract class PackagePrivateClass {
public static class StaticClass {
void instanceFunction() {
}
static void classFunction() {
}
}
}
The adapter java class (StaticClassAdapter.java):
class StaticClassAdapter {
private static ApiClass.StaticClass staticClass;
void instanceFunction() {
staticClass.instanceFunction();
}
static void classFunction() {
PackagePrivateClass.StaticClass.classFunction();
}
}
So in your kotlin code...
class KotlinClass {
fun main() {
StaticClassAdapter().instanceFunction()
StaticClassAdapter.classFunction()
}
}

Error generating signed APK due to proguard rules

Generating signed APK giving error after I updated Android Studio to 3.3-rc01 and enabled R8 code shrinking.
It is giving following proguard error :
Error: ~/app/proguard-rules.pro, offset: 2613, line: 74, column: 7, Expected char '-' at ~/app/proguard-rules.pro:74:7
-dump class_files.txt
before android studio 3.3-rc01 and without R8 code shrinking it was working perfectly fine.
Any workarounds for this or I have to disable the proguard rules now.
Following is my proguard-rules.pro file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# Retrofit does reflection on generic parameters and InnerClass is required to use Signature.
-keepattributes Signature, InnerClasses
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
#retrofit2.http.* <methods>;
}
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit
# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.-KotlinExtensions
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt dependency is available.
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-dontwarn javax.xml.stream.**
-dontwarn rx.internal.util.unsafe.**
#Glide proguard rules
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
-keep class android.support.v7.widget.LinearLayoutManager { *; }
-keep public class * extends android.support.v7.widget.RecyclerView$LayoutManager {
public <init>(...);
}
##---------------Begin: proguard configuration common for all Android apps ----------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-allowaccessmodification
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
-repackageclasses ''
-keep class com.qikcircle.qiketask.models.** { *; }
-keep class android.support.v4.** {*;}
-keep public class * extends android.app.Activity
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
public static <fields>;
}
# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public class * {
public protected *;
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
##---------------End: proguard configuration common for all Android apps ----------
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
# For using GSON #Expose annotation
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson ----------
#removing logs
-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(...);
}
#for getting crash reports
-assumenosideeffects class android.util.Log {
public static int v(...);
public static int d(...);
}
#Crashlytics proguard rules
-keepattributes SourceFile,LineNumberTable
-keep public class * extends java.lang.Exception
-ignorewarnings
-keep class * {
public private *;
}
I've tried the dump directive with Proguard (I didn't use it before) and all works fine.
[...]
## Strip Log.d
-assumenosideeffects class android.util.Log {
public static *** d(...);
}
-dump foo.txt
[...]
And I find my foo.txt under ./app/foo.txt
Printing classes to [./app/foo.txt]...
Then I enable R8 in legacy mode:
# For the bravests
android.enableR8=true
# For the crazyest. Must be enable also the previous setting
#android.enableR8.fullMode=true
And I got your error.
Without this line I can compile my APK even in full mode without any (apparent) issue.
So I confirm that this directive is not supported. Remember that R8 is still in beta. If you want you can submit an issue on the link I posted in comment.
Opened the issue here.
for me i had to remove the first line " public private *; " in my prograuard.pro file

Arquillian with Mockito and CDI

Is it possible to create spy(mock) object in testing class?
Here is tested class.
#Stateless
#Slf4j
public class UserDao {
#Inject
private TestBean testBean;
public String mock() {
return testBean.mock();
}
public String notMock() {
return testBean.notMock();
}
}
TestBean code
#Stateless
#Slf4j
public class TestBean {
public String notMock() {
return "NOT MOCK";
}
public String mock() {
return "IMPLEMENTED MOCK";
}
}
Here's my test
#RunWith(Arquillian.class)
public class UserDataTest {
#Rule
public ExpectedException thrown = ExpectedException.none();
#Inject
private UserDao userDao;
#Deployment
protected static Archive createWar() {
File[] dependencies = Maven.configureResolver()
.withRemoteRepo("nexus-remote", "http://maven.wideup.net/nexus/content/groups/public/", "default")
.withRemoteRepo("nexus-release", "http://maven.wideup.net/nexus/content/repositories/releases/", "default")
.resolve(
"org.slf4j:slf4j-simple:1.7.7",
"eu.bitwalker:UserAgentUtils:1.15",
"org.mockito:mockito-all:1.10.8"
).withoutTransitivity().asFile();
return ShrinkWrap
.create(WebArchive.class, "pass.jpa.war")
.addAsWebInfResource("jbossas-ds.xml")
.addAsWebInfResource("jboss-deployment-structure.xml")
.addAsLibraries(
PassApiDeployments.createDefaultDeployment(),
PassUtilLibrary.createDefaultDeployment(),
PassJpaDeployments.createDefaultDeployment()
).addAsLibraries(dependencies);
}
#Test
public void testMock() {
assertEquals("MOCK", userDao.mock());
}
#Test
public void testNotMock() {
assertEquals("NOT MOCK", userDao.notMock());
}
}
I'd like to create a spy object on TestBean to change result on method test() of this bean.
So is it possible to create TestBean spy in UserDao.
I solve some problems through producer like this.
#Singleton
public class MockFactory {
#Produces
#ArquillianAlternative
public TestBean getTestBean() {
return when(mock(TestBean.class).mock()).thenReturn("MOCK").getMock();
}
}
But in this example I need create on Bean completely on my own. And if it is bean with additional dependencies and thus i will manage all dependencies.
As far as I know, its not possible to use a mocking framework in combination with arquillian ...
I haven't used it myself, but this Arquillian extension seems to be specifically designed to support Mockito Spy objects in an Arquillian test: https://github.com/topikachu/arquillian-extension-mockito/