Loading Inspections - Getting the Classloader Right
I l;oad my inspections using through my inspectionToolProvider extension.
I want to be able to supply inspections dynamically using Lua.
My first couple trys at this were moderately successful - but I kept running into classloader issues. Before I do anything to hacky. I'd like to know if this is just the wrong way to go about this.
Basically I get a static initializer error from one of the base classes that can't find its bundle.
I am trying to create Java classes forr each inspection written in Lua. I could just write one and call it LuaInspections, and then I wouldn't have this problem because I could avoiid creating the Inspection classes while the EP is running, and instead just do it during the inspections.
I would like it to be seamless, so the user cant tell if the inspection is written in Lua or Java.
Is there a way to add the inspections once I am running using the plugin classloader?
It may well have just been bad implementation on my part - but I was wondering if you had any advice about the best way to provide these "dynamic" or "user supplied' inspections.
Please sign in to leave a comment.
I'd love to be able to do this as well, unfortunately my understanding is that it's impossible. Actually, it's impossible to do what I wanted to do, you might be luckier. The problem is that you need to return Class objects from the InspectionToolProvider - this is difficult to do in Clojure, the dynamic compilation usually creates anonymous class instances. If you can dynamically compile some Lua to a Class object that can be instantiated you might be in luck. I'm assuming those classes should be loaded using the plugin class loader, but you could check this debugging the inspections you have right now and seeing what their classloader is.
I thought of a few variations, like having a common base class that has some configuration that allows it to find or instantiate the actual inspection at runtime, but I could never get around the need for a Class instance.
Yeah - it is the intelliJ classloader, not my plugin's. So I may need to write my own inspection configuration options, and make 1 LuaBasedInspections class to hold them all.
Hmm, that's annoying. Does the IntelliJ classloader have access to the plugin classloaders? If not that's going to be a problem for me since Clojure itself is exposed through the plugin classloader and is required to load classes compiled from Clojure.
I'll try implementing this sometime soon and report back what I find.
Note that you don't have to use InspectionToolWrapper and to return Class objects. InspectionToolRegistrar.registerInspectionToolFactory() gives you a much more direct way to accomplish what you need.
Oh fantastic, thanks Dmitry! I'll try this as soon as I get a moment.
Fantastic. Next chance I get I'll give it a try.
In order for the binding library I am using to work it woiud require an interface, and in the API currently everything is an abstract class. I will have to make an adapter class that I can instantiate from an interface or find a better binding solution - but these are all solvable issues.
The loading does work now. It turns out that the problem was a bug in the Lua implementation in Java that was not allowing me to override its use of the system class loader vs the calling function's.