ninia / jep

Embed Python in Java
Other
1.28k stars 145 forks source link

How does jep determine which python dll to use? #457

Closed jjnuclera closed 1 year ago

jjnuclera commented 1 year ago

In our set up we have two projects, one using jep and one pure python, which aren't supposed to be linked in any way. Both projects have their python dependencies bundled with them, including a python310.dll file.

In the jep project we use MainInterpreter.setInitParams(new PyConfig().setPythonHome(System.getProperty("user.dir") + "\\python")) to direct it to it's python interpreter & dependencies.

If the other project is not installed, this works fine. But if we do install it, jep seems to use that project's interpreter and things start to fail. I'm guessing jep is searching for .dlls at some point in the process, since renaming our 'other' dll to python310.old.dll means it picks up the expected one and things work again. It also seems to matter where the other project is installed - something like C:\Users\Username is fine but C:\Users\Username\AppData\Local\Programs has this issue.

The output from sys.path_importer_cache has the first entry as <other project path>\\python310.zip: None, but then all the rest are of the form <jep project path>\\python\\lib\\site-packages: FileFinder(...) .

Any help on how jep sets these things up would be appreciated, hopefully we can find a way to force it to use the correct dll!

bsteffensmeier commented 1 year ago

The loading of dependencies is operating system dependent and jep tries to let your OS handle it as much as possible. Our first attempt is always to just load libjep and let the OS find any dependencies, including libpython. If your operating system fails to find libpython then there is code in jep that will try to find it by searching under the python home in the PyConfig().

I suspect that your other project is installing python in a way that enables the OS to find libpython in the first attempt without jep being involved. I am not very familiar with the linking process on windows so I cannot point you to exactly which settings configure that. If that is the case then you may need to reconfigure your environment before running your program. Another option which might work is to call System.load() with the expected libpython before loading jep, I am not sure if this will override the other library or not.

jjnuclera commented 1 year ago

Hi Ben, appreciate you responding - you were right about the OS finding/loading libpython automatically. I'm not too familiar with the linking process on windows either but through some trial and error I was able to create an installer for the other project where the OS doesn't find libpython automatically! So the jep project then hits the code which searches python home for libpython and everything works again.

Using System.load directly also worked, which was a nice surprise! Though since I'm not sure exactly what happens when loading the library over an existing one, I went for the above solution.

Thanks again for your help.