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

SpringBoot调用Python脚本异常排查:手动正常但Java调用卡住

问题:SpringBoot调用Python脚本卡在视频写入步骤,手动执行正常

背景信息

我有一个名为movie.py的Python脚本,存放路径为resources/movie-python,脚本导入内容如下:

import os
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.video.VideoClip import TextClip
from moviepy.video.compositing.CompositeVideoClip import CompositeVideoClip
import subprocess
import moviepy.config as conf
from moviepy.audio.io.AudioFileClip import AudioFileClip
import pyttsx3

手动在脚本目录执行python movie.py时运行完全正常,但通过SpringBoot的Java代码调用时,脚本会卡在video_with_text.write_videofile(temp_file, codec='libx264', audio_codec='aac')这一行,无法继续执行。

Java调用代码

public void callPythonFile() {
    try {
        // Directory where the Python script is located
        final File scriptDirectory = new File("src/main/resources/movie-python");

        // Command to run the Python script
        final String command = "python movie.py";

        // Start the process with the script directory as the working directory
        ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
        processBuilder.directory(scriptDirectory);
        Process process = processBuilder.start();

        // Read output from the process
        InputStream inputStream = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }

        // Wait for the process to finish
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("Python script exited with non-zero code: " + exitCode);
        }
        System.out.println("Python script exited with code: " + exitCode);

    } catch (IOException | InterruptedException e) {
        throw new RuntimeException("Error executing Python script: " + e.getMessage(), e);
    }
}

核心原因分析

1. 标准错误流未读取导致阻塞

Java代码仅读取了子进程的标准输出流(InputStream),但忽略了标准错误流(ErrorStream)。MoviePy执行视频写入时会输出大量日志到标准错误,当错误流的缓冲区被填满后,子进程会被强制阻塞,无法继续执行后续逻辑。

2. Python环境不匹配

手动执行时使用的是当前终端关联的Python环境,而Java启动子进程时默认使用系统全局的Python环境,两者的依赖包版本、路径配置可能存在差异。比如MoviePy依赖的ffmpeg路径未正确配置,导致无法调用编码器完成视频写入。

3. 文件权限与路径问题

虽然设置了脚本目录为工作目录,但SpringBoot运行进程的用户权限可能和手动执行的用户不同,导致临时文件temp_file无法创建或写入。另外,如果temp_file使用相对路径,在Java进程的上下文里可能解析到错误的位置,引发写入阻塞。

4. Pyttsx3的无终端兼容性问题

脚本中导入的pyttsx3是一个语音合成库,它依赖交互式终端环境。在Java调用的无终端子进程中,该库可能初始化失败或陷入等待输入的状态,间接导致整个脚本卡住。

解决建议

  • 同时处理标准错误流:新增线程读取process.getErrorStream(),避免缓冲区溢出阻塞进程。
  • 指定Python解释器完整路径:将命令中的python替换为手动执行时使用的Python完整路径(比如/usr/bin/python3.8或C:\Python39\python.exe),确保环境一致。
  • 使用绝对路径处理临时文件:修改Python脚本中temp_file的路径为绝对路径,同时检查SpringBoot运行用户对该路径是否有读写权限。
  • 调整Pyttsx3配置:初始化pyttsx3时指定无头模式,或者在Java调用时设置环境变量PYTHONUNBUFFERED=1禁用输出缓冲,避免交互等待。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:47:48