Proguard keep option to handle OSGi declarative service - osgi

What is the keep option to use for OSGi declarative service to obfuscate with Proguard
Referring to the example below, I need to keep the DS relevant functions without Proguard removes it, because it cant find the reference
#Component
public class RandomApp {
private RandomGenApi randomGenApi;
#Reference
public void setRandomGenService(RandomGenApi randomGenApi) {
this.randomGenApi = randomGenApi;
}
#Activate
void startRandomApp() {
System.out.println("Startig RandomApp...");
}

I could achieve this by defining the OSGi services as the entry points.
Here is the keep options to be defined
#Keep annotations.
-keepattributes *Annotation*
#Keep all Component classes
-keep #org.osgi.service.component.annotations.Component class *
#Kepp all Component classes member functions with OSGi specific annotations
-keepclassmembers #org.osgi.service.component.annotations.Component class * {
#Keep all methods with annotatios Reference.
#org.osgi.service.component.annotations.Reference *;
#Keep all methods with annotatios Activate.
#org.osgi.service.component.annotations.Activate *;
}

Related

How to annotate JMX beans with OSGi native annotations?

I have a JMX bean which is running on felix scr annotations (AEM 6.4.8, Java 8) and would like to refactor it so it uses OSGi annotations instead. Basically, it's pretty clear what to do, there is only one tiny little "=" that I guess needs to be escaped?
The old code looks like this:
#Component(immediate=true)
#Property(name="jmx.objectname", value={"com.mypackage.monitoring:type=HierarchyModificationListenerMbean"})
#Service
public class HierarchyModificationListenerMbeanImpl
extends AnnotatedStandardMBean
implements ListenerStats {
The refactored code would then be:
#Component(immediate=true, service = ListenerStats.class, property = {"jmx.objectname=com.mypackage.monitoring:type=HierarchyModificationListenerMbean"})
public class HierarchyModificationListenerMbeanImpl
extends AnnotatedStandardMBean
implements ListenerStats {
I am not sure how to deal with the ":type=" in this case.
Any ideas?
take a look at this page https://aem.redquark.org/2018/10/day-16-creating-jmx-mbeans-in-aem.html it looks like the property definition you have should do the trick
your code looks good to me. only thing is, do you have an interface HierarchyModificationListenerMbean? your implementation class should declare that it implements such interface
Example:
public interface MyMBean {
}
#Component(service = DynamicMBean.class, property = {
"jmx.objectname=com.yourproject.osgi:type=MyMBean"
})
public class MyMBeanImpl extends AnnotatedStandardMBean implements MyMBean {
public MyMBeanImpl() {
super(MyMBean.class)
}
}

How to keep enums working with proguard enabled?

I have developed an android application that uses Enums in many modules. Now i am trying to protect my application from reverse engineering, for this purpose i have enabled proguard in my application but the issue is after enabling proguard my application crashes wherever i have used Enums.
I have created the following class to define all enums
package app.mypackagename.utils;
import android.content.Context;
public class EnumUtils {
public static enum AppDomain {
LIVE, STAGING, MOCK
}
public static enum UserRole {
CUSTOMER, ADMIN;
}
public static enum Module {
REGISTRATION, PRODUCT
}
}
Enum "UserRole" is being used inside a model class "User"
package app.mypackagename.flavors.models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import app.mypackagename.utils.EnumUtils;
public class User {
#SerializedName("sulLevelcode")
public String sulLevelcode;
public EnumUtils.UserRole userRole = null;
}
On successful login i am checking the user role using following code
Gson gson = new Gson();
Type listType = new TypeToken<User>() {
}.getType();
onlineUser = ((User) gson.fromJson(taskItem.getRawResponse(),
listType));
onlineUser.userID = userId;
if (onlineUser.sulLevelcode.equalsIgnoreCase(Constants.LEVEL_CODE_CUSTOMER)) {
onlineUser.userRole = EnumUtils.UserRole.CUSTOMER;
}
But applications always crashes on accessing Enum value.
Below is the crash trace
java.lang.AssertionError: java.lang.NoSuchFieldException: CUSTOMER
at b.b.c.b.a.ja$a.<init>(:808)
at b.b.c.b.a.V.a(:834)
at b.b.c.p.a(:423)
at b.b.c.b.a.p.a(:115)
at b.b.c.b.a.p.a(:164)
at b.b.c.b.a.p.a(:100)
at b.b.c.p.a(:423)
at b.b.c.p.a(:886)
at b.b.c.p.a(:852)
at b.b.c.p.a(:801)
at app.mypackagename.activities.k.a(:355)
at app.mypackagename.f.c.a(:442)
at app.mypackagename.f.c.a(:43)
at app.mypackagename.f.b.a(:288)
at app.mypackagename.f.b.a(:271)
at b.c.a.b.m.c(:107)
at b.c.a.b.m.b(:141)
at b.c.a.b.m.a(:128)
at b.c.b.A.a(:456)
at b.c.a.b.m.c(:107)
at b.c.a.b.m.b(:141)
at b.c.a.b.m.a(:128)
at b.c.b.r.run(:246)
at b.c.a.y$d.run(:60)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6577)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)
Caused by: java.lang.NoSuchFieldException: CUSTOMER
at java.lang.Class.getField(Class.java:1549)
at b.b.c.b.a.ja$a.<init>(:797)
at b.b.c.b.a.V.a(:834) 
at b.b.c.p.a(:423) 
at b.b.c.b.a.p.a(:115) 
at b.b.c.b.a.p.a(:164) 
at b.b.c.b.a.p.a(:100) 
at b.b.c.p.a(:423) 
at b.b.c.p.a(:886) 
at b.b.c.p.a(:852) 
at b.b.c.p.a(:801) 
at app.mypackagename.activities.k.a(:355) 
at app.mypackagename.f.c.a(:442) 
at app.mypackagename.f.c.a(:43) 
at app.mypackagename.f.b.a(:288) 
at app.mypackagename.f.b.a(:271) 
at b.c.a.b.m.c(:107) 
at b.c.a.b.m.b(:141) 
at b.c.a.b.m.a(:128) 
at b.c.b.A.a(:456) 
at b.c.a.b.m.c(:107) 
at b.c.a.b.m.b(:141) 
at b.c.a.b.m.a(:128) 
at b.c.b.r.run(:246) 
at b.c.a.y$d.run(:60) 
at android.os.Handler.handleCallback(Handler.java:761) 
at android.os.Handler.dispatchMessage(Handler.java:98) 
at android.os.Looper.loop(Looper.java:156) 
at android.app.ActivityThread.main(ActivityThread.java:6577) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)  
Below is my proguard rules 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
-dontwarn com.alcorlink.**
-dontwarn com.google.android.**
-dontwarn androidx.media.**
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class app.app.mypackagename.utils.EnumUtils { *; }
##---------------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.
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class app.mypackagename.flavors.models.User.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in #JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
#com.google.gson.annotations.SerializedName <fields>;
}
##---------------End: proguard configuration for Gson ----------
I have tried almost every solution available on Stack Overflow but i am unable to solve this issue.
Some from the ways i tried
--keep class app.mypackagename.utils.EnumUtils{ *; }
-keep class app.mypackagename.flavors.models.User.** { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers enum * { *; }
-keepclassmembers enum app.mypackagename.** { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public enum app.mypackagename.utils.EnumUtils** {
**[] $VALUES;
public *;
}
-keepattributes AppDomain
-keepattributes UserRole
Can somebody please help me out with this. Any help will be appreciated.
I had the same issue, but adding this line to my proguard-rules.pro worked -
-keep class app.mypackagename.constants.* { <fields>; }.
where "app.mypackagename.constants" is the package where all my enums are located.

BrightCove Video Player not working on Android

java.lang.RuntimeException: A Component requires the 'com.brightcove.player.event.Emits' annotation. If you wish to not listen or emit, create the corresponding annotation with an empty events list.
Has any one else face the same issue??
any help will be appreciable.
It sounds like you do not have the annotation
#Emits(events = {})
before your class declaration. If you show us the relevant fragment it might be obvious to someone what the problem is. A component that emits no events and listens for no events would look like,
/**
* Provides a Component object that is not very useful.
*/
#Emits(events = {})
#ListensFor(events = {})
public class NotVeryUsefulComponent extends AbstractComponent {
}
Please update the proguard with the following lines
-keep public class com.brightcove.player.** { public *;}
-keepclassmembers public class com.brightcove.player.** { public *;}
-keepclasseswithmembers public class com.brightcove.player.** { public *;}
-keep class com.google.android.exoplayer.** { *;}
If you are not using the exoplayer, omit the last line
Your proguard configuration is stripping out the annotations. As an example, please see the proguard-project.txt in our samples repo:
https://github.com/BrightcoveOS/android-player-samples/blob/master/proguard-project.txt

Can the Parse jar be reduced to have fewer methods?

Because of the Android 64k max method limit, I'm trying to reduce the number of methods provided by the Parse Android SDK. Parse-1.5.0.jar has some 4,500+ methods. Any suggestions?
Removing the SDK and using the REST APIs is a possibility, but may be somewhat time consuming.
Try using ProGuard and leave out the idea of using REST APIs... Honestly I never heard about such a workaround for such a problem 0_o
Just tell ProGuard to shrink your code, skipping additional features like obuscation if you don't want to slow down the deploy. The proguard-project.txt file will be more or less like this:
-dontoptimize
-dontobfuscate
-allowaccessmodification
-dontpreverify
# The remainder of this file is identical to the non-optimized version
# of the Proguard configuration file (except that the other file has
# flags to turn off optimization).
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.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.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-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);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# The support library 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.
-dontwarn android.support.**

Inject #Parameter in different class in maven plugin

I am writing a maven plugin and based on my previous experience i know that my mojo class will end up with a bunch of #Parameters to configure it. What I would like to do is instead of having those configuration parameters injected in the mojo class, I would like to have them injected in a second, configuration-only class. Is this possible?
The current way I do it is the mojo class just constructs a Configuration object where it passes all the injected parameters. Something like this
#Mojo
public class MyMojo extends AbstractMojo {
private MyConfig myConfig;
#Parameter
private String myArg1;
...
public void execute() {
myConfig = new MyConfig(myArg1, myArg2, ...);
}
}
But this is rather ugly. I want the DI to happen directly in Config
If MyConfig is a pojo, you can use the #Parameter here as well, However, you config will look like:
<configuration>
<myConfig>
<someField>value</someField>
</myConfig>
</configuration>
The second trick is to use setters, because an #Parameter-annotated field will use the matching public setter, if there is one.
private MyConfig myConfig = new MyConfig();
#Parameter
private String someField;
// matching setter for #parameter-annotated field
public void setSomeField( String field )
{
myConfig.setSomeField( field );
}
You can use your MyConfig POJO as #Parameter:
#Mojo
public class MyMojo extends AbstractMojo {
#Parameter
private MyConfig myConfig;
...
}
The rules for mapping complex objects are as follows:
There must be a private field that corresponds to name of the element being mapped. So in our case the person element must map to a person field in the mojo.
The object instantiated must be in the same package as the Mojo itself. So if your mojo is in com.mycompany.mojo.query then the mapping mechanism will look in that package for an object named Person. As you can see the mechanism will capitalize the first letter of the element name and use that to search for the object to instantiate.
Source
However, using the #Parameter for fields of MyConfig has no effect, see this thread.

Resources