You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Python3调用Java类及输出错误处理(含JPype问题排查)

Let's work through your issues step by step to get Python 3 calling your Java class properly, with output and error logging sorted out.


1. Fix the ModuleNotFoundError: No module named 'jpype'

First off, the PyPI package for JPype is jpype1 (not just jpype). Install it via pip:

pip install jpype1

Then correct your import statement in Python (it's lowercase jpype, not uppercase):

import jpype as jp

2. Prepare Your Java Class for JPype Access

Your Java code has a few issues that block Python from interacting with it properly:

  • The testAll() method is private — Python can't access private Java methods, so change it to public.
  • There are syntax errors (extra parentheses in method calls, malformed printf statements).
  • You need to compile the .java file to a .class file first:
    Open your terminal, navigate to the folder with ClassWithTest.java, and run:
    javac ClassWithTest.java
    

Here's the corrected Java code:

public class ClassWithTest{
    public ClassWithTest(){ 
        System.out.println(insertLength("Tests ready to run")); 
    }
    public void testAbs(){ 
        System.out.println(insertLength("Invocation of " + Thread.currentThread().getStackTrace()[1].getMethodName())); 
        System.out.println(insertLength("abs(-2) = 2: " + testResult(Math.abs(-2), 2))); 
        System.out.println(insertLength("abs(-3) = -2: " + testResult(Math.abs(-3), -2))); 
    }
    public void testRound(){ 
        System.out.println(insertLength("Invocation of " + Thread.currentThread().getStackTrace()[1].getMethodName())); 
        System.out.println(insertLength("round(0.7) = 1: " + testResult(Math.round(0.7), 1))); 
        System.out.println(insertLength("round(0.2) = 1: " + testResult(Math.round(0.2), 1))); 
    }
    public void testMin(){ 
        System.out.println(insertLength("Invocation of " + Thread.currentThread().getStackTrace()[1].getMethodName())); 
        System.out.println(insertLength("min(7,3) = 3: " + testResult(Math.min(7,3), 3))); 
        System.out.println(insertLength("min(5,7) = 7: " + testResult(Math.min(5,7), 7))); 
    }
    public void testMax(){ 
        System.out.println(insertLength("Invocation of " + Thread.currentThread().getStackTrace()[1].getMethodName())); 
        System.out.println(insertLength("max(7,14) = 14: " + testResult(Math.max(7,14), 14))); 
        System.out.println(insertLength("max(5,7) = 5: " + testResult(Math.max(5,7), 5))); 
    }
    public void TestDiv(){ 
        System.out.println(insertLength("Invocation of " + Thread.currentThread().getStackTrace()[1].getMethodName())); 
        System.out.println(insertLength("14 / 2 = 7: " + testResult(14 / 7, 3))); 
    }
    public void testMult(int x){ 
        System.out.println(insertLength("Invocation of " + Thread.currentThread().getStackTrace()[1].getMethodName())); 
        System.out.printf("2 * %d = %s%n", x, testResult(2 * x, 2 * x)); 
    }
    public void otherTest(){ 
        System.out.println(insertLength("Invocation of " + Thread.currentThread().getStackTrace()[1].getMethodName())); 
        System.out.printf("1 = 1: %s%n", testResult(1, 1)); 
    }
    // Make testAll public so Python can call it
    public void testAll(){ 
        System.out.println(insertLength("Invocation of " + Thread.currentThread().getStackTrace()[1].getMethodName())); 
        testAbs(); 
        testRound(); 
        testMin(); 
        testMax(); 
    }
    private static String testResult(double result, double expected){ 
        return (result == expected ? "ok" : "no"); 
    }
    public static String insertLength(Object obj){ 
        String line = obj.toString(); 
        return String.format("[%d]> %s", line.length(), line); 
    }
    public static void main(String[] args){ 
        new ClassWithTest().testAll(); 
    }
}

3. Corrected Python Code to Call Java & Log Output/Errors

Your original Python code had critical mistakes (wrong JVM path, missing classpath, incorrect method calls). Here's the fixed version that meets all your requirements:

import logging
import jpype as jp
from jpype import JClass, java

# Configure error logging to write to ERROR.txt
logging.basicConfig(
    filename="ERROR.txt",
    level=logging.ERROR,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

def main():
    # Get the default JVM path (auto-detects your system's JVM)
    jvm_path = jp.getDefaultJVMPath()
    
    try:
        # Start JVM, add current directory to classpath (so it finds ClassWithTest.class)
        jp.startJVM(
            jvm_path,
            "-ea",
            "-Djava.class.path=.",
            convertStrings=False
        )
        
        # Load the Java class
        ClassWithTest = JClass("ClassWithTest")
        
        # Redirect Java's System.out to OUTPUT.txt
        file_output = java.io.FileOutputStream("OUTPUT.txt")
        print_stream = java.io.PrintStream(file_output)
        java.lang.System.setOut(print_stream)
        
        # Create class instance and run tests
        test_instance = ClassWithTest()
        test_instance.testAll()
        
        # Clean up output stream
        print_stream.close()
        file_output.close()
        
    except Exception as e:
        # Log full error details (including stack trace) to ERROR.txt
        logging.error(str(e), exc_info=True)
    finally:
        # Ensure JVM always shuts down, even if an error occurs
        if jp.isJVMStarted():
            jp.shutdownJVM()

if __name__ == "__main__":
    main()

4. Key Things to Remember

  • Classpath: Always add the directory with your compiled .class files to the JVM's classpath (we used -Djava.class.path=. for the current directory).
  • JVM Shutdown: The finally block ensures the JVM closes properly even if an error happens — this prevents leftover JVM processes.
  • Java Output Redirection: Using Java's own System.setOut() is the most reliable way to capture all Java console output to a file.
  • Error Logging: Adding exc_info=True to logging.error() saves the full stack trace, which makes debugging way easier.

With these changes, you'll:

  1. Successfully call your Java class from Python 3
  2. Save all Java execution output to OUTPUT.txt
  3. Log any errors (JPype issues, Java exceptions) to ERROR.txt before the program terminates

内容的提问来源于stack exchange,提问作者saharsa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:01:26