Java imports now require the JVM to be started?
Hey Petrus,
I am working on porting a library (called tbx20py
) at my job at TU Berlin from Orekit JCC to Orekit jpype.
Old behaviour with Orekit JCC
Before with Orekit JCC, I had several Python files importing java classes at the top of the file, and it was not a problem importing these Python files even before the JVM was started, for instance a library file called orekitutils.py
:
import os
from java.io import File
from java.util import ArrayList
from org.orekit.data import DirectoryCrawler, DataContext
[etc...]
def load_orekit_data():
# Function which loads our own orekit data folder
And then I would import Orekit, functions from this file (and other files) at the top of a script with:
import orekit
from tbx20py.orekitutils import load_orekit_data
And then only starting the JVM in the main function:
if orekit.getVMEnv() is None:
orekit.initVM()
And then loading the Orekit data, etc.
New behaviour with Orekit jpype?
Now it seems that with Orekit jpype, I need to start the JVM before being able to import orekit & java classes, otherwise I get an error.
For instance the same code snippet as before (adapted to the orekit_jpype name) now gives the following error:
---------------------------------------------------------------------------
> ImportError Traceback (most recent call last)
> Cell In[2], line 2
> 1 import orekit_jpype as orekit
> ----> 2 from tbx20py.orekitutils import load_orekit_data
> 3 if orekit.getVMEnv() is None:
> 4 orekit.initVM()
>
> File /media/ssd/git/tbx20py/tbx20py/orekitutils.py:12
> 1 """
> 2 __author__ = "Clément Jonglez (ILR TU Berlin)"
> 3 __copyright__ = "2013-2019 Technische Universität Berlin. All rights reserved."
> (...)
> 8 used or distributed without prior written consent of Technische Universität Berlin.
> 9 """
> 11 import os
> ---> 12 from java.io import File
> 13 from java.util import ArrayList
> 14 from org.orekit.data import DirectoryCrawler, DataContext
>
> File ~/miniforge3/envs/tubix20/lib/python3.11/site-packages/jpype/imports.py:155, in _JImportLoader.find_spec(self, name, path, target)
> 153 if not base in _JDOMAINS:
> 154 return None
> --> 155 raise ImportError("Attempt to create Java package '%s' without jvm" % name)
> 157 # Check for aliases
> 158 if name in _JDOMAINS:
>
> ImportError: Attempt to create Java package 'java' without jvm
I fixed that by adding an initVM guard at the beginning of each library file depending on Orekit:
from jpype import JImplements, JOverride
import orekit_jpype as orekit
orekit.initVM()
import os
from java.io import File
from java.util import ArrayList
from org.orekit.data import DirectoryCrawler, DataContext
[etc...]
Therefore the orekit_jpype's initVM
will maybe be called several times, but it's not a problem because I saw this method internally checks whether the JVM is already started or not.
Is this behaviour expected? Is there a better solution than what I used?