Open theigl opened 1 week ago
Could you try to invoke ThreadSafeFury#setClassLoader? It should work
I will try this in my application tomorrow! It does not work in my test, but I just realized that my test is flawed.
Unfortunately, it does not work. Here is a simplified test-case that demonstrates the issue:
import org.apache.fury.Fury;
import org.apache.fury.ThreadSafeFury;
import org.apache.fury.config.Language;
import org.junit.jupiter.api.Test;
import java.util.concurrent.CountDownLatch;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
class ClassLoaderTest {
static class MyClassLoader extends ClassLoader {}
@Test
void shouldUseProvidedClassLoader() throws InterruptedException {
final MyClassLoader myClassLoader = new MyClassLoader();
final ThreadSafeFury fury = Fury.builder()
.withClassLoader(myClassLoader)
.withLanguage(Language.JAVA)
.requireClassRegistration(false)
.buildThreadSafeFuryPool(1, 1);
fury.setClassLoader(myClassLoader);
final CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
final ClassLoader t = fury.getClassLoader();
assertInstanceOf(MyClassLoader.class, t);
latch.countDown();
}).start();
latch.await();
}
}
It's not how this API be used, you should invoke fury.setClassLoader(myClassLoader);
just before you invoke Fury#deserialize
. This set classloader is cached as a thread local variable, thus is only visible on your setting thread
Ah OK! Thanks for clarifying this.
Is there a reason the API has to be so complicated for ThreadPoolFury
? I understand that it has to be this way if I want to customize the class loader on a per-call or per-thread basis. But in my case I just want to use a "hard-coded" class loader for each and every thread. Could it not use the class loader passed to .withClassLoader(xyz)
by default?
You can do that by:
new ThreadPoolFury(classloader -> Fury.builder()
.withClassLoader(myClassLoader)
.withLanguage(Language.JAVA)
.requireClassRegistration(false))
But this is indeed a bug, we need to use classloader set in FuryBuilder for ThreadSafeFury too. Would you like to submit a PR?
I'm on holiday for the next 7-10 days. If the issue is still open when I come back, I can take a look!
Search before asking
Version
0.8.0
Component(s)
Java
Minimal reproduce step
It is quite difficult to simulate this behavior:
In the same package, put the following class:
What did you expect to see?
I can read proxies for private interfaces loaded during application startup.
What did you see instead?
The following exception is thrown in a Spring Boot app when reading a proxy created by Spring's
SerializableTypeWrapper
:The class was loaded by Spring during application startup using the
AppClassLoader
.ThreadPoolFury
always uses the current thread context which isTomcatEmbeddedClassLoader
in my case. It is not possible to forceThreadPoolFury
to use the class loader provided to Fury.Anything Else?
No response
Are you willing to submit a PR?