Python wrapper and orekit.initVM()

Hi Orekit experts!

I am just starting out with orekit, using it from python using the python wrapper here:

I cannot use anaconda so I built the egg myself following instructions here:

I will be calling Orekit in a python service on a background thread. Most of the samples I see have this code at the top of each module where orekit is used:

import orekit
orekit.initVM()

this works fine if the code is used from the main thread. but if orekit is called from a background thread I get this:

“RuntimeError: attachCurrentThread() must be called first”

What is the best practice for calling Orekit from a background thread? Should initVM() should only be called once per thread? Or once per process? Is there a function or method I can call to discover if initVM() needs to be called?

I did some experiments and got a segfault after calling Orekit a second time. first time works, second time segfaults:

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f0eac15da84, pid=29843, tid=0x00007f0e7affd700
#
# JRE version: OpenJDK Runtime Environment (8.0_151-b12) (build 1.8.0_151-8u151-b12-0ubuntu0.17.04.2-b12)
# Java VM: OpenJDK 64-Bit Server VM (25.151-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [_orekit.cpython-36m-x86_64-linux-gnu.so+0x80ca84]  JCCEnv::setClassPath(char const*)+0x24

Thanks,
Jesse

Hi Jesse,

And welcome to the orekit community :slight_smile:

I played a bit with the attachCurrentThread but can’t seem to find the code. Orekit is based on the JCC tool, which describes the method shortly at:

https://lucene.staged.apache.org/pylucene/features.html

Before PyLucene APIs can be used from a thread other than the main thread that was not created by the Java Runtime, the attachCurrentThread() method must be called on the JCCEnv object returned by the initVM() or getVMEnv() functions.

Basically you get an object returned from the vm=orekit.initVM() call, which you then pass to the new thread and call the vm.attachCurrentThread() on, or get it via orekit.getVMEnv() in the new thread. You can use the orekit.getVMEnv() to see if there is a java engine has been started as well.

Regards
/Petrus