Is it possible for switch the classloader in Rhino code?
PawelLipski opened this issue · comments
AFAICS Rhino executed via com.intellij.remoterobot.RemoteRobot#callJs(java.lang.String, boolean)
(or runJs
) is executed with PluginClassLoader
for Robot server
as context classloader. Attempt to setContextClassLoader
to the PluginClassLoader
of the tested plugin's don't seem to work:
Rhino code:
const pluginId = PluginId.getId('com.virtuslab.git-machete');
const pluginClassLoader = PluginManagerCore.getPlugin(pluginId).getPluginClassLoader();
Thread.currentThread().setContextClassLoader(pluginClassLoader);
const providerClass = Class.forName('com.virtuslab.gitmachete.frontend.ui.providerservice.SelectedGitRepositoryProvider'); // some class from my plugin
results in:
java.lang.Throwable: Wrapped java.lang.ClassNotFoundException: com.virtuslab.gitmachete.frontend.ui.providerservice.SelectedGitRepositoryProvider
PluginClassLoader(plugin=PluginDescriptor(name=Robot server, id=com.jetbrains.test.robot-server-plugin,
descriptorPath=plugin.xml, path=/tmp/ide-probe/instances/intellij-instance-2022.1--QLOZN9sdT3iaH2Vwk9Djew/plugins/robot-server-plugin,
version=0.11.13, package=null, isBundled=true), packagePrefix=null, instanceId=20, state=active)
So it seems that Rhino uses Robot server's PluginClassLoader
, no matter what setContextClassLoader
points to. Is there any way around that?
Hi, can you try to do it this way?
const pluginId = PluginId.getId('com.virtuslab.git-machete');
const pluginClassLoader = PluginManagerCore.getPlugin(pluginId).getPluginClassLoader();
const providerClass = Class.forName('com.virtuslab.gitmachete.frontend.ui.providerservice.SelectedGitRepositoryProvider', true, pluginClassLoader); // some class from my plugin
Yes! I can alternatively load a single class explicitly pointing to pluginClassLoader
also by:
const providerClass = pluginClassLoader.loadClass('com.virtuslab.gitmachete.frontend.ui.providerservice.SelectedGitRepositoryProvider', true, pluginClassLoader); // some class from my plugin
but what I'm aiming at is to switch the default classloader used by Rhino! I tried Thread.currentThread().setContextClassLoader(pluginClassLoader);
but to now avail, Rhino still seems to use the classloader associated with Robot Server plugin, not the plugin I've pointed to
So I can provide a workaround by using more reflection (relying on Class
and Method
objects in Rhino code)... but curious if it's possible to just re-wire Rhino to use a different classloader completely 🤔
I've tried to pass plugin classloader to rhino execution context and unfortunately it failed with Loader can not resolve Rhino classes error.
As for setContextClassLoader
way, seems that Rhino caches it and keeps using the one was set on context creating. And if not I guess we would have the same error.
It might work if we run Robot Server not as a plugin but in the premain of Idea launching somewhere on early stage and it would be loaded by classloader which would be an ancestor for all plugin classloaders. But I guess it's to much for this task
Okay, that's roughly what I was afraid of... lemme close this issue then and fall back to explicit pluginClassLoader.loadClass(...)
calls indeed