2

I have written a server in Java that allows clients connected to it to control the mouse and keyboard of the computer. To do this it uses the java.awt.Robot class.

I need this server to run in the background and start automatically. The first OS I am tackling this problem on is Debian based (Ubuntu 11.04) and a daemon seems like the obvious choice. The problem is that when the daemon is started during boot or during the installation of my debian package (whose postinst script starts it using /etc/init.d/pc-remote-server start) I get this error:

java.awt.AWTException: headless environment
    at java.awt.Robot.<init>(Robot.java:97)
    at com.se.pcremote.server.CommandExecuter.<init>(CommandExecuter.java:72)
    at com.se.pcremote.server.PCRemoteServer.<init>(PCRemoteServer.java:215)
    at com.se.pcremote.server.PCRemoteServer.main(PCRemoteServer.java:122)

Is there any way I can use the java.awt.Robot class from within a daemon process? Could I spawn a secondary process from the daemon process that is not a 'headless environment'? Or is there a better way for me to get a 'service' like result that does not have this limitation?

Gyan aka Gary Buyn
  • 12,242
  • 2
  • 23
  • 26

3 Answers3

1

"Headless" means that this code needs access to a graphics environment, and it hasn't.

You can run in headless mode by supplying a system property which provides a crude implementation which gives just the basics for running applications, but which most likely cannot support Robot. Try it however first.

If you cannot do that, you need a graphics environment for your process. The usual way to do this is to run a VNC X-server as it doesn't require physical hardware, and then connect to it.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • After testing combinations of setting/not setting `DISPLAY=:0.0` and setting `java.awt.headless=true` or `java.awt.headless=false` I think I've determined that: 1) When there is no `DISPLAY` environment variable, Java goes into headless mode. 2) If you set one manually it tricks Java to **not** go into headless mode. 3) You can set `java.awt.headless` to override whatever Java decided when it started. 4) If you try to trick Java, it will just crash instead of throwing an exception gracefully. – Gyan aka Gary Buyn May 23 '11 at 08:16
  • I'm going to look up this VNC business now. – Gyan aka Gary Buyn May 23 '11 at 08:17
  • I've figured out how to start a VNC server using x11vnc and to start a client with tightvnc but that opens a window showing the screen you want to control (as you'd expect). Is there a way to connect without opening a window and then to run a shell command in that environment? – Gyan aka Gary Buyn May 23 '11 at 09:48
1

I assume, you must set the DISPLAY variable correctly (in the environment of the robot process at the time when the robot process is started) for this to work -- in your case you would need to specify a display in your DISPLAY variable which is created some time after the program is started. --

No idea whether this really works, but you could give it a try and report back here whether it works.

BertNase
  • 2,374
  • 20
  • 24
  • I just tried setting and exporting the DISPLAY environment variable in the deamon script before it starts. When the server started I printed all the environment variables from within Java which included DISPLAY=:0.0 but it looks like it crashed when attempting to instantiate the Robot (no exception). I never see anything in var/log/daemon.log – Gyan aka Gary Buyn May 23 '11 at 07:58
1

Alright, after doing some more research and trying some more options here is what I came up with:

Can I use java.awt.Robot from within a daemon? No.

Further down in my question I elaborated a little:

Is there any way I can use the java.awt.Robot class from within a daemon process? No. As above.

Could I spawn a secondary process from the daemon process that is not a 'headless environment'? Not that I could figure out. It was going to be a lot of work if I did do it anyway.

Or is there a better way for me to get a 'service' like result that does not have this limitation? Yes! Use the desktop environment! In my case since I was using Ubuntu the desktop environment was Gnome. Gnome has a Startup Applications feature that runs off .desktop files on a global and per-user basis as described here. They also provide information on the structure of these .desktop files here. I added a .desktop file to /etc/xdg/autostart (the global autostart folder) that ran my Java 'service' and it worked like a treat.

Gyan aka Gary Buyn
  • 12,242
  • 2
  • 23
  • 26