question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

At Android both FstCodec and MarshallingCodec don't run

See original GitHub issue

Using this simple code at android (java):

`

private RList<MyObject> connect(String address) {

    Config config = new Config();

    config.useSingleServer().setAddress(address);

    RedissonClient client = Redisson.create(config);

    return client.getList("Section::Unit"); }

`

I get this IllegalStateException:

Caused by: java.lang.IllegalStateException: java.lang.reflect.InvocationTargetException at org.redisson.command.RedisExecutor.getCodec(RedisExecutor.java:692) at org.redisson.command.RedisExecutor.execute(RedisExecutor.java:113) at org.redisson.command.CommandAsyncService.async(CommandAsyncService.java:612) at org.redisson.command.CommandAsyncService.readAsync(CommandAsyncService.java:369) at org.redisson.RedissonList.getAsync(RedissonList.java:296) at org.redisson.RedissonList.getValue(RedissonList.java:325) at org.redisson.RedissonList$1.getValue(RedissonList.java:500)

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Class.isPrimitive()' on a null object reference at org.objenesis.ObjenesisBase.getInstantiatorOf(ObjenesisBase.java:86) at org.nustaq.serialization.FSTObjenesisInstantiator.<init>(FSTObjenesisInstantiator.java:38) at org.nustaq.serialization.FSTConfiguration$4.getInstantiator(FSTConfiguration.java:403) at org.redisson.codec.FstCodec.copy(FstCodec.java:200)

Looking inside code I found that this function (file FstCodec.java):

` package org.redisson.codec;

public FstCodec(ClassLoader classLoader, FstCodec codec) {
    this(copy(classLoader, codec));
}

` … call private copy function and this one call def.setInstantiator(codec.config.getInstantiator(null)).

The problem is, at android, FstCodec call this function: ` package org.nustaq.serialization;

 protected static FSTConfiguration createAndroidDefaultConfiguration(ConcurrentHashMap<FieldKey,FSTClazzInfo.FSTFieldInfo> shared) {
    final Objenesis genesis = new ObjenesisStd();
    FSTConfiguration conf = new FSTConfiguration(shared) {
        @Override
        public FSTClassInstantiator getInstantiator(Class clazz) {
            return new FSTObjenesisInstantiator(genesis,clazz);
        }
    };

` … that override default getInstantiator(class class2instantiate) that must not receive parameter as null.

I’m using: implementation ‘de.ruedigermoeller:fst:2.57’ implementation ‘org.redisson:redisson:3.12.5’ at gradle dependency and redis 6.0.3 version running at docker. android compileSdkVersion 29 (android 10.0 Q)

Thanks for this incredible program, I holpe that this help you to improve it.

hipolito

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
hcarrarocommented, May 27, 2020

Thank you by your attention and help! Sorry by the long time to answer… I’ve run tests with both redisson versions 3.12.5 and 3.13.0 and found the same error. At both MarshallingCodec doesn’t run at android.

I’d like help you fix that and find the error location at android. Let me show you:

Running this simple code:

private RList<MyObject> connect(String address) {
    Config config = new Config();
    config.useSingleServer().setAddress(address);
    RedissonClient client = Redisson.create(config);
    return client.getList("Section::Unit", new MarshallingCodec()); 
}

I got this error:

java.util.ServiceConfigurationError: org.jboss.marshalling.ProviderDescriptor: Provider org.jboss.marshalling.river.RiverProviderDescriptor could not be instantiated
    at java.util.ServiceLoader.fail(ServiceLoader.java:233)
    at java.util.ServiceLoader.access$100(ServiceLoader.java:183)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:392)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:416)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:494)
    at org.jboss.marshalling.Marshalling.loadMarshallerFactory(Marshalling.java:112)
    at org.jboss.marshalling.Marshalling.getProvidedMarshallerFactory(Marshalling.java:101)
    at org.redisson.codec.MarshallingCodec.<init>(MarshallingCodec.java:214)
    at org.redisson.codec.MarshallingCodec.<init>(MarshallingCodec.java:197)
    at org.redisson.config.Config.<init>(Config.java:111)
    at org.redisson.Redisson.<init>(Redisson.java:62)
    at org.redisson.Redisson.create(Redisson.java:104)
    ...

The problem here is… To allocate MarshallingCodec we have this constructor: Called with protocol = ‘RIVER’ and configuration = ‘null’ [that’s OK!]

package org.redisson.codec;

public class MarshallingCodec extends BaseCodec {
...

    public MarshallingCodec(Protocol protocol, MarshallingConfiguration configuration) {
        this.factory = Marshalling.getProvidedMarshallerFactory(protocol.toString().toLowerCase());
        if (factory == null) {
            throw new IllegalArgumentException(protocol.toString());
        }
        if (configuration == null) {
            configuration = createConfig();
        }
        this.configuration = configuration;
    }
...
}

Marshalling.getProvidedMarshallerFactory(‘river’) call this function [that’s OK!]:

package org.jboss.marshalling.river;

public class RiverMarshallerFactory extends AbstractMarshallerFactory {
    private final SerializableClassRegistry registry;

    /**
     * Construct a new instance of a River marshaller factory.
     */
    public RiverMarshallerFactory() {
        if (getSecurityManager() == null) {
            registry = SerializableClassRegistry.getInstance();
         } else {
            registry = doPrivileged(new PrivilegedAction<SerializableClassRegistry>() {
                public SerializableClassRegistry run() {
                    return SerializableClassRegistry.getInstance();
                }
            });
        }
    }
...
}

Even I set or don’t SecurityManager I got the same error, so let’s try with getSecurityManager() return ‘null’ this function try set registry using SerializableClassRegistry.getInstance() but,

package org.jboss.marshalling.reflect;

public final class SerializableClassRegistry {
    ...
    private static final SerializableClassRegistry INSTANCE = new SerializableClassRegistry();
    private static final SerializablePermission PERMISSION = new SerializablePermission("allowSerializationReflection");

    public static SerializableClassRegistry getInstance() throws SecurityException {
        final SecurityManager manager = getSecurityManager();
        if (manager != null) {
            manager.checkPermission(PERMISSION);
        }
        return INSTANCE;
    }
...
}

now you can see, that inside the class SerializableClassRegistry the static final var SerializablePermission PERMISSION is always initialized with new SerializablePermission(“allowSerializationReflection”) before the function getInstance() is called, even when getSecurityManager() return null! [that’s not OK!!!]

That’s the problem. At android, SerializablePermission is not defined, as you can see here!

package java.io;

// Android-changed: Replaced with empty implementation and documented as legacy security code.
/**
 * This legacy security is not supported on Android. Do not use.
 */
public final class SerializablePermission extends BasicPermission {
...
}

So the RiverProviderDescriptor could not be instantiated.

To these tests I use:

at gradle dependency

implementation 'org.jboss.marshalling:jboss-marshalling:2.0.9.Final'
implementation 'org.jboss.marshalling:jboss-marshalling-river:2.0.9.Final'
implementation 'org.redisson:redisson:3.13.0'
    or
implementation 'org.redisson:redisson:3.12.5'

and redis 6.0.3 version running at docker android compileSdkVersion 29 (android 10.0 Q)

If that make sense for you I have some suggestions about how to fix error at redisson using coded FstCodec, but both class SerializableClassRegistry (package org.jboss.marshalling.reflect) and SerializablePermission (package java.io) are set final so I can’t see how to fix this inside redisson.

Cheers, hipolito

0reactions
mrnikocommented, May 31, 2020

Thanks for your feedback! I’ll note Kyro5Codec and SerializationCodec codecs as Android compatible on https://github.com/redisson/redisson/wiki/4.-data-serialization page. JsonJacksonCodec is also compatible.

Read more comments on GitHub >

github_iconTop Results From Across the Web

FstCodec (Redisson 3.7.2 API) - Javadoc.io
public class FstCodec extends BaseCodec. Efficient and speedy serialization codec fully compatible with JDK Serialization codec.
Read more >
mrniko/redisson - Gitter
Hi, I was looking at serializers/codec and noticed that it used to be FST but was changed to for MarshallingCodec.. Was curious on...
Read more >
CHANGELOG.md · master · edNb8H / Redisson · GitCode
Fixed - MarshallingCodec doesn't release allocated ByteBuf object if exception thrown ... Fixed - don't add Redis Slave as active if connections can't...
Read more >
Register a custom serializer implementing instantiate or define ...
Even Redisson has made Marshalling Codec as its default codec. The best part is that it can serialize almost all objects. Share.
Read more >
Redisson - Redis Java client with features of In-Memory Data ...
The sessions objects are working as all is handled at Tomcat level, but the client is jumping between both class loader. Anyone was...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found