Failing to integrate proguard obfuscation with a micronaut service

Attempting to setup obfuscation for miconaut based micro service fails with this error:

io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [io.micronaut.context.event.ApplicationEventPublisher<io.micronaut.context.event.StartupEvent>] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).

but it starts up fine without obfuscation. our config setting are:

-keep class some.example.Application { *; }

-keep class !some.example.**,** { *; }
-keep interface !some.example.**,** { *; }

Preserve Micronaut classes

-keep class io.micronaut.**.** { *; }
-keep interface io.micronaut.**.** { *; }

-keep class io.micronaut.context.event.** { *; }
-keepclassmembers class * implements io.micronaut.context.event.** { *; }

Preserve Micronaut-specific classes and annotations

-keep @io.micronaut.context.annotation.* class * {*;}
-keep class * implements io.micronaut.context.BeanContext {*;}
-keep class * implements io.micronaut.context.BeanDefinitionRegistrar {*;}

Preserve other necessary classes

-keep class io.micronaut.context.env.DefaultPropertyPlaceholderResolver {*;}

# If using AOT (Ahead of Time) compilation, preserve related classes
-keep class io.micronaut.core.annotation.Generated.* {*;}

-keep class org.slf4j.** { *; }

Could you please provide some guidance as to how we go about resolving this?
Would it be possible to provide a demo of proguard obfuscation only working with a micronaut based app?

1 Like

@jonas.gijbels or @ewoutd Would you be able to help or give pointers please.

Dear @AliO,

First of all, welcome to our community and thanks for posting your question!

To further assist you, can you please share with us the full configuration you are handing to proguard & the full build log? If possible, a sample application that reproduces the issue would also help.

Kind regards,

Ewout

@ewoutd

Thank you for your response, I’ve uploaded the sample app into github:

If you attempt to build and obfuscate the jar and startup the service, then the controller beans are no longer registered via micronaut. but we’ve excluded any annotations from being obfuscated. so can you please help us in some way to continue to expose controller endpoints.

I’ve got it working to a point where the micronaut Controller annotations registers beans in the github repo above, but now I can’t get the jackson serializer working for a data class. Can you please help @ewoutd

Dear @AliO

Have you already checked out the following example in the ProGuard manual?

Processing bean classes

If your application, applet, servlet, library, etc., makes extensive use of introspection on bean classes to find bean editor classes, or getter and setter methods, then configuration may become painful. There’s not much else you can do than making sure the bean class names, or the getter and setter names don’t change. For instance:

-keep public class com.example.MyBean {
    public void setMyProperty(int);
    public int getMyProperty();
}

-keep public class com.example.MyBeanEditor

If there are too many elements to list explicitly, wildcards in class names and method signatures might be helpful. This example preserves all possible setters and getters in classes in the package mybeans:

-keep class mybeans.** {
    void set*(***);
    void set*(int, ***);

    boolean is*();
    boolean is*(int);

    *** get*();
    *** get*(int);
}

The ā€˜***’ wildcard matches any type (primitive or non-primitive, array or non-array). The methods with the ā€˜int’ arguments matches properties that are lists.

In addition, with regards to Jackson serialization, can you give us an example of a dataclass that misbehaves due to jackson serialization?

Kind regards,

Ewout

1 Like

As you can see from the same example github repo, I’m having a serialisation issue where the jackson deserializer for the various field definitions using @JsonProperty(ā€œsomefieldā€) annotation are not being honoured:

see following class: /main/kotlin/com/example/data/CoolDevice.kt

currently we get API response from the controller endpoint (/api/v1/hello) as:

{
"deviceId": "jZwx9rFyR7ffKg==",
"status": 123
}

But we should instead be getting below example, thats matching the Jackson JsonProperty annotation definitions:

{
"di": "[B@5db4aac2",
"st": 123
}

We’re not sure if this is being caused by the kotlin reflection exemption rules we’ve added. Can you please help.

Can you please help with the issue above with the jackson serializer not working due to obfuscation issues.