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
847 stars 158 forks source link

NoClassDefFoundError in Android 5-6 when built in Android Studio 4.2.1 #488

Closed aloz77 closed 2 years ago

aloz77 commented 3 years ago

Expected behavior

MQTT Client can init and connect with Android 5-6 devices

Actual behavior

The client is crashing in Android 5 and Android 6 with

java.lang.NoClassDefFoundError: com.hivemq.client.internal.mqtt.-$$Lambda$QT9XFB_2yV951PYVP80Cqx3qU9Q
    at com.hivemq.client.internal.mqtt.MqttRxClientBuilderBase.automaticReconnect(MqttRxClientBuilderBase.java:156)
    at com.hivemq.client.internal.mqtt.mqtt3.Mqtt3RxClientViewBuilder.automaticReconnect(Mqtt3RxClientViewBuilder.java:38)
    at com.mypackage.MqttHiveClient.<init>(MqttHiveClient.java:54)

No issues with newer Android versions or when built in Android Studio 4.1.x

To Reproduce

Run the app with following code

Reproducer code

                Mqtt3ClientBuilder mqtt3ClientBuilder = Mqtt3Client.builder()
                        .identifier(identifier)
                        .serverHost(host)
                        .serverPort(port)
                        .simpleAuth(Mqtt3SimpleAuth.builder()
                                .username(username)
                                .password(password.getBytes())
                                .build())
                        .automaticReconnect()
                        .initialDelay(10, TimeUnit.SECONDS)
                        .maxDelay(60, TimeUnit.SECONDS)
                        .applyAutomaticReconnect();

dependencies:

    implementation 'com.hivemq:hivemq-mqtt-client:1.2.2'
    implementation 'com.hivemq:hivemq-mqtt-client-websocket:1.2.2'
    implementation 'net.sourceforge.streamsupport:android-retrostreams:1.7.3'
    implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.3'

buildscript/dependencies:

        classpath 'com.android.tools.build:gradle:4.2.1'
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
        classpath 'gradle.plugin.com.github.sgtsilvio.gradle:android-retrofix:0.3.6'

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

SgtSilvio commented 3 years ago

Hi @aloz77 did you set the Java version to 1.8, so that lambdas are properly desugared?

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

(https://hivemq.github.io/hivemq-mqtt-client/docs/installation/android/)

aloz77 commented 3 years ago

Yes, of cause, JavaVersion.VERSION_1_8 is enabled as in your snippet above.

The issue was introduced by Android 4.2 IMHO.

SgtSilvio commented 3 years ago

Did you set?

android {
    compileOptions {
        coreLibraryDesugaringEnabled = true
    }
}

If not, what is the default value? Maybe it changed in the new version of the Android plugin.

I believe that this setting is not compatible with the android-retrofix plugin.

aloz77 commented 3 years ago

There was no coreLibraryDesugaringEnabled entry in my build.gradle. I tried coreLibraryDesugaringEnabled false but this didn't help either.

aloz77 commented 3 years ago

I tried to build with the old Gradle and Gradle Plugin and it works for Android 5 then.

classpath 'com.android.tools.build:gradle:4.1.3'

distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip

A fix for the latest Android Studio 4.2.1 would be great.

digrec commented 3 years ago

I have exactly the same issue, as aloz77 does, on:

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
java.lang.NoClassDefFoundError: com.hivemq.client.internal.mqtt.-$$Lambda$Df8yRNpuHjFWi4vVWQkOSvVrarE
    at com.hivemq.client.internal.mqtt.MqttClientTransportConfigImplBuilder.webSocketConfig(MqttClientTransportConfigImplBuilder.java:206)
    at com.hivemq.client.internal.mqtt.MqttRxClientBuilder.webSocketConfig(MqttRxClientBuilder.java:39)

The only workaround for me until now was downgrading AGP to 4.1.3. Maybe it has something to do with AGP 4.2.1 using Java 8 language level by default?

Disabling core lib desugaring doesn't help.

But enabling it, like this does help:

android {
    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
    ...
}

and the NoClassDefFoundError is gone on Android 6.

Is this now recommended solution when using HiveMQ client and AGP 4.2.1, even if I'm using only Kotlin in my project? Or RetroFix plugin needs a fix?

SgtSilvio commented 3 years ago

Hi @digrec The problem with coreLibraryDesugaring is, that Android still only supports a subset of the Java 8 libraries, for example a CompletableFuture backport is missing iirc. Imho the android-retrofix plugin needs an update to support the new android plugin which seems to have broken backwards compatibility.

volkansahin45 commented 3 years ago

Same problem. Downgrade AGP 4.1.3 fixed for now.

george-theocharis commented 3 years ago

Any progress on this maybe? It doesn't actually work in AGP 7 too. I opened a retrofix issue too before seeing this issue here.

codefluencer commented 3 years ago

Having the same problem, any other fixes apart from downgrading gradle ?

HarisHoulis commented 2 years ago

Any news on this? 🙏

SgtSilvio commented 2 years ago

@aloz77 @digrec @volkansahin45 @george-theocharis @codefluencer @HarisHoulis the new 0.4.0 release of android-retroffix (https://github.com/SgtSilvio/android-retrofix/releases/tag/v0.4.0) should work with Android Gradle Plugin 4.x and 7.x Please comment if it works now.

aloz77 commented 2 years ago

Yes, looks like working now. Tested with Android 6.

digrec commented 2 years ago

@SgtSilvio thanks for the fix, the original issue is now resolved. Tested on Android 6 and 7.

But one of our android apps is now failing to build with: Cause: module-info class is frozen

I reported the issue here https://github.com/SgtSilvio/android-retrofix/issues/11

Any suggestions?

SgtSilvio commented 2 years ago

@digrec should be fixed in the new version 0.4.1 (https://github.com/SgtSilvio/android-retrofix/releases/tag/v0.4.1)