java - 僵尸异常幸存被捕获

标签 java linux exception browser libgdx

我在尝试使用 LibGDX 游戏引擎中的 Gdx.net.openURI(String) 时遇到了一个非常奇怪的问题。这是一种简单地在我的浏览器中打开页面的方法。如果有效则返回 true,否则返回 false。 有效(打开页面)并返回 true,但我的控制台中出现随机异常,但未捕获此异常。

boolean opened;
try
{
    opened = Gdx.net.openURI(DONATE_URL); //at net.jumpai.client.menu.DonateDialog.<init>(DonateDialog.java:30)
}
catch(Exception ex)
{
    opened = false;
}

// some other code that is always executed

这是我得到的输出:

java.io.IOException: Cannot run program "sensible-browser": error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at java.lang.Runtime.exec(Runtime.java:620)
    at java.lang.Runtime.exec(Runtime.java:485)
    at org.lwjgl.LWJGLUtil$1.run(LWJGLUtil.java:406)
    at org.lwjgl.LWJGLUtil$1.run(LWJGLUtil.java:404)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.lwjgl.LWJGLUtil.execPrivileged(LWJGLUtil.java:404)
    at org.lwjgl.LinuxSysImplementation.openURL(LinuxSysImplementation.java:78)
    at org.lwjgl.Sys.openURL(Sys.java:257)
    at com.badlogic.gdx.backends.lwjgl.LwjglNet.openURI(LwjglNet.java:66)
    at net.jumpai.client.menu.DonateDialog.<init>(DonateDialog.java:30)
    at net.jumpai.client.world.online.OnlineWorldScreen.donateClicked(OnlineWorldScreen.java:434)
    at net.jumpai.util.event.ListenableImpl.trigger(ListenableImpl.java:25)
    at net.jumpai.client.menu.AccountMenu.lambda$new$0(AccountMenu.java:54)
    at net.jumpai.util.ui.listener.ClickAdapter.lambda$new$0(ClickAdapter.java:43)
    at net.jumpai.util.ui.listener.ClickAdapter.clicked(ClickAdapter.java:50)
    at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(ClickListener.java:89)
    at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:59)
    at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java:351)
    at com.badlogic.gdx.InputMultiplexer.touchUp(InputMultiplexer.java:96)
    at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:332)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:217)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:126)
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 22 more

我确保这段代码没有执行两次,这个问题不是一次有效而另一次无效的情况。这让我印象深刻。这是真正的异常(exception)吗?我不知道在哪里可以捕获和打印它。如何预防?

我使用的是 ArchLinux,我的浏览器是 Chromium。

最佳答案

正如 Perry Monschau 在命令中提到的,异常是由 Gdx.net.openURI() 调用的内部方法的 try-catch 打印的

所以我做了一个方法来避免控制台中出现不必要的错误:

public static boolean openURI(String uri)
{
    PrintStream prevErr = System.err;
    try
    {
        System.setErr(NullPrintStream.instance);
    }
    catch(SecurityException ignored)
    {
        return Gdx.net.openURI(uri);
    }

    try
    {

        return Gdx.net.openURI(uri);
    }
    finally
    {
        System.setErr(prevErr);
    }
}

在不先询问的情况下在控制台中打印内容的方法是 LWJGL 的 LinuxSysImplementation(评论不是我的):

// Linux may as well resort to pure Java hackery, as there's no Linux native way of doing it
// right anyway.

String[] browsers = {"sensible-browser", "xdg-open", "google-chrome", "chromium", "firefox", "iceweasel", "mozilla", "opera", "konqueror", "nautilus", "galeon", "netscape"};

for ( final String browser : browsers ) {
    try {
        LWJGLUtil.execPrivileged(new String[] { browser, url });
        return true;
    } catch (Exception e) {
        // Ignore
        e.printStackTrace(System.err);
    }
}

关于java - 僵尸异常幸存被捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51482803/

相关文章:

exception - 如何在 Flutter 中传递(在方法堆栈中)异常?

java - 在java中重新抛出不同的捕获异常

java - 显示不确定的进度指示器

java - 如何保护 Android 中的 .txt 文件免受用户侵害?

java - ServerSocket 构建失败

python - 使用 python3 查找空闲的 tcp 端口

linux - Linux脚本中如何将状态输出成多个文本?

C++ 迭代器异常安全

java - 从其他项目调用 REST Web 服务

python - 在 Python 2 中指定自定义日志记录 Linux 文件路径