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.

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.