powered by Jive Software

Smack 4.4.0-alpha3 (20200404): causing problem in aTalk build with incompatible types for classes implementation of ExtensionElement

Upon upgraded aTalk to use smack-4.4.0-alpha3 release on 20200404, the aTalk project can logger be built under Android Studio (AS). The build throws incompatible types for all the aTalk classes implementation of the interface ExtensionElement.

Please see comments in Issue Tracker:
https://issuetracker.google.com/issues/153594531

The problem does not seems to relate to the AS release version nor the gradle versions.
The problem remains even I have downgraded the AS from 3.6.2 to 3.5.3 and also all the gradle tools versions.

It seems that AS is unable to relate aTalk classes implementation to its ExtensionElement interface defined in smack library. Eventually I have to extract both the below 2 files from smack-core library and placed them into the aTalk local project directory (using jarjar.repackage). Only then, AS is able to build aTalk project sucessfully i.e.
‘org.jivesoftware.smack.packet.stanza’ and ‘org.jivesoftware.smack.packet.stanzaView’

I have no idea which one is the cause of the problem i.e. AS or smack.
Note: there is no build problem with smack-4.4.0-alphas3 released on 20190916.

    jarjar.repackage {
        from("org.igniterealtime.smack:smack-core:$smackVersion") {
            transitive = false
        }
        destinationDir new File("${projectDir}/../aTalk/third_party/m2/org/igniterealtime/smack/smack-core-jarjar/${smackVersion}")
        destinationName "smack-core-jarjar-${smackVersion}.jar"

        // smack-core
        classDelete 'org.jivesoftware.smack.packet.stanza'
        classDelete 'org.jivesoftware.smack.packet.stanzaView'
        classDelete 'org.jivesoftware.smack.provider.AbstractProvider'
        classDelete 'org.jivesoftware.smack.util.StringUtils**'
        classDelete 'org.jivesoftware.smack.AbstractXMPPConnection**'
    },
====== Android Studio IDE reported build errors ============= 
> Task :aTalk:compileFdroidDebugJavaWithJavac
Gradle may disable incremental compilation as the following annotation processors are not incremental: jetified-butterknife-compiler-10.1.0.jar (com.jakewharton:butterknife-compiler:10.1.0).
Consider setting the experimental feature flag android.enableSeparateAnnotationProcessing=true in the gradle.properties file to run annotation processing in a separate task and make compilation incremental.
Note: [1] Wrote GeneratedAppGlideModule with: []
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java:780: error: incompatible types: ExtensionElement cannot be converted to TransferExtensionElement
                    = jingle.getExtension(TransferExtensionElement.ELEMENT, TransferExtensionElement.NAMESPACE);
                                         ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java:782: error: incompatible types: ExtensionElement cannot be converted to CallIdExtensionElement
                    = jingle.getExtension(CallIdExtensionElement.ELEMENT, CallIdExtensionElement.NAMESPACE);
                                         ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java:705: error: incompatible types: ExtensionElement cannot be converted to TransferExtensionElement
                    = jingle.getExtension(TransferExtensionElement.ELEMENT, TransferExtensionElement.NAMESPACE);
                                         ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/CallJabberImpl.java:734: error: incompatible types: ExtensionElement cannot be converted to CoinExtensionElement
        CoinExtensionElement coin = jingle.getExtension(CoinExtensionElement.ELEMENT, CoinExtensionElement.NAMESPACE);
                                                       ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java:297: error: incompatible types: ExtensionElement cannot be converted to JingleReason
                JingleReason reason = responseIQ.getExtension(JingleReason.ELEMENT, JingleReason.NAMESPACE);
                                                             ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/jivesoftware/smackx/httpauthorizationrequest/HTTPAuthorizationRequestManager.java:92: error: incompatible types: ExtensionElement cannot be converted to Body
            Message.Body bodyExt = message.getExtension(Message.Body.ELEMENT, Message.Body.NAMESPACE);
                                                       ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/jivesoftware/smackx/httpauthorizationrequest/element/ConfirmExtension.java:104: error: incompatible types: ExtensionElement cannot be converted to ConfirmExtension
        return message.getExtension(ELEMENT, NAMESPACE);
                                   ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java:948: error: incompatible types: ExtensionElement cannot be converted to DelayInformation
        DelayInformation delayInfo = msg.getExtension(DelayInformation.ELEMENT, DelayInformation.NAMESPACE);
                                                     ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java:781: error: incompatible types: ExtensionElement cannot be converted to DelayInformation
                = msg.getExtension(DelayInformation.ELEMENT, DelayInformation.NAMESPACE);
                                  ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java:2012: error: incompatible types: ExtensionElement cannot be converted to DelayInformation
            DelayInformation delayInfo = message.getExtension(DelayInformation.ELEMENT, DelayInformation.NAMESPACE);
                                                             ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java:2046: error: incompatible types: ExtensionElement cannot be converted to MultipleAddresses
            MultipleAddresses mAddress = message.getExtension(MultipleAddresses.ELEMENT, MultipleAddresses.NAMESPACE);
                                                             ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java:2733: error: incompatible types: ExtensionElement cannot be converted to MUCUser
            MUCUser mucUser = presence.getExtension(MUCUser.ELEMENT, MUCUser.NAMESPACE);
                                                   ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java:2830: error: incompatible types: ExtensionElement cannot be converted to Nick
            Nick nickExtension = presence.getExtension(Nick.ELEMENT_NAME, Nick.NAMESPACE);
                                                      ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java:2835: error: incompatible types: ExtensionElement cannot be converted to Email
            Email emailExtension = presence.getExtension(Email.ELEMENT_NAME, Email.NAMESPACE);
                                                        ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java:2840: error: incompatible types: ExtensionElement cannot be converted to AvatarUrl
            AvatarUrl avatarUrl = presence.getExtension(AvatarUrl.ELEMENT_NAME, AvatarUrl.NAMESPACE);
                                                       ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/net/java/sip/communicator/impl/protocol/jabber/ChatRoomJabberImpl.java:2845: error: incompatible types: ExtensionElement cannot be converted to StatsId
            StatsId statsId = presence.getExtension(StatsId.ELEMENT_NAME, StatsId.NAMESPACE);
                                                   ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/atalk/android/gui/chat/conference/CaptchaDialog.java:137: error: incompatible types: ExtensionElement cannot be converted to Body
        Body bodyExt = mMessage.getExtension(Body.ELEMENT, Body.NAMESPACE);
                                            ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/atalk/android/gui/chat/conference/CaptchaDialog.java:280: error: incompatible types: ExtensionElement cannot be converted to Captcha
            Captcha captcha = mMessage.getExtension(CaptchaIQ.ELEMENT, CaptchaIQ.NAMESPACE);
                                                   ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/atalk/android/gui/chat/conference/CaptchaDialog.java:288: error: incompatible types: ExtensionElement cannot be converted to BoBExt
            BoBExt bob = mMessage.getExtension(BoBExt.ELEMENT, BoBExt.NAMESPACE);
                                              ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/jivesoftware/smackx/avatar/vcardavatar/VCardAvatarManager.java:273: error: incompatible types: ExtensionElement cannot be converted to VCardTempXUpdate
        VCardTempXUpdate vCardXExtension = stanza.getExtension(ELEMENT, NAMESPACE);
                                                              ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java:540: error: incompatible types: ExtensionElement cannot be converted to DataPacketExtension
                    DataPacketExtension data = packet.getExtension(
                                                                  ^
/home/cmeng/workspace/android/atalk-android/aTalk/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java:595: error: incompatible types: ExtensionElement cannot be converted to DataPacketExtension
                data = packet.getExtension(
                                          ^
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
22 errors

> Task :aTalk:compileFdroidDebugJavaWithJavac FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':aTalk:compileFdroidDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2m 1s
22 actionable tasks: 20 executed, 2 up-to-date
1:50:04 PM: Task execution finished 'build'.

The return type of getExtension(String, String) changed. So you simply had to cast the return type.

But current master does contain a version of getExtension(String, String) with the original signature, while the method itself is marked as deprecated. Please use getExtension(Class) (when possible).

Yes, this is the very first thing I did, casting of the returned value to its implemented class also removed the Incompatible types errors.

Actually all this while, I have been placing the whole smack library source under AS IDE; when I upgraded the source to smack 4.4.0-alpha3 (20200404) release; I am still able to build all the smack libraries without problem. I notice that, within the smack source, it too makes call to getExtension(String, String); AS however does not throws Incompatible types on these statements.

After all the other failed attempts, eventually I found that the extraction of the two sources files (20200404) i.e. Stanza and StanzaView classes from smack-core.jar, and placed them in the aTalk local project directory seem to have satisfied AS build process. The StanzaView is also required as AS will throw errors if it is not included:

    @SuppressWarnings("unchecked")
    @Override
    public final <E extends ExtensionElement> E getExtension(QName qname) {
        synchronized (extensionElements) {
            return (E) extensionElements.getFirst(qname);
        }
    }

Personally I am not too familiar with the following declaration i.e.

public final PE getExtension(String elementName, String namespace){};

My understanding is that, the statement declares that the returned value PE of the getExtension() is an extension of the ExtensionElement parent. It is therefore when a class implements ExtensionElement, the IDE should not throw Incompatible types in getExtension(String, String); at least this is truth when placing the Stanza class in the aTalk project directory. My puzzle is why AS failed to refer to the same class method declaration when it is embedded within the smack-core.jar library.

=================================
The Stanza class file that I have extracted is from -alpha3 (20200404) release, it contains the following getExtensionElement declaration. By the way, there is no indication that the class method is deprecated; did I missed out something?

 /**
     * Returns the first extension that matches the specified element name and
     * namespace, or <code>null</code> if it doesn't exist. If the provided elementName is null,
     * only the namespace is matched. Extensions are
     * are arbitrary XML elements in standard XMPP stanzas.
     *
     * @param elementName the XML element name of the extension. (May be null)
     * @param namespace the XML element namespace of the extension.
     * @param <PE> type of the ExtensionElement.
     * @return the extension, or <code>null</code> if it doesn't exist.
     */
    @SuppressWarnings("unchecked")
    public final <PE extends ExtensionElement> PE getExtension(String elementName, String namespace) {
        if (namespace == null) {
            return null;
        }
        QName key = new QName(namespace, elementName);
        ExtensionElement packetExtension = getExtension(key);
        if (packetExtension == null) {
            return null;
        }
        return (PE) packetExtension;
    }

    @SuppressWarnings("unchecked")
    @Override
    public final <E extends ExtensionElement> E getExtension(QName qname) {
        synchronized (extensionElements) {
            return (E) extensionElements.getFirst(qname);
        }
    }

hello cmeng,
i followed and did all the script described above :
jarjar.repackage {
from(“org.igniterealtime.smack:smack-core:$smackVersion”) {
transitive = false
}
destinationDir new File("${projectDir}/…/aTalk/third_party/m2/org/igniterealtime/smack/smack-core-jarjar/${smackVersion}")
destinationName “smack-core-jarjar-${smackVersion}.jar”

    // smack-core
    classDelete 'org.jivesoftware.smack.packet.stanza'
    classDelete 'org.jivesoftware.smack.packet.stanzaView'
    classDelete 'org.jivesoftware.smack.provider.AbstractProvider'
    classDelete 'org.jivesoftware.smack.util.StringUtils**'
    classDelete 'org.jivesoftware.smack.AbstractXMPPConnection**'
},

but i still get a lot of build error messages like this:

error: incompatible types: ExtensionElement cannot be converted to VCardTempXUpdate
VCardTempXUpdate vCardXExtension = stanza.getExtension(ELEMENT, NAMESPACE);
do you have any ideas?

What I wrote above: add a cast.

You do not need to extract the two smack files i.e. Stanza and StanzaView if you cast the return value as proposed.