如何等到环境无头?

时间:2015-06-24 15:44:06

标签: java linux headless

我创建了一个用Ubuntu 12.04启动的 Java服务器,我遇到了一个问题:我的代码需要一个非无头(或头部)环境才能工作,否则它抛出了HeadlessException:

java.awt.AWTException: headless environment
at java.awt.Robot.<init>(Robot.java:91)
at remote_control.RobotThread.run(RobotThread.java:35)
at java.lang.Thread.run(Thread.java:745)

但似乎我的.jar在启动时在X服务器之前启动,所以我总是得到&#34; HeadlessException&#34;。为了使我的JAR从我的系统开始,我做了类似的事情:

sudo update-rc.d my_script_to_initiate_my_jar defaults 99 01

我找不到在X服务器之后启动 JAR的方法,所以我认为解决此问题的最佳方法是在我的代码中使用忙等待。我已经检查了很多问题(在StackOverflow和谷歌),我找到了一些常见的解决方案:

// First solution
while (GraphicsEnvironment.isHeadless()) {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

// Second solution
GraphicsEnvironment ge;
do {
    ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
} while (ge.isHeadless());

不幸的是,这些解决方案并不起作用:isHeadless()始终返回true ,因此它永远不会退出循环。是的,此时我已经在使用Unity(Ubuntu图形界面),所以我已经拥有了一个满满的环境&#34;。对不起,如果我犯了一些错误,但我是UNIX / Linux的新手。

如果您需要任何进一步的信息,请询问我,我会提供。解决方案也必须是非GUI特定的(例如:仅适用于GNOME或Unity,必须适用于所有这些)。

修改

您可以检查/etc/init.d/内的.sh脚本,并负责使用系统启动JAR。包含@ that-other-guy提供的脚本。

#!/bin/sh
SERVICE_NAME=labspy_client
PATH_TO_JAR=/var/lib/LabSpy/Student.jar
PID_PATH_NAME=/tmp/labspy_client_pid
case $1 in
    start)
        echo "Starting $SERVICE_NAME ..."
        if [ ! -f $PID_PATH_NAME ]; then
                export DISPLAY=:0
                until xwininfo -root > /dev/null
                do
                    sleep 5
                done
                nohup /opt/java/bin/java -jar $PATH_TO_JAR /tmp 2>> /var/log/labspy_stdout >> /var/log/labspy_stderr &
                        echo $! > $PID_PATH_NAME
                echo "$SERVICE_NAME started ..."
        else
                echo "$SERVICE_NAME is already running ..."
        fi
    ;;
    stop)
        if [ -f $PID_PATH_NAME ]; then
            PID=$(cat $PID_PATH_NAME);
            echo "$SERVICE_NAME stoping ..."
            kill $PID;
            echo "$SERVICE_NAME stopped ..."
            rm $PID_PATH_NAME
        else
            echo "$SERVICE_NAME is not running ..."
        fi
    ;;
    restart)
        if [ -f $PID_PATH_NAME ]; then
            PID=$(cat $PID_PATH_NAME);
            echo "$SERVICE_NAME stopping ...";
            kill $PID;
            echo "$SERVICE_NAME stopped ...";
            rm $PID_PATH_NAME
            echo "$SERVICE_NAME starting ..."
            nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
                        echo $! > $PID_PATH_NAME
            echo "$SERVICE_NAME started ..."
        else
            echo "$SERVICE_NAME is not running ..."
        fi
    ;;
esac 

1 个答案:

答案 0 :(得分:3)

使用DISPLAY环境变量确定用于图形程序的显示。这通常由X会话设置并从X会话继承。

如果您认为合适的显示服务器将在不久的将来启动并运行,您可以猜测它的显示数量 - 可能是:0 - 并等待它响应。

我真的不相信Java会在首次初始化后重新检查显示是否有效,所以这里是一个shell脚本循环:

export DISPLAY=:0
export XAUTHORITY="/home/youruser/.Xauthority"
until xwininfo -root > /dev/null
do
  sleep 5
done
echo "X server is now running"

这是一个高度反Unix的解决方案,由您的Windows风格要求假设只有一个屏幕并且您需要控制它。

表现良好的Unix程序不会像这样对系统起作用,而是让用户在他们选择的显示器上启动服务器。