use of org.redisson.codec.CustomObjectInputStream in project redisson by redisson.
the class TasksRunnerService method decode.
@SuppressWarnings("unchecked")
private <T> T decode(TaskParameters params) {
ByteBuf classBodyBuf = Unpooled.wrappedBuffer(params.getClassBody());
ByteBuf stateBuf = Unpooled.wrappedBuffer(params.getState());
try {
HashValue hash = new HashValue(Hash.hash128(classBodyBuf));
Codec classLoaderCodec = CODECS.get(hash);
if (classLoaderCodec == null) {
RedissonClassLoader cl = new RedissonClassLoader(codec.getClassLoader());
cl.loadClass(params.getClassName(), params.getClassBody());
classLoaderCodec = this.codec.getClass().getConstructor(ClassLoader.class).newInstance(cl);
CODECS.put(hash, classLoaderCodec);
}
T task;
if (params.getLambdaBody() != null) {
ByteArrayInputStream is = new ByteArrayInputStream(params.getLambdaBody());
// set thread context class loader to be the classLoaderCodec.getClassLoader() variable as there could be reflection
// done while reading from input stream which reflection will use thread class loader to load classes on demand
ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(classLoaderCodec.getClassLoader());
ObjectInput oo = new CustomObjectInputStream(classLoaderCodec.getClassLoader(), is);
task = (T) oo.readObject();
oo.close();
} finally {
Thread.currentThread().setContextClassLoader(currentThreadClassLoader);
}
} else {
task = (T) classLoaderCodec.getValueDecoder().decode(stateBuf, null);
}
Injector.inject(task, RedissonClient.class, redisson);
Injector.inject(task, String.class, params.getRequestId());
if (tasksInjector != null) {
tasksInjector.inject(task);
}
return task;
} catch (Exception e) {
throw new IllegalStateException("Unable to initialize codec with ClassLoader parameter", e);
} finally {
classBodyBuf.release();
stateBuf.release();
}
}
Aggregations