Python4J Cannot find the customized Python path in miniconda

Dear Community,

Recently, I’m trying to integrate my Pytorch models in the DL4J environment. Since my Pytorch models require additional modules, I need to create a virtual environment to import all dependencies.

As shown in the section Python Path in DL4J, DL4J enables the users to customize their own python environments. I created the new python virtual environment with miniconda. Unfortunately, I do not understand the following points:

  • org.eclipse.python4j.path: Should I change this path? As I understood, The user should use the following codes to get the path info:

import sys
import os

I created a virtual environment for python 3.10.4. However, using the code above, the python version turns to be python 3.10.2. After inspecting the deep4j project, I found that the printed version is the one that is automatically loaded and cached by the deep4j framework (javacpp) within the

In such a case, how to let the D4J project accept the newly created virtual environment?

  • org.eclipse.python4j.path.append: How can I use this property concretely? What does the following explanation mean? Further information or a demo would be great. What do the “none, before, after” imply here? How to use these flags?
A user can select none, before, or after.
In order to specify a custom python path, a user should be aware of 3 properties
  • Eager graph (TensorFlow 2.x eager/PyTorch) graph execution is planned. Is there any release plan for this supportive feature available now?

I’m working with Eclipse. Any further information & input about integrating the Pytorch model into DL4J will be appreciated.

Thanks in advance!

@Anakin that just gets you the python path you still have to set the system property. The append type just sets whether we should use any of the pre built in libraries (numpy mainly) or if we should let the user specify.

Hi @agibsonccc thanks a lot for your response and the explanation. I’m still a little bit confused by these preperties. Here is the Java snippet:

public class PythonExecutor {
	public static void main(String[] args) throws InterruptedException {
			System.setProperty("org.eclipse.python4j.path.append", "/home/skywalker/miniconda3/envs/venv_dl4j_3.10.4:/home/skywalker/miniconda3/envs/venv_dl4j_3.10.4/lib/");
			System.out.println("org.eclipse.python4j.path.append " + System.getProperty("org.eclipse.python4j.path.append"));
			try (PythonGIL pythonGIL = PythonGIL.lock()) {
				List<PythonVariable> inputs = new ArrayList<PythonVariable>();
				String code = Files.readString(Paths.get("/home/skywalker/miniconda3/envs/venv_dl4j_3.10.4/"));
			} catch (Throwable e) {
				// TODO Auto-generated catch block

The python script is shown as follows:

import os
import sys
from platform import python_version


print('python_version', python_version())

import torch
import torchvision

After running the Java code, I got the following error:

org.eclipse.python4j.path.append /home/skywalker/miniconda3/envs/venv_dl4j_3.10.4:/home/skywalker/miniconda3/envs/venv_dl4j_3.10.4/lib/
12:13:38.371 [main] DEBUG org.nd4j.python4j.PythonGIL - Acquiring GIL on 1
12:13:38.373 [main] INFO org.nd4j.python4j.PythonGIL - Pre Gil State ensure for thread 1
12:13:38.373 [main] INFO org.nd4j.python4j.PythonGIL - Thread 1 acquired GIL
Traceback (most recent call last):
  File "<string>", line 65, in <module>
ModuleNotFoundError: No module named 'torch'
0 /home/skywalker/.javacpp/cache/cpython-3.10.2-1.5.7-linux-x86_64.jar/org/bytedeco/cpython/linux-x86_64/lib
1 /home/skywalker/.javacpp/cache/cpython-3.10.2-1.5.7-linux-x86_64.jar/org/bytedeco/cpython/linux-x86_64/lib/python3.10
2 /home/skywalker/.javacpp/cache/cpython-3.10.2-1.5.7-linux-x86_64.jar/org/bytedeco/cpython/linux-x86_64/lib/python3.10/site-packages
python_version 3.10.2
No module named 'torch'
12:13:38.384 [main] DEBUG org.nd4j.python4j.PythonGIL - Pre gil state release for thread 1
12:13:38.385 [main] INFO org.nd4j.python4j.PythonGIL - Releasing GIL on thread 1
org.nd4j.python4j.PythonException: ModuleNotFoundError: No module named 'torch'
	at org.nd4j.python4j.PythonExecutioner.throwIfExecutionFailed(
	at org.nd4j.python4j.PythonExecutioner.exec(
	at com.demo.PythonExecutor.main(

It turns out that although the append property is set (not sure, whether it has been done correctly), the javacpp stills calls the pre-built python, i.e.,, in which the torch is not installed yet.

In my case, there are multiple Pytorch models, converting these models with onnx is much more daunting work since there are different issues during the exporting. As a short term solution, therefore I intent to use all the existing python-based solutions diretly and wait until D4J framework releases the powerful features for (eager/PyTorch) graph. Is it necessary to activate the miniconda environment at first within D4J?

I’m still struggling with this issue to use this customized python environment in D4J ecosystem. Any inputs will be appreciated.

@Anakin python4j doesn’t really understand miniconda concepts. You have to activate the right profile in miniconda then use the python script to get the right python path. All we can do is load a python path you tell us to.
I think you should isolate anything to do with python4j specifically and first just understand what a python path is and how it works. Googling brings this up:

Once you understand what a PYTHONPATH is the properties we list make a bit more sense.

Beyond that…I’m not sure what the issue is with onnx models. I’d at least try it. It’s just a few lines of code. You can see some examples here: deeplearning4j/ at master · eclipse/deeplearning4j · GitHub

It’s basically just setting up the data in pytorch and then calling export. That export call traces the call graph and sets up the appropriate ops. I’m happy to support either use case though.

@Anakin I was confused by the documentation too but I have Java now executing Python code using the packages from my miniconda environment.
There are a couple of key things to understand.

Your miniconda Python interpreter will not be used. The CPython interpreter bundled with javacpp will be used. Your miniconda environment is used to simply install python packages the javacpp CPython interpreter can load.
Ideally the miniconda Python versions would be identical so that the packages miniconda installs will be for that exact version, and avoid any issues where the interface to C extension modules or something isn’t backwards compatible, but as long as this hasn’t changed between versions it will run fine.
My installed version of CPython with javacpp is using v3.10.2, I installed v3.10.4 with miniconda.

To let your javacpp interpreter load your packages from your miniconda env you just need to point javacpp to your site-packages /home/skywalker/miniconda3/envs/venv_dl4j_3.10.4/lib/python3.10/site-packages

In the Java code running System.setProperty('org.eclipse.python4j.path', pythonEnvPath) didn’t do anything for me.
You can check if your value got loaded into the path by running print statements in your python script to see if your miniconda sitepackages path is there

import sys
for path in sys.path:
out = str(sys.path)

It should print


I think setting the System property this way doesn’t work because org.nd4j.python4j has already been imported and loaded javacpp
To get this to work I had to add the System Property as a “VM option”
If running from the command line this is done like
java -Dcustom_key="custom_value" ...

I’m using IntelliJ and had to alter my run configurations to insert this
Under Run/Debug configurations
Under Modify options select Add VM Options
In VM Options insert

@Robbie-Palmer thanks for the updated explanation. The next release is about done and I wanted to do a pass on the docs so feedback is appreciated.