How make a plugin depend on runtime/provided dependency ?
Hi,
I am trying to create a plugin that uses an API from a third party vendor. This API consists in a JAR file AND some native libs that are located in a given directory.
My problem comes from the fact that this API is not open source, and then cannot be bundled in my plugin.
Hence, for development, I can specify those dependencies as "compile only" and "runtime" so that I can compile and test it, without bundling those files inside the plugin itself --> this part is fine :)
The issue come when I want to use the "runIde". Everything starts fine since I lazily use the external API, but at the moment I try to access the Java API it crashes ... obviously since the API jar is not bundled.
My problem is : how can I say to IntelliJ to to actually look for those files ??? The actual flow of my plugin would be that the user need to specify to path to those files, and the plugin would use it. It if were only jars, I could do some magic with the classloaders, but with the native libs, I am kinda blocked by the fact that the VM option java.library.path must be set before startup
Thanks
Please sign in to leave a comment.
Off the top of my head: you need to separate your code that depends on the native libraries from code that can run without them.
Do not trigger class loading which depend on the native libraries without first verifying that the native libraries are installed. This means not even importing those classes into ones you want to run without the libraries.
In your plugin code, which is not dependent on native libraries, check if they are configured and installed before loading any classes. Instead, prompt the user to install/configure your plugin.
If you limit your access to classes which depend on the native libraries to dynamic class instantiation, that way you are guaranteed to not accidentally trigger class loader for those classes
Yes absolutely, that's kinda what I am doing because the native lib is lazily loaded by some java code which is never called unless I do a specific action that needs it.
The problem is that "when the native lib is being tried to be loaded it needs to be in the java.library.path" which is not the case by default since it is located in some installation folder. At this points the "System.loadLibrary" complains that it cannot find the library, and unfortunately this call is in the API I do not own so I cannot load it by myself separately :""""(
This problem is not trivial to me because the "java.library.path" cannot be changed at runtime, meaning that I need to place the native libs somewhere that is included in the library path of the IntelliJ runtime itself.
So I could either :
- copy the libs at runtime to a place located in the library path of the IntelliJ runtime --> feasible but I need to keep track of each files I copy in order to clean them - and there are a bunch of them potentially
- modify the java.library.path of IntelliJ --> can be configured by changing the jvm options (https://www.jetbrains.com/help/idea/tuning-the-ide.html#configure-jvm-options) but it is not recommended, and even kinda forbidden for macos users.
Both of them are not quite good solutions to me, I tried the second one locally cause it is the easiest to setup. Seems to locate the libs but I also found out that the providen libs are not compatible with the M1 architecture, so I would need to change the Java runtime of intellij for M1 users which is not acceptable.
I think after all the "simplest" solution will be to proxy this external tool outside of IntelliJ to leverage more easily those issues, and provide some API that is actually simple to use :D