Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does the client still build in Android studio? #561

Open
2 tasks done
spink4 opened this issue Feb 22, 2023 · 21 comments
Open
2 tasks done

Does the client still build in Android studio? #561

spink4 opened this issue Feb 22, 2023 · 21 comments
Labels

Comments

@spink4
Copy link

spink4 commented Feb 22, 2023

Checklist

❓ Question

I am really happy with your mqtt client as it works flawlessly in my use case (an android app). My problem comes when building a minified release version using R8/proguard in android studio. I followed the instructions for android here but I get multiple errors such as:

Unexpected reference to missing service class: META-INF/services/reactor.blockhound.integration.BlockHoundIntegration.

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())
Missing class io.netty.channel.epoll.EpollSocketChannel (referenced from: com.hivemq.client.internal.netty.NettyEventLoopProvider com.hivemq.client.internal.netty.NettyEventLoopProvider$EpollHolder.eventLoopProvider())
Missing class io.netty.handler.codec.http.FullHttpResponse (referenced from: void com.hivemq.client.internal.mqtt.handler.websocket.MqttWebsocketHandshakeHandler.channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object) and 1 other context)
Missing class io.netty.handler.codec.http.HttpClientCodec (referenced from: void com.hivemq.client.internal.mqtt.handler.websocket.MqttWebSocketInitializer.initChannel(io.netty.channel.Channel, com.hivemq.client.internal.mqtt.MqttClientConfig, com.hivemq.client.internal.mqtt.MqttWebSocketConfigImpl, java.util.function.Consumer, java.util.function.BiConsumer))

My proguard-rules.pro contains:

-keepclassmembernames class io.netty.** { *; }
-keepclassmembers class org.jctools.** { *; }

and the build.gradle has:

buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    packagingOptions {
        exclude 'META-INF/INDEX.LIST'
        exclude 'META-INF/io.netty.versions.properties'
    }

I've tried creating a new 'empty activity' project from android studio but I still get the same errors when building a minified release.
I understand android studio uses R8 rather than proguard now - could this have anything to do with it?

Thank you for your help.

Steve.

@SgtSilvio
Copy link
Member

Hi @spink4
Of course it should be possible to use proguard/R8 with the hivemq-mqtt-client.
There have been a lot of updates to the Android toolchain, so maybe you are right that this is related to R8.

Unexpected reference to missing service class: META-INF/services/reactor.blockhound.integration.BlockHoundIntegration.

This seems unrelated to the hivemq-mqtt-client.

Missing class io.netty.channel.epoll.Epoll (referenced from: com.hivemq.client.internal.netty.NettyEventLoopProvider

This should only be a warning, but maybe this changed.
Maybe a -dontwarn io.netty.channel.epoll.Epoll helps here.

To find out a proper fix, can you please add the full output of the minifiyReleaseWithR8 task to see if we are dealing with errors or warnings.

@spink4
Copy link
Author

spink4 commented Feb 22, 2023

Thanks for the prompt reply. From a new 'empty activity' project in Android studio, here is the full output:

> Task :app:minifyReleaseWithR8
AGPBI: {"kind":"warning","text":"Unexpected reference to missing service class: META-INF/services/reactor.blockhound.integration.BlockHoundIntegration.","sources":[{"file":"C:\\Users\\Steve\\AndroidStudioProjects\\MyApplication\\app\\build\\intermediates\\merged_java_res\\release\\base.jar"}],"tool":"R8"}
AGPBI: {"kind":"warning","text":"Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in C:\\Users\\Steve\\AndroidStudioProjects\\MyApplication\\app\\build\\outputs\\mapping\\release\\missing_rules.txt.\n","sources":[{}]}
AGPBI: {"kind":"warning","text":"Missing class org.apache.log4j.Level (referenced from: void io.netty.util.internal.logging.Log4JLogger.debug(java.lang.String) and 3 other contexts)\r\nMissing class org.apache.log4j.Logger (referenced from: org.apache.log4j.Logger io.netty.util.internal.logging.Log4JLogger.logger and 16 other contexts)\r\nMissing class org.apache.log4j.Priority (referenced from: void io.netty.util.internal.logging.Log4JLogger.debug(java.lang.String) and 11 other contexts)\r\nMissing class org.apache.logging.log4j.LogManager (referenced from: io.netty.util.internal.logging.InternalLogger io.netty.util.internal.logging.Log4J2LoggerFactory.newInstance(java.lang.String))\r\nMissing class org.apache.logging.log4j.Logger (referenced from: java.lang.Boolean io.netty.util.internal.logging.Log4J2Logger$1.run() and 2 other contexts)\r\nMissing class org.apache.logging.log4j.message.MessageFactory (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger))\r\nMissing class org.apache.logging.log4j.spi.ExtendedLogger (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger))\r\nMissing class org.apache.logging.log4j.spi.ExtendedLoggerWrapper (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger) and 1 other context)\r\nMissing class org.slf4j.ILoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean))\r\nMissing class org.slf4j.Logger (referenced from: org.slf4j.Logger io.netty.util.internal.logging.Slf4JLogger.logger and 16 other contexts)\r\nMissing class org.slf4j.LoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean) and 1 other context)\r\nMissing class org.slf4j.Marker (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.log(int, java.lang.String) and 2 other contexts)\r\nMissing class org.slf4j.helpers.FormattingTuple (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.debug(java.lang.String, java.lang.Object) and 6 other contexts)\r\nMissing class org.slf4j.helpers.MessageFormatter (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.debug(java.lang.String, java.lang.Object) and 5 other contexts)\r\nMissing class org.slf4j.helpers.NOPLoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean))\r\nMissing class org.slf4j.spi.LocationAwareLogger (referenced from: org.slf4j.spi.LocationAwareLogger io.netty.util.internal.logging.LocationAwareSlf4JLogger.logger and 9 other contexts)\r\nMissing class reactor.blockhound.integration.BlockHoundIntegration (referenced from: io.netty.util.internal.Hidden$NettyBlockHoundIntegration)","sources":[{}],"tool":"R8"}
Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in C:\Users\Steve\AndroidStudioProjects\MyApplication\app\build\outputs\mapping\release\missing_rules.txt.


Missing class org.apache.log4j.Level (referenced from: void io.netty.util.internal.logging.Log4JLogger.debug(java.lang.String) and 3 other contexts)
Missing class org.apache.log4j.Logger (referenced from: org.apache.log4j.Logger io.netty.util.internal.logging.Log4JLogger.logger and 16 other contexts)
Missing class org.apache.log4j.Priority (referenced from: void io.netty.util.internal.logging.Log4JLogger.debug(java.lang.String) and 11 other contexts)
Missing class org.apache.logging.log4j.LogManager (referenced from: io.netty.util.internal.logging.InternalLogger io.netty.util.internal.logging.Log4J2LoggerFactory.newInstance(java.lang.String))
Missing class org.apache.logging.log4j.Logger (referenced from: java.lang.Boolean io.netty.util.internal.logging.Log4J2Logger$1.run() and 2 other contexts)
Missing class org.apache.logging.log4j.message.MessageFactory (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger))
Missing class org.apache.logging.log4j.spi.ExtendedLogger (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger))
Missing class org.apache.logging.log4j.spi.ExtendedLoggerWrapper (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger) and 1 other context)
Missing class org.slf4j.ILoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean))
Missing class org.slf4j.Logger (referenced from: org.slf4j.Logger io.netty.util.internal.logging.Slf4JLogger.logger and 16 other contexts)
Missing class org.slf4j.LoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean) and 1 other context)
Missing class org.slf4j.Marker (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.log(int, java.lang.String) and 2 other contexts)
Missing class org.slf4j.helpers.FormattingTuple (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.debug(java.lang.String, java.lang.Object) and 6 other contexts)
Missing class org.slf4j.helpers.MessageFormatter (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.debug(java.lang.String, java.lang.Object) and 5 other contexts)
Missing class org.slf4j.helpers.NOPLoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean))
Missing class org.slf4j.spi.LocationAwareLogger (referenced from: org.slf4j.spi.LocationAwareLogger io.netty.util.internal.logging.LocationAwareSlf4JLogger.logger and 9 other contexts)
Missing class reactor.blockhound.integration.BlockHoundIntegration (referenced from: io.netty.util.internal.Hidden$NettyBlockHoundIntegration)

It does break my app if I include minify/proguard in the build process.

Thank you for taking a look at this.

Steve.

@SgtSilvio
Copy link
Member

Can you please add the content of the file C:\Users\Steve\AndroidStudioProjects\MyApplication\app\build\outputs\mapping\release\missing_rules.txt?
Does it work if you add those to your proguard-rules.pro configuration?

@spink4
Copy link
Author

spink4 commented Feb 24, 2023

Thanks for your reply. The missing_rules.txt contains:

# Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin.
-dontwarn reactor.blockhound.integration.BlockHoundIntegration

I added this rule to proguard-rules.txt and did a rebuild. This time around the missing_rules.txt file contained:

-dontwarn org.apache.log4j.Level
-dontwarn org.apache.log4j.Logger
-dontwarn org.apache.log4j.Priority
-dontwarn org.apache.logging.log4j.LogManager
-dontwarn org.apache.logging.log4j.Logger
-dontwarn org.apache.logging.log4j.message.MessageFactory
-dontwarn org.apache.logging.log4j.spi.ExtendedLogger
-dontwarn org.apache.logging.log4j.spi.ExtendedLoggerWrapper
-dontwarn org.slf4j.ILoggerFactory
-dontwarn org.slf4j.Logger
-dontwarn org.slf4j.LoggerFactory
-dontwarn org.slf4j.Marker
-dontwarn org.slf4j.helpers.FormattingTuple
-dontwarn org.slf4j.helpers.MessageFormatter
-dontwarn org.slf4j.helpers.NOPLoggerFactory
-dontwarn org.slf4j.spi.LocationAwareLogger

I added the lot and it does then build without any errors or warnings. It's an 'empty activity' android app so its hard to test.

If I do the same process on my app I end up with a proguard-rules.txt that looks like this:

-keepclassmembernames class io.netty.** { *; }
-keepclassmembers class org.jctools.** { *; }
-dontwarn reactor.blockhound.integration.BlockHoundIntegration
-dontwarn org.apache.log4j.Level
-dontwarn org.apache.log4j.Logger
-dontwarn org.apache.log4j.Priority
-dontwarn org.apache.logging.log4j.LogManager
-dontwarn org.apache.logging.log4j.Logger
-dontwarn org.apache.logging.log4j.message.MessageFactory
-dontwarn org.apache.logging.log4j.spi.ExtendedLogger
-dontwarn org.apache.logging.log4j.spi.ExtendedLoggerWrapper
-dontwarn org.slf4j.ILoggerFactory
-dontwarn org.slf4j.Logger
-dontwarn org.slf4j.LoggerFactory
-dontwarn org.slf4j.Marker
-dontwarn org.slf4j.helpers.FormattingTuple
-dontwarn org.slf4j.helpers.MessageFormatter
-dontwarn org.slf4j.helpers.NOPLoggerFactory
-dontwarn org.slf4j.spi.LocationAwareLogger
-dontwarn io.netty.channel.epoll.Epoll
-dontwarn io.netty.channel.epoll.EpollEventLoopGroup
-dontwarn io.netty.channel.epoll.EpollSocketChannel
-dontwarn io.netty.handler.codec.http.FullHttpResponse
-dontwarn io.netty.handler.codec.http.HttpClientCodec
-dontwarn io.netty.handler.codec.http.HttpHeaders
-dontwarn io.netty.handler.codec.http.HttpObjectAggregator
-dontwarn io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame
-dontwarn io.netty.handler.codec.http.websocketx.CloseWebSocketFrame
-dontwarn io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame
-dontwarn io.netty.handler.codec.http.websocketx.PingWebSocketFrame
-dontwarn io.netty.handler.codec.http.websocketx.PongWebSocketFrame
-dontwarn io.netty.handler.codec.http.websocketx.TextWebSocketFrame
-dontwarn io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker
-dontwarn io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory
-dontwarn io.netty.handler.codec.http.websocketx.WebSocketFrame
-dontwarn io.netty.handler.codec.http.websocketx.WebSocketHandshakeException
-dontwarn io.netty.handler.codec.http.websocketx.WebSocketVersion
-dontwarn io.netty.handler.proxy.HttpProxyHandler
-dontwarn io.netty.handler.proxy.ProxyHandler
-dontwarn io.netty.handler.proxy.Socks4ProxyHandler
-dontwarn io.netty.handler.proxy.Socks5ProxyHandler
-dontwarn io.netty.internal.tcnative.Buffer
-dontwarn io.netty.internal.tcnative.CertificateCallback
-dontwarn io.netty.internal.tcnative.CertificateVerifier
-dontwarn io.netty.internal.tcnative.Library
-dontwarn io.netty.internal.tcnative.SSL
-dontwarn io.netty.internal.tcnative.SSLContext
-dontwarn io.netty.internal.tcnative.SniHostNameMatcher
-dontwarn org.conscrypt.BufferAllocator
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.HandshakeListener
-dontwarn org.eclipse.jetty.alpn.ALPN$ClientProvider
-dontwarn org.eclipse.jetty.alpn.ALPN$Provider
-dontwarn org.eclipse.jetty.alpn.ALPN$ServerProvider
-dontwarn org.eclipse.jetty.alpn.ALPN
-dontwarn org.eclipse.jetty.npn.NextProtoNego$ClientProvider
-dontwarn org.eclipse.jetty.npn.NextProtoNego$Provider
-dontwarn org.eclipse.jetty.npn.NextProtoNego$ServerProvider
-dontwarn org.eclipse.jetty.npn.NextProtoNego

It does build without showing any of the warnings but unfortunately the app is still broken when I run it on a device. If I remove the minify step from the build process then it works beautifully.

Does that help? I'm really happy with the hive client because it's super stable so I would love to get this sorted..

Steve.

@SgtSilvio
Copy link
Member

I built an app that connects, publishes and disconnects when clicking a button and it works for me (only tested with an emulator and not a real device).
I get the same warnings as you, but these are only warnings and don't affect the functioning of the app.
So there needs to be a difference between our setups.
Can you share your "'empty activity' android app"?
Please also provide the following information

  • Gradle version
  • Android Gradle Plugin version
  • compileSdkVersion
  • minSdkVersion
  • targetSdkVersion
  • Android version of your test device

@spink4
Copy link
Author

spink4 commented Feb 25, 2023

Thanks so much for your effort on this.

My setup is:

  • Gradle version: 7.5
  • Android Gradle Plugin version: 7.4
  • compileSDKVersion: 33
  • minSdkVersion: 24
  • targetSdkVersion: 33

The purpose of the Android 'empty activity' project was really just to show the warnings that were being generated (in a clean environment), but I didn't take it any further than that.

My app makes an API call as soon as it starts and that breaks if the build includes the minify process. My app uses Retrofit2 for the API call so maybe that uses a library that mqtt also uses. I'm not sure.

I'm happy to share code with you but I guess it's best not to post it in a public forum. What do you suggest?

Thanks again for all your help, it's very much appreciated.

Steve.

@SgtSilvio
Copy link
Member

SgtSilvio commented Mar 1, 2023

I'm happy to share code with you but I guess it's best not to post it in a public forum. What do you suggest?

I think best would be if you could

  1. Create a private repository on GitHub
  2. Add the code that you want to share to that repository
  3. Share the repository with me via the repository settings > access

@spink4
Copy link
Author

spink4 commented Mar 2, 2023

Good idea. I will get this setup as soon as I can.

Steve.

@Devenom1
Copy link

I have the exact same issue

@Devenom1
Copy link

Devenom1 commented Apr 25, 2023

Is there any way to prioritise this issue? This is the only MQTT library that seemed to work with Android very well with Obfuscation and R8 and everything. It doesn't anymore with the latest Gradle Version (8.0.0) and Java 17

@SgtSilvio
Copy link
Member

Can you share a reproducer?
Also, do you use the android-retrofix plugin? If so, which version? Did you update to the latest version (0.5.0)?

@Devenom1
Copy link

Hi @SgtSilvio thanks for the quick reply.

Yes so I get an error similar to what @spink4 pasted above. I'm pasting it here again.

> Task :app:minifyReleaseWithR8
AGPBI: {"kind":"warning","text":"Unexpected reference to missing service class: META-INF/services/reactor.blockhound.integration.BlockHoundIntegration.","sources":[{"file":"C:\\Users\\Steve\\AndroidStudioProjects\\MyApplication\\app\\build\\intermediates\\merged_java_res\\release\\base.jar"}],"tool":"R8"}
AGPBI: {"kind":"warning","text":"Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in C:\\Users\\Steve\\AndroidStudioProjects\\MyApplication\\app\\build\\outputs\\mapping\\release\\missing_rules.txt.\n","sources":[{}]}
AGPBI: {"kind":"warning","text":"Missing class org.apache.log4j.Level (referenced from: void io.netty.util.internal.logging.Log4JLogger.debug(java.lang.String) and 3 other contexts)\r\nMissing class org.apache.log4j.Logger (referenced from: org.apache.log4j.Logger io.netty.util.internal.logging.Log4JLogger.logger and 16 other contexts)\r\nMissing class org.apache.log4j.Priority (referenced from: void io.netty.util.internal.logging.Log4JLogger.debug(java.lang.String) and 11 other contexts)\r\nMissing class org.apache.logging.log4j.LogManager (referenced from: io.netty.util.internal.logging.InternalLogger io.netty.util.internal.logging.Log4J2LoggerFactory.newInstance(java.lang.String))\r\nMissing class org.apache.logging.log4j.Logger (referenced from: java.lang.Boolean io.netty.util.internal.logging.Log4J2Logger$1.run() and 2 other contexts)\r\nMissing class org.apache.logging.log4j.message.MessageFactory (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger))\r\nMissing class org.apache.logging.log4j.spi.ExtendedLogger (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger))\r\nMissing class org.apache.logging.log4j.spi.ExtendedLoggerWrapper (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger) and 1 other context)\r\nMissing class org.slf4j.ILoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean))\r\nMissing class org.slf4j.Logger (referenced from: org.slf4j.Logger io.netty.util.internal.logging.Slf4JLogger.logger and 16 other contexts)\r\nMissing class org.slf4j.LoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean) and 1 other context)\r\nMissing class org.slf4j.Marker (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.log(int, java.lang.String) and 2 other contexts)\r\nMissing class org.slf4j.helpers.FormattingTuple (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.debug(java.lang.String, java.lang.Object) and 6 other contexts)\r\nMissing class org.slf4j.helpers.MessageFormatter (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.debug(java.lang.String, java.lang.Object) and 5 other contexts)\r\nMissing class org.slf4j.helpers.NOPLoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean))\r\nMissing class org.slf4j.spi.LocationAwareLogger (referenced from: org.slf4j.spi.LocationAwareLogger io.netty.util.internal.logging.LocationAwareSlf4JLogger.logger and 9 other contexts)\r\nMissing class reactor.blockhound.integration.BlockHoundIntegration (referenced from: io.netty.util.internal.Hidden$NettyBlockHoundIntegration)","sources":[{}],"tool":"R8"}
Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in C:\Users\Steve\AndroidStudioProjects\MyApplication\app\build\outputs\mapping\release\missing_rules.txt.


Missing class org.apache.log4j.Level (referenced from: void io.netty.util.internal.logging.Log4JLogger.debug(java.lang.String) and 3 other contexts)
Missing class org.apache.log4j.Logger (referenced from: org.apache.log4j.Logger io.netty.util.internal.logging.Log4JLogger.logger and 16 other contexts)
Missing class org.apache.log4j.Priority (referenced from: void io.netty.util.internal.logging.Log4JLogger.debug(java.lang.String) and 11 other contexts)
Missing class org.apache.logging.log4j.LogManager (referenced from: io.netty.util.internal.logging.InternalLogger io.netty.util.internal.logging.Log4J2LoggerFactory.newInstance(java.lang.String))
Missing class org.apache.logging.log4j.Logger (referenced from: java.lang.Boolean io.netty.util.internal.logging.Log4J2Logger$1.run() and 2 other contexts)
Missing class org.apache.logging.log4j.message.MessageFactory (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger))
Missing class org.apache.logging.log4j.spi.ExtendedLogger (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger))
Missing class org.apache.logging.log4j.spi.ExtendedLoggerWrapper (referenced from: void io.netty.util.internal.logging.Log4J2Logger.<init>(org.apache.logging.log4j.Logger) and 1 other context)
Missing class org.slf4j.ILoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean))
Missing class org.slf4j.Logger (referenced from: org.slf4j.Logger io.netty.util.internal.logging.Slf4JLogger.logger and 16 other contexts)
Missing class org.slf4j.LoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean) and 1 other context)
Missing class org.slf4j.Marker (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.log(int, java.lang.String) and 2 other contexts)
Missing class org.slf4j.helpers.FormattingTuple (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.debug(java.lang.String, java.lang.Object) and 6 other contexts)
Missing class org.slf4j.helpers.MessageFormatter (referenced from: void io.netty.util.internal.logging.LocationAwareSlf4JLogger.debug(java.lang.String, java.lang.Object) and 5 other contexts)
Missing class org.slf4j.helpers.NOPLoggerFactory (referenced from: void io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(boolean))
Missing class org.slf4j.spi.LocationAwareLogger (referenced from: org.slf4j.spi.LocationAwareLogger io.netty.util.internal.logging.LocationAwareSlf4JLogger.logger and 9 other contexts)
Missing class reactor.blockhound.integration.BlockHoundIntegration (referenced from: io.netty.util.internal.Hidden$NettyBlockHoundIntegration)

To reproduce this error just include the hivemq mqtt client in your android app. Make sure you have the latest gradle 8.0.0 or above because it uses R8 to minify by default. Upgrade Java from 1.8 to 17. And then try to build a release version of the android app with these enabled

minifyEnabled true
multiDexEnabled true
shrinkResources true

About android retrofix
This is what I have in my build.gradle at the app level. The plugin is commented so I think I'm not using it anymore

//apply plugin: 'com.github.sgtsilvio.gradle.android-retrofix'

...... other android stuff

buildscript {
    repositories {
        google()
        gradlePluginPortal()
    }
    dependencies {
        classpath 'gradle.plugin.com.github.sgtsilvio.gradle:android-retrofix:0.4.1'
    }
}

@SgtSilvio
Copy link
Member

Can you explain what problem you are facing? Does the app crash? The log lines that you showed are only warnings and no errors.

@Devenom1
Copy link

The app doesn't build in release mode. With the latest gradle version the log lines I showed are no longer warnings. They are errors. So I had to downgrade gradle to 7.4.1 and they became warnings again. But I need to use the latest version of gradle

@bddckr
Copy link

bddckr commented Apr 25, 2023

I'm using this awesome MQTT client without any issues on Android API levels 29+, building in the CLI with Gradle 8.1.1, Android Gradle Plugin 8.0.0 and Android Studio 2022.2.1 (all the latest versions at the time of writing this). The only gotcha is that you have to navigate Proguard rules a bit yourself, something that other libraries also tend to require. That said, libraries could ship with their own Proguard consumer rules these days, so a default could be offered that way.

The log output is pretty much telling you what to do exactly:

Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in C:\Users\Steve\AndroidStudioProjects\MyApplication\app\build\outputs\mapping\release\missing_rules.txt.

Whether simply ignoring the missing classes is a good idea must be decided by you, after evaluating what you use in detail yourself.

Perhaps we can figure out a good default that this library should ship with?

I'm currently only using the client and websocket modules from this project. Here's the working Proguard rules file I use for that:

# Default suggestions from the MQTT client, adjusted a bit by us.
# https://hivemq.github.io/hivemq-mqtt-client/docs/installation/android/
-keepclassmembernames class io.netty.** { *; }
-keepclassmembernames class org.jctools.** { *; }

# Our own additions, after testing a minified build at runtime.
-dontwarn io.netty.channel.epoll.Epoll
-dontwarn io.netty.channel.epoll.EpollEventLoopGroup
-dontwarn io.netty.channel.epoll.EpollSocketChannel
-dontwarn io.netty.handler.proxy.HttpProxyHandler
-dontwarn io.netty.handler.proxy.ProxyHandler
-dontwarn io.netty.handler.proxy.Socks4ProxyHandler
-dontwarn io.netty.handler.proxy.Socks5ProxyHandler
-dontwarn io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod
-dontwarn io.netty.internal.tcnative.AsyncTask
-dontwarn io.netty.internal.tcnative.Buffer
-dontwarn io.netty.internal.tcnative.CertificateCallback
-dontwarn io.netty.internal.tcnative.CertificateCompressionAlgo
-dontwarn io.netty.internal.tcnative.CertificateVerifier
-dontwarn io.netty.internal.tcnative.Library
-dontwarn io.netty.internal.tcnative.SSL
-dontwarn io.netty.internal.tcnative.SSLContext
-dontwarn io.netty.internal.tcnative.SSLPrivateKeyMethod
-dontwarn io.netty.internal.tcnative.SSLSessionCache
-dontwarn io.netty.internal.tcnative.SessionTicketKey
-dontwarn io.netty.internal.tcnative.SniHostNameMatcher
-dontwarn org.apache.log4j.Level
-dontwarn org.apache.log4j.Logger
-dontwarn org.apache.log4j.Priority
-dontwarn org.apache.logging.log4j.Level
-dontwarn org.apache.logging.log4j.LogManager
-dontwarn org.apache.logging.log4j.Logger
-dontwarn org.apache.logging.log4j.message.MessageFactory
-dontwarn org.apache.logging.log4j.spi.ExtendedLogger
-dontwarn org.apache.logging.log4j.spi.ExtendedLoggerWrapper
-dontwarn org.conscrypt.BufferAllocator
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.HandshakeListener
-dontwarn org.eclipse.jetty.alpn.ALPN$ClientProvider
-dontwarn org.eclipse.jetty.alpn.ALPN$Provider
-dontwarn org.eclipse.jetty.alpn.ALPN$ServerProvider
-dontwarn org.eclipse.jetty.alpn.ALPN
-dontwarn org.eclipse.jetty.npn.NextProtoNego$ClientProvider
-dontwarn org.eclipse.jetty.npn.NextProtoNego$Provider
-dontwarn org.eclipse.jetty.npn.NextProtoNego$ServerProvider
-dontwarn org.eclipse.jetty.npn.NextProtoNego
-dontwarn org.slf4j.ILoggerFactory
-dontwarn org.slf4j.Logger
-dontwarn org.slf4j.LoggerFactory
-dontwarn org.slf4j.Marker
-dontwarn org.slf4j.helpers.FormattingTuple
-dontwarn org.slf4j.helpers.MessageFormatter
-dontwarn org.slf4j.helpers.NOPLoggerFactory
-dontwarn org.slf4j.spi.LocationAwareLogger
-dontwarn reactor.blockhound.integration.BlockHoundIntegration

@Devenom1
Copy link

Hey @bddckr thanks for the reply. I tried adding the -dontwarn lines but when I built the minified version the library didn't seem to work. Disabling minify would get it working again. I don't remember the exact issue but adding the the -dontwarn lines wouldn't crash the app instead the HiveMQ functionality seemed to be broken.

I will give it another go in a few days. I'm caught up with another project.

Perhaps we can figure out a good default that this library should ship with?

And yes this would be great. And yes it would be great if this library could specify the default proguard rules.

Once again I really appreciate your in-depth reply. I will definitely give it another go.

@SgtSilvio
Copy link
Member

Perhaps we can figure out a good default that this library should ship with?

Agree that this would be the desired state, but all the warning rules originate from dependencies, mostly netty, so in a perfect world, these libraries should ship with good defaults. It would be a bigger effort to maintain them in this library. Also, different people could use different versions of netty.

@Devenom1
Copy link

Oh ok. That makes sense @SgtSilvio. Thanks! Hopefully the netty community will provide one soon.

@spink4
Copy link
Author

spink4 commented Apr 26, 2023

It does break my app if I build a minified version. I ended up not using minify in the build process (temporary solution!) but will try to find time to properly look at what is breaking and why.

@DonnyRozendal
Copy link

Any ideas on how to fix this guys? I'm stuck on Gradle wrapper 7.6.3 because version 8 still breaks minified release builds. This works for now, but whenever Android Studio Hedgehog releases in the next few weeks, this Gradle wrapper version won't be supported anymore. Source: https://developer.android.com/build/releases/gradle-plugin#api-level-support

@DonnyRozendal
Copy link

DonnyRozendal commented Dec 11, 2023

Slight correction: it seems Gradle 8 is not forced on Android Studio Hedgehog. However, you then can't safely apply API level 34, since Gradle 7 isn't tested on that API level. You get a lint error for this as well. However, it does compile for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants