Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redisson and Json for objects

I currently trying out Redisson as a Redis client and so far I've been able to replace a good chunk of code with no issues. The only problem I'm having now is trying to use the distributed collections, such as Queue or List.

List<MyEntry> entries = // read some sample data from a file
RedissonClient client = // create client
RBlockingQueue<MyEntry> queue = client.getBlockingQueue("test-queue", new JsonJacksonCodec());

queue.addAll(entries);
List<MyEntry> readBack = new ArrayList<>();
queue.drainTo(readBack);

When I get to the last line, I always get this exception -

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 1439]

When I add @JsonTypeInfo to my class, it appears to work, however, most of the classes I don't have access to add the @JsonTypeInfo annotation to.

I am missing something here? One way to work around this could be to use the ByteArrayCodec and serialize/deserialize using my own ObjectMapper (edit: trying this throws another type of exception!), but if possible I'd prefer to let Redisson handle this since it offers many codecs already.

Any help is much appreciated as usual!

A bit more info - I ended up writing my own simple Codec, that simply takes a Class as a parameter, and creates a Decoder and Encoder works similiar to how the JsonJacksonCodec works, with one difference -

 private static class MyCodec<T> implements Codec {

    private final Decoder<Object> decoder = new Decoder<Object>() {
        @Override
        public T decode(ByteBuf buf, State state) throws IOException {
            return mapper.readValue((InputStream) new ByteBufInputStream(buf), type);
        }
    };

    private final ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
    private final Class<T> type;

    public MyCodec(Class<T> type) {
        this.type = type;
    }

    // rest of methods...
}

And I was able to get my example working - but this feels like a workaround, rather than a solution to the original problem, and I don't want to have to write additional Codecs for each implementation I have :)

like image 306
KingTravisG Avatar asked Aug 28 '17 20:08

KingTravisG


People also ask

Why use Redisson?

Redisson is a thread-safe Redis client for the Java programming language. It allows you to use all of the familiar Java collections and data structures on top of Redis - such as List, Map, Queue, Lock, Semaphore and many more.

How Redisson works?

Redisson constitutes an in-memory data grid that offers distributed Java objects and services backed by Redis. Its distributed in-memory data model allows sharing of domain objects and services across applications and servers.

Is Redisson thread safe?

Redisson client and all of its objects are thread safe. threads and nettyThreads are configuration for the internal thread pools. Since netty uses event loop model that is similar to the way Redis works internally, you don't need a great deal of threads.

What is RBucket Redisson?

Redisson implements the Holder class in Redis with the RBucket interface, which can hold any type of object. RBucket implements methods such as compareAndSet(), get(), getAndDelete(), getAndSet(), set(), size(), trySet(), and more. The maximum size of the object is 512 megabytes.


2 Answers

Redisson provides a default Jackson codec for classes that are NOT annotated with Jackson annotations. Your existing annotations is taking precedence over the default codec setting, hence the problem. You can try other types of codec like fst codec or supply your own compatible object mappper to the Jackson codec.

like image 166
Redisson_RuiGu Avatar answered Oct 21 '22 18:10

Redisson_RuiGu


See Fundamental API design flaw -- with respect to encoding and serialization

I would very much like to be wrong. Currently looking for a way to address this that doesn't require major surgery.

like image 24
DALDEI Avatar answered Oct 21 '22 18:10

DALDEI