所以我得到了一个使用滑地图的应用程序,由 MapTiler 服务器托管。 我写了一个名为
setup_server.sh
的小 sh 脚本来启动服务器:
#! /bin/sh
./maptiler-server --workDir "./" --adminPassword "abcdefg"
此脚本调用可执行 unix 文件并指定 Web 界面的工作目录和管理员密码。当我从终端调用这个脚本时,一切正常。服务器启动并继续运行。输出如下所示:
******@MacBook-Pro-von-****** maptiler-server-macos % sh setup_server.sh
2024-12-14T11:17:00.962Z [info]: Config file used: /Users/******/Desktop/GpxEvalApp/maptiler-server-macos/config.json
2024-12-14T11:17:02.212Z [error]: Virtual tilesets are not supported on your platform. We are working on enabling it in future versions, in the meantime, you can use docker distribution.
(node:32756) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `maptiler-server --trace-warnings ...` to show where the warning was created)
2024-12-14T11:17:02.948Z [info]: MapTiler Server ready on http://localhost:3650, administration on: http://localhost:3650/admin
注意:我使用 **** 审查了我的名字。
要从我的应用程序中运行脚本,我使用以下 Kotlin 代码(使用 kscript-tools):
class ScriptExecutor {
companion object{
@JvmStatic
fun execute(s: String){
try {
val cmd: String = "/bin/sh -c sh ./maptiler-server-macos/setup_server.sh"
cmd.runCommand()
//Runtime.getRuntime().exec(cmd)
}catch (e: Exception){
e.printStackTrace()
}
}
}
}
现在应用程序将进入 try/catch 并调用
cmd.runCommand()
函数。然后任务管理器中会出现一个名为“bash”的新进程(0,0% CPU 使用率,1 个线程)。
应用程序不会越过上述函数并运行,直到手动终止。当终止时,“bash”进程也终止。终止“bash”进程时,Kotlin 应用程序会抛出以下错误:
java.lang.RuntimeException:
at BashResult.getOrThrow(CommandLineTool.kt:19)
at DHCMap.subsystems.utilitys.ScriptExecutor$Companion.execute(ScriptExecutor.kt:35)
at DHCMap.subsystems.utilitys.ScriptExecutor.execute(ScriptExecutor.kt)
at DHCMap.Main.main(Main.java:21)
我尝试了不同的命令,例如
ls
或date
,它们工作得很好。我也尝试通过 Runtime.getRuntime().execc(cmd)
执行命令,结果相同。
我正在运行 MacOS Venuta 13.6.5,并且从 Java 代码中调用 Kotlin 代码。我检查了 MacOS 设置是否存在权限问题,但看起来一切都很好。
所以我需要一些帮助来了解为什么从 Kotlin 执行脚本时服务器无法启动。
首先感谢@Slaw。事实上,使用输出日志修复了错误。新的 Kotlin 代码如下:
class ScriptExecutor {
companion object{
@JvmStatic
fun execute(s: String){
val process = ProcessBuilder("/bin/sh", s).start()
// Stream output and error logs
val output = BufferedReader(InputStreamReader(process.inputStream))
val error = BufferedReader(InputStreamReader(process.errorStream))
// Print output in the background (optional)
Thread {
output.lines().forEach { println(it) }
}.start()
Thread {
error.lines().forEach { println(it) }
}.start()
}
}}
输出被打印到控制台,而消耗则外包给另一个线程。