hivemq / hivemq-mqtt-client

HiveMQ MQTT Client is an MQTT 5.0 and MQTT 3.1.1 compatible and feature-rich high-performance Java client library with different API flavours and backpressure support
https://hivemq.github.io/hivemq-mqtt-client/
Apache License 2.0
854 stars 158 forks source link

Missing class io.netty.channel.epoll.Epoll, com.aayushatharva.brotli4j. and other when compile Android Project #609

Open yuriisurzhykov opened 9 months ago

yuriisurzhykov commented 9 months ago

I'm trying to build an android application with using HiveMQ library. My project configurations are next:

Java - 17 Kotlin 1.9.20 Gradle - 8.4 Android Gradle Pluging - 8.1.4

For proguard configuration I have the following:

    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }

I have added the library as it described in the document: https://hivemq.github.io/hivemq-mqtt-client/docs/installation/android/ I put proguard rules as it described there, but the project still doesn't want to compile, and it gives me the message:

Missing class io.netty.channel.epoll.Epoll (referenced from: com.hivemq.client.internal.netty.NettyEventLoopProvider com.hivemq.client.internal.netty.NettyEventLoopProvider$EpollHolder.eventLoopProvider())
Missing class io.netty.channel.epoll.EpollEventLoopGroup (referenced from: com.hivemq.client.internal.netty.NettyEventLoopProvider com.hivemq.client.internal.netty.NettyEventLoopProvider$EpollHolder.eventLoopProvider())

And the whole huge list of usages.

After I got this error I modified the proguard-rules.pro file to the following:

-keep class io.netty.** { *; }
-keep class org.conscrypt.** { *; }
-keep class com.aayushatharva.** { *; }
-keep class com.aayushatharva.brotli4j.** { *; }
-keep class org.jctools.** { *; }

But it still gives me an error about missing sources:

Missing class com.aayushatharva.brotli4j.Brotli4jLoader (referenced from: void io.netty.handler.codec.compression.Brotli.<clinit>() and 2 other contexts)
Missing class com.aayushatharva.brotli4j.decoder.DecoderJNI$Status (referenced from: void io.netty.handler.codec.compression.BrotliDecoder$1.<clinit>() and 1 other context)
Missing class com.aayushatharva.brotli4j.decoder.DecoderJNI$Wrapper (referenced from: com.aayushatharva.brotli4j.decoder.DecoderJNI$Wrapper io.netty.handler.codec.compression.BrotliDecoder.decoder and 4 other contexts)
Missing class com.aayushatharva.brotli4j.encoder.BrotliEncoderChannel (referenced from: com.aayushatharva.brotli4j.encoder.BrotliEncoderChannel io.netty.handler.codec.compression.BrotliEncoder$Writer.brotliEncoderChannel and 3 other contexts)
Missing class com.aayushatharva.brotli4j.encoder.Encoder$Mode (referenced from: void io.netty.handler.codec.compression.BrotliOptions.<clinit>())
Missing class com.aayushatharva.brotli4j.encoder.Encoder$Parameters (referenced from: com.aayushatharva.brotli4j.encoder.Encoder$Parameters io.netty.handler.codec.compression.BrotliEncoder.parameters and 11 other contexts)
Missing class com.github.luben.zstd.Zstd (referenced from: io.netty.buffer.ByteBuf io.netty.handler.codec.compression.ZstdEncoder.allocateBuffer(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, boolean) and 1 other context)
Missing class com.google.protobuf.ExtensionRegistry (referenced from: void io.netty.handler.codec.protobuf.ProtobufDecoder.<init>(com.google.protobuf.MessageLite) and 1 other context)
Missing class com.google.protobuf.ExtensionRegistryLite (referenced from: com.google.protobuf.ExtensionRegistryLite io.netty.handler.codec.protobuf.ProtobufDecoder.extensionRegistry and 3 other contexts)
Missing class com.google.protobuf.MessageLite$Builder (referenced from: void io.netty.handler.codec.protobuf.ProtobufDecoder.decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List) and 1 other context)
Missing class com.google.protobuf.MessageLite (referenced from: com.google.protobuf.MessageLite io.netty.handler.codec.protobuf.ProtobufDecoder.prototype and 6 other contexts)
...

The list about missing sources is really big. I have tried to remove shrinkResources configuration, and the project still doesn't compile. I have tried to modify

-keep class io.netty.** { *; }
-keep class org.conscrypt.** { *; }

To:

-keep class io.netty.**
-keep class org.jctools.**

But nothing helps me, so what is your suggestions?

yuriisurzhykov commented 9 months ago

I've tried to add -dontwant flags for all packages for that I'm getting errors:

-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
-dontwarn com.aayushatharva.**
-dontwarn com.github.luben.**
-dontwarn com.google.protobuf.**
-dontwarn com.jcraft.**
-dontwarn com.ning.**
-dontwarn io.netty.**
-dontwarn net.jpountz.**
-dontwarn org.apache.log4j.**
-dontwarn org.jboss.log4j.**
-dontwarn org.slf4j.**
-dontwarn sun.security.**

I compiled, but then I get crash of my app, because of: Caused by: java.lang.IllegalArgumentException: Can't find '[toLeakAwareBuffer]' in io.netty.buffer.AbstractByteBufAllocator

yuriisurzhykov commented 9 months ago

✅Ok, I don't know if its correct way to solve the problem, I don't like it, but at least it works now ✅. So what I just did is beside of -dontwarn rules, I left and -keep rules for the same packages. So now the proguard-rules.pro file looks like this:

-keep class io.netty.** { *; }
-keep class org.jctools.** { *; }
-keep class org.conscrypt.** { *; }
-keep class org.bouncycastle.** { *; }
-keep class org.openjsse.** { *; }
-keep class com.aayushatharva.** { *; }
-keep class com.github.luben.** { *; }
-keep class com.google.protobuf.** { *; }
-keep class com.jcraft.** { *; }
-keep class com.ning.** { *; }
-keep class net.jpountz.** { *; }
-keep class org.apache.log4j.** { *; }
-keep class org.jboss.log4j.** { *; }
-keep class org.slf4j.** { *; }
-keep class sun.security.** { *; }

-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
-dontwarn com.aayushatharva.**
-dontwarn com.github.luben.**
-dontwarn com.google.protobuf.**
-dontwarn com.jcraft.**
-dontwarn com.ning.**
-dontwarn io.netty.**
-dontwarn net.jpountz.**
-dontwarn org.apache.log4j.**
-dontwarn org.jboss.log4j.**
-dontwarn org.slf4j.**
-dontwarn sun.security.**

As I said, I don't like this solution, and it would be really good at least, if you would provide consumer-rules.pro by your library, so that proguard be able to look at those consumer-rules.pro rules and keep all the sources required for your lib.

distinctdan commented 6 months ago

+1, this libary doesn't work with ProGuard and the rules in the docs don't work.