powered by Jive Software

Smack 4.4.0: aTalk implementation of Extension Element Provider classes are being rejected by AbstractProvider.java

I have just upgraded to use smack-4.4.0 official release for aTalk.
See that there is some changes in the AbstractProvider.java; but it is still no working for aTalk as reported in:

Below is the aTalk debug.log

2020-12-14 12:11:13.704 7370-30976/org.atalk.android E/AndroidRuntime: FATAL EXCEPTION: AccountManager.loadStoredAccounts
    Process: org.atalk.android, PID: 7370
    java.lang.AssertionError: Element type 'EE' is neither of type Class or ParameterizedType
        at org.jivesoftware.smack.provider.AbstractProvider.<init>(AbstractProvider.java:46)
        at org.jivesoftware.smack.provider.Provider.<init>(Provider.java:40)
        at org.jivesoftware.smack.provider.ExtensionElementProvider.<init>(ExtensionElementProvider.java:29)
        at org.xmpp.extensions.DefaultExtensionElementProvider.<init>(DefaultExtensionElementProvider.java:43)
        at org.xmpp.extensions.coin.CoinIQProvider.<init>(CoinIQProvider.java:46)
        at net.java.sip.communicator.impl.protocol.jabber.ProtocolProviderServiceJabberImpl.initialize(ProtocolProviderServiceJabberImpl.java:2091)
        at net.java.sip.communicator.impl.protocol.jabber.ProtocolProviderFactoryJabberImpl.createService(ProtocolProviderFactoryJabberImpl.java:121)
        at net.java.sip.communicator.service.protocol.ProtocolProviderFactory.loadAccount(ProtocolProviderFactory.java:934)
        at net.java.sip.communicator.service.protocol.AccountManager.doLoadStoredAccounts(AccountManager.java:139)
        at net.java.sip.communicator.service.protocol.AccountManager.loadStoredAccounts(AccountManager.java:294)
        at net.java.sip.communicator.service.protocol.AccountManager.runInLoadStoredAccountsThread(AccountManager.java:394)
        at net.java.sip.communicator.service.protocol.AccountManager.access$000(AccountManager.java:36)
        at net.java.sip.communicator.service.protocol.AccountManager$1.run(AccountManager.java:329)

I am not sure by maybe try to not use the diamond operator here but actually specify the type:

Actually it does not help; if I replace the <> with the following statement i.e.:

    private final DefaultExtensionElementProvider<URIsExtension> urisProvider
            = new DefaultExtensionElementProvider<URIsExtension>(URIsExtension.class);

The code inspector will indicate it is redundant:

Explicit type argument URIsExtension can be replaced with <> 
Inspection info: Reports all new expressions with type arguments which can be replaced with diamond type <>
Such <> syntax is not supported under Java 1.6 or earlier JVMs.

In order for AbstractProvider to accept aTalk extension elements, I need to change its code to below:
i.e. to include an additional else statement. Not sure if smack team will consider to include this additional in smack in future release.

           // required by aTalk class otherwise elementType is only resolved to <EE>
            elementClass =  (Class<E>)  elementType.getClass();
public class AbstractProvider<E extends Element> {

    private final Class<E> elementClass;

    @SuppressWarnings("unchecked")
    protected AbstractProvider() {
        Type currentType = getClass().getGenericSuperclass();
        while (!(currentType instanceof ParameterizedType)) {
            Class<?> currentClass = (Class<?>) currentType;
            currentType = currentClass.getGenericSuperclass();
        }
        ParameterizedType parameterizedGenericSuperclass = (ParameterizedType) currentType;
        Type[] actualTypeArguments = parameterizedGenericSuperclass.getActualTypeArguments();
        Type elementType = actualTypeArguments[0];

        if (elementType instanceof Class) {
            elementClass = (Class<E>) elementType;
        } else if (elementType instanceof ParameterizedType) {
            ParameterizedType parameteriezedElementType = (ParameterizedType) elementType;
            elementClass = (Class<E>) parameteriezedElementType.getRawType();
        } else {
            // required by aTalk class otherwise elementType is only resolved to <EE>
            elementClass =  (Class<E>)  elementType.getClass();
//            throw new AssertionError(
//                    "Element type '" + elementType + "' is neither of type Class or ParameterizedType");
        }
    }

    public final Class<E> getElementClass() {
        return elementClass;
    }
}

Interesting, could you tell me the type of elementType in that case? Ideally we use this type as additional else if (element instanceof X) case, and I need to now what X should be in this case.

From break point displayed info, it shows it is a “libcore.reflect.TypeVariableImpl”; Changing to the following, then it also works.

    protected AbstractProvider() {
        Type currentType = getClass().getGenericSuperclass();
        while (!(currentType instanceof ParameterizedType)) {
            Class<?> currentClass = (Class<?>) currentType;
            currentType = currentClass.getGenericSuperclass();
        }
        ParameterizedType parameterizedGenericSuperclass = (ParameterizedType) currentType;
        Type[] actualTypeArguments = parameterizedGenericSuperclass.getActualTypeArguments();
        Type elementType = actualTypeArguments[0];

        if (elementType instanceof Class) {
            elementClass = (Class<E>) elementType;
        } else if (elementType instanceof ParameterizedType) {
            ParameterizedType parameteriezedElementType = (ParameterizedType) elementType;
            elementClass = (Class<E>) parameteriezedElementType.getRawType();
        } else if (elementType instanceof TypeVariable) {
            // required by aTalk class otherwise elementType is only resolved to <EE>
            elementClass =  (Class<E>)  elementType.getClass();
        } else {
            throw new AssertionError(
                   "Element type '" + elementType + "' is neither of type Class or ParameterizedType");
        }
    }

Created SMACK-898

I have also pushed a commit to my abstract-provider-element-type branch:

could you try this change and report back if this fixes the issue for you?

Yes, tested the new change, it is working. Thanks.