从 Java 启动 OpenOffice 服务 (soffice) 时出现问题(命令在命令行中运行,但不能从 Java 运行)

发布于 2024-07-11 17:05:03 字数 582 浏览 7 评论 0原文

我想执行一个简单的命令,该命令可以在 shell 中运行,但不能在 Java 中运行。 这是我想要执行的命令,效果很好:

soffice -headless "-accept=socket,host=localhost,port=8100;urp;" 

这是我从 Java 执行的代码,试图运行此命令:

String[] commands = new String[] {"soffice","-headless","\"-accept=socket,host=localhost,port=8100;urp;\""};
Process process = Runtime.getRuntime().exec(commands)
int code = process.waitFor();
if(code == 0)
    System.out.println("Commands executed successfully");

当我运行此程序时,我得到“命令已成功执行”。 但是,当程序完成时,该进程并未运行。 有没有可能JVM在程序运行后将其杀死?

为什么这不起作用?

I want to exceute a simple command which works from the shell but doesn't work from Java.
This is the command I want to execute, which works fine:

soffice -headless "-accept=socket,host=localhost,port=8100;urp;" 

This is the code I am excecuting from Java trying to run this command:

String[] commands = new String[] {"soffice","-headless","\"-accept=socket,host=localhost,port=8100;urp;\""};
Process process = Runtime.getRuntime().exec(commands)
int code = process.waitFor();
if(code == 0)
    System.out.println("Commands executed successfully");

When I run this program I get "Commands executed successfully".
However the process is not running when the program finishes.
Is it possible that the JVM kills the program after it has run?

Why doesn't this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

揽清风入怀 2024-07-18 17:05:03

我不确定我是否弄错了,但据我所知,您正在生成命令,但从未将它们传递给“执行”方法......您正在执行“”。

尝试使用 Runtime.getRuntime().exec(commands) =)

I'm not sure if I'm not mistaken, but as far as I see you're generating the commands but never passing them to the "execute" method... you're executing "".

Try using Runtime.getRuntime().exec(commands) =)

江湖彼岸 2024-07-18 17:05:03

我想说一下我是如何解决这个问题的。
我创建了一个 sh 脚本,基本上为我运行 soffice 命令。

然后,我只需从 Java 运行该脚本,它就可以正常工作,如下所示:

public void startSOfficeService() throws InterruptedException, IOException {
        //First we need to check if the soffice process is running
        String commands = "pgrep soffice";
        Process process = Runtime.getRuntime().exec(commands);
        //Need to wait for this command to execute
        int code = process.waitFor();

        //If we get anything back from readLine, then we know the process is running
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        if (in.readLine() == null) {
            //Nothing back, then we should execute the process
            process = Runtime.getRuntime().exec("/etc/init.d/soffice.sh");
            code = process.waitFor();
            log.debug("soffice script started");
        } else {
            log.debug("soffice script is already running");
        }

        in.close();
    }

我还通过调用此方法来终止 soffice 进程:

public void killSOfficeProcess() throws IOException {
        if (System.getProperty("os.name").matches(("(?i).*Linux.*"))) {
            Runtime.getRuntime().exec("pkill soffice");
        }
    }

请注意,这仅适用于 Linux。

I would like to say how I solved this.
I created a sh script that basically run the command of soffice for me.

Then from Java I just run the script, and it works fine, like this:

public void startSOfficeService() throws InterruptedException, IOException {
        //First we need to check if the soffice process is running
        String commands = "pgrep soffice";
        Process process = Runtime.getRuntime().exec(commands);
        //Need to wait for this command to execute
        int code = process.waitFor();

        //If we get anything back from readLine, then we know the process is running
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        if (in.readLine() == null) {
            //Nothing back, then we should execute the process
            process = Runtime.getRuntime().exec("/etc/init.d/soffice.sh");
            code = process.waitFor();
            log.debug("soffice script started");
        } else {
            log.debug("soffice script is already running");
        }

        in.close();
    }

I also kill the soffice process by calling this method:

public void killSOfficeProcess() throws IOException {
        if (System.getProperty("os.name").matches(("(?i).*Linux.*"))) {
            Runtime.getRuntime().exec("pkill soffice");
        }
    }

Note that this only works in Linux.

不即不离 2024-07-18 17:05:03

我相信您没有正确处理引用。 原始 sh 命令行包含双引号以防止 shell 解释分号。 shell 在 soffice 进程看到它们之前将它们剥离。

在你的Java代码中,shell永远不会看到参数,所以不需要额外的双引号(用反斜杠转义)——而且它们可能会让soffice感到困惑。

这是去掉多余引号的代码(并添加了一个分号)

String[] commands = new String[] {"soffice","-headless","-accept=socket,host=localhost,port=8100;urp;"};
Process process = Runtime.getRuntime().exec(commands);
int code = process.waitFor();
if(code == 0) 
    System.out.println("Commands executed successfully");

(免责声明:我不懂 Java,而且我还没有测试过这个!)

I believe you aren't handling quoting correctly. The original sh command line includes double quotes to prevent the shell interpreting the semicolons. The shell strips them off before the soffice process sees them.

In your Java code the shell will never see the arguments, so the extra double quotes (escaped with backslashes) are not needed - and they are probably confusing soffice.

Here's the code with the extra quotes stripped out (and a semicolon thrown in)

String[] commands = new String[] {"soffice","-headless","-accept=socket,host=localhost,port=8100;urp;"};
Process process = Runtime.getRuntime().exec(commands);
int code = process.waitFor();
if(code == 0) 
    System.out.println("Commands executed successfully");

(Disclaimer: I don't know Java, and I haven't tested this!)

无法言说的痛 2024-07-18 17:05:03

“/Applications/OpenOffice.org\ 2.4.app/Contents/MacOS/soffice.bin -headless -nofirststartwizard -accept='socket,host=localhost,port=8100;urp;StartOffice.Service'”

或者简单地转义引号也可以。 我们将这样的命令提供给 ant 脚本,该脚本最终会像上面那样以 exec 调用结束。 我还建议每 500 次左右的转换重新启动该进程,因为 OOO 无法正确释放内存(取决于您运行的版本)。

"/Applications/OpenOffice.org\ 2.4.app/Contents/MacOS/soffice.bin -headless -nofirststartwizard -accept='socket,host=localhost,port=8100;urp;StartOffice.Service'"

or simply escaping the quotes will work as well. We feed a command like this to an ant script that ultimately ends up in an exec call like you have above. I would also recommend restarting the process every 500 or so conversions because OOO does not properly free memory (depending on what version you are running).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文