英文:
executing java command from script gives error even though same command from cli works fine
问题
我正在编写一个Python脚本,其中包括启动一个JAR文件。
我正在使用以下方法执行Java命令:
def first_launch(self):
if self.is_initialize:
subprocess.run(
[f"-Xmx{self.max_memory}M", f"-Xms{self.min_memory}M", "-jar server.jar", "nogui"],
executable="/usr/bin/java",
cwd=self.directory
)
else:
raise Exception("Server is not initialized")
其中变量的值为:
- directory: /Users/cschmitz/Desktop/opt/minecraft/server
- max memory: 2048
- min memory: 1024
这将生成以下命令:
/usr/bin/java -Xmx2048M -Xms1024M -jar server.jar nogui
当我从终端运行此命令时,它正常工作。
但是,当我尝试从Python的子进程中执行它时,我收到以下错误信息:
无法完成操作。找不到支持 -Xmx2048M 的Java运行时。请访问 http://www.java.com 以获取有关安装Java的信息。
我正在使用Java可执行文件的绝对路径(与终端中使用的相同路径),因此似乎不太可能抓取不同版本的命令(例如,如果我的终端路径包含不同版本的命令,而我的Python文件没有访问权限)。
我在网上搜索了答案,我看到这条消息可能是因为只安装了Java运行时环境而不是开发工具包,但据我所知,我已安装了JDK(或者我认为如果我安装了OpenJDK,我不会只得到运行时环境)。
❯ java -version
openjdk version "19.0.1" 2022-10-18
OpenJDK Runtime Environment Homebrew (build 19.0.1)
OpenJDK 64-Bit Server VM Homebrew (build 19.0.1, mixed mode, sharing)
而且,实际上我可以从终端中正常启动它,这表明我已安装了正确的工具。有关我所做错了或误解的任何想法吗?
英文:
I'm writing a python script that amongst other things launches a jar file.
I'm using the following method to fire the java command:
def first_launch(self):
if self.is_initialize:
subprocess.run(
[f"-Xmx{self.max_memory}M", f"-Xms{self.min_memory}M", f"-jar server.jar", "nogui"],
executable="/usr/bin/java",
cwd=self.directory
)
else:
raise Exception("Server is not initialized")
Where the var values are:
- directory: /Users/cschmitz/Desktop/opt/minecraft/server
- max memory: 2048
- min memory: 1024
which should all come out to be the command:
/usr/bin/java -Xmx2048M -Xms1024M -jar server.jar nogui
When I run this command from my terminal it works fine:
But when I try firing it from the python subprocess I get the error:
> The operation couldn’t be completed. Unable to locate a Java Runtime that supports -Xmx2048M.
Please visit http://www.java.com for information on installing Java.
I'm using an absolute path to my java executable (the same one I'm using on in the CLI) so it seems unlikely that I'd be grabbing a different version of the command (like if my cli path included a different version of the command than what my python file had access to).
I searched around for answers online and I saw where you'd see this message if you only had the java runtime and not the dev kit, but as far as I can tell I have the jdk installed (or at least I figured that if I installed open jdk I wouldn't get just the runtime environment).
❯ java -version
openjdk version "19.0.1" 2022-10-18
OpenJDK Runtime Environment Homebrew (build 19.0.1)
OpenJDK 64-Bit Server VM Homebrew (build 19.0.1, mixed mode, sharing)
And really the fact that I can launch it just fine from the cli suggests that I have the right tools installed.
Any ideas of what I'm doing wrong or misunderstanding??
答案1
得分: 0
/usr/bin/java
应该是第一个参数,而不仅仅是executable
。
只有在需要将argv[0]
传递给程序的情况下才需要设置executable
,这里没有必要它们不同。您立即遇到的错误似乎是JVM将argv[0]
中最后一个/
后的内容视为它应该运行的操作模式的名称;正常的操作模式是java
,但没有名为-Xmx2048m
的模式。
根据argv[0}
来决定运行模式的软件相当常见:例如,如果您使用executable='/bin/bash'
,并且argv[0]
是sh
,bash将以POSIX sh兼容模式运行,关闭了一些非POSIX功能。
作为额外的问题,-jar
和server.jar
应该是两个单独的参数:-jar
被指定为下一个参数来指定要运行的jar文件。
因此,正确的代码看起来更像是:
subprocess.run(
['/usr/bin/java',
f'-Xmx{self.max_memory}M',
f'-Xms{self.min_memory}M',
'-jar', 'server.jar',
'nogui'],
cwd=self.directory
)
英文:
/usr/bin/java
should be the first argument, not (or at least, not just) the executable
.
You only need to set executable
when you need to pass a program a argv[0]
that differs from the executable name; there's no reason for them to be different here. The immediate error you get appears to be the JVM treating the basename of (which is to say, everything past the last /
in) argv[0]
as the name of an operational mode it's supposed to run in; the normal operating mode is java
, but there's no mode named -Xmx2048m
.
Software deciding what mode to run in based on its argv[0]
is fairly common: For example, if you call executable='/bin/bash'
with an argv[0]
of sh
, bash runs in POSIX sh compatibility mode, turning off several non-POSIX features.
As an additional issue, -jar
and server.jar
should be two separate arguments: -jar
is specified as an argument that specifies that the next argument is the jar to run.
Thus, correct code would look more like:
subprocess.run(
['/usr/bin/java',
f'-Xmx{self.max_memory}M',
f'-Xms{self.min_memory}M',
'-jar', 'server.jar',
'nogui'],
cwd=self.directory
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论