pythonjpype

Jpype: ModuleNotFoundError when import classes in jar


Problem

I got an ModuleNotFoundError: No module named 'spoon' when I set the -Djava.class.path as a directory "jars/*".

Project structure

utils
├── __init__.py
├── jars
│   └── spoon-core-9.2.0-beta-4.jar
└── parse_utils.py
# parse_utils.py

import jpype
import jpype.imports
from jpype.types import *

JARS_PATH = 'jars/*'
jpype.startJVM(jpype.getDefaultJVMPath(),  '-Djava.class.path=' + JARS_PATH)

import spoon.Launcher as Launcher

What I've tried

JClass and JPackage

I found a similar problem at stackoverflow Jpype import cannot find module in jar and I tried the top answer but failed.

Launcher = jpype.JPackage('spoon').Launcher  # AttributeError: Java package 'spoon' is not valid
Launcher = jpype.JClass('spoon.Launcher')  # TypeError: Class spoon.Launcher is not found
Launcher = jpype.JClass("java.lang.Class").forName('spoon.Launcher') # java.lang.ClassNotFoundException: java.lang.ClassNotFoundException: spoon.Launcher

use jar path

JARS_PATH = 'jars/spoon-core-9.2.0-beta-4.jar'

and I got :

Traceback (most recent call last):
  File "ClassLoader.java", line 357, in java.lang.ClassLoader.loadClass
  File "Launcher.java", line 338, in sun.misc.Launcher$AppClassLoader.loadClass
  File "ClassLoader.java", line 424, in java.lang.ClassLoader.loadClass
  File "URLClassLoader.java", line 381, in java.net.URLClassLoader.findClass
java.lang.ClassNotFoundException: java.lang.ClassNotFoundException: com.martiansoftware.jsap.JSAPException

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "org.jpype.pkg.JPypePackage.java", line -1, in org.jpype.pkg.JPypePackage.getObject
  File "Class.java", line 348, in java.lang.Class.forName
  File "Class.java", line -2, in java.lang.Class.forName0
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/audrey/Documents/GitHub/xiaoven/codegex/utils/parse_utils.py", line 16, in <module>
    import spoon.Launcher as Launcher
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 914, in _find_spec
  File "/usr/local/Caskroom/miniconda/base/envs/codegex/lib/python3.8/site-packages/jpype/imports.py", line 194, in find_spec
    if not hasattr(base, parts[2]):
java.lang.NoClassDefFoundError: java.lang.NoClassDefFoundError: com/martiansoftware/jsap/JSAPException

Solution

  • See this link:

    I would start with checking to see if the jar was picked up in the path.

    import jpype
    jpype.startJVM(classpath="jars/*")
    print(jpype.java.lang.System.getProperty("java.class.path"))
    

    My guess is there is a syntax error in your test code, or the spoon jar is missing some dependency, but nothing stands out in your example. Do you have the required jar dependencies including com.martiansoftware.jsap.JSAPException in the jars directory?

    After I download the missing jars manually according to the error log (or the External Libraries list under IDEA project view), it succeeded to import spoon classes.