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?
"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.
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.
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.
Related
I would like to implement a java application (server application) that can download a new version (.jar file) from a given url, and then update itself at runtime.
What is the best way to do this and is it possible?
I guess that the application can download a new .jar file and start it. But how should I do the handover, e.g. know when the new application is started and then exit. Or is there a better way to do this?
The basic structure of a solution is as follows:
There is a main loop responsible for repeatedly loading the latest version of the app (if required) and launching it.
The application does its thing, but periodically checks the download URL. If it detects a new version it exits back to the launcher.
There are a number of ways you could implement this. For example:
The launcher could be a wrapper script or binary application that starts a new JVM to run the application from a JAR file that gets replaced.
The launcher could be a Java application that creates a classloader for the new JAR, loads an entrypoint class and calls some method on it. If you do it this way, you have to watch for classloader storage leaks, but that's not difficult. (You just need to make sure that no objects with classes loaded from the JAR are reachable after you relaunch.)
The advantages of the external wrapper approach are:
you only need one JAR,
you can replace the entire Java app,
any secondary threads created by the app, etc will go away without special shutdown logic, and
you can also deal with recovery from application crashes, etc.
The second approach requires two JARs, but has the following advantages:
the solution is pure Java and portable,
the changeover will be quicker, and
you can more easily retain state across the restart (modulo leakage issues).
The "best" way depends on your specific requirements.
It should also be noted that:
There are security risks with auto-updating. In general, if the server that provides the updates is compromised, or if the mechanisms for providing the updates are susceptible to attack, then auto-updating can lead to a compromise of the client(s).
Pushing a update to a client that cause damage to the client could have legal risks, and risks to your business' reputation.
If you can find a way to avoid reinventing the wheel, that would be good. See the other answers for suggestions.
I am currently developing a JAVA Linux Daemon and also had the need to implement an auto-update mechanism. I wanted to limit my application to one jar file, and came up with a simple solution:
Pack the updater application in the update itself.
Application: When the application detects a newer version it does the following:
Download update (Zipfile)
Extract Application and ApplicationUpdater (all in the zipfile)
Run updater
ApplicationUpdater: When the updater runs it does the following:
Stop the Application (in my case a daemon via init.d)
Copy the downloaded jar file to overwrite current Application
Start the Application
Cleanup.
Hope it helps someone.
I've recently created update4j which is fully compatible with Java 9's module system.
It will seamlessly start the new version without a restart.
This is a known problem and I recommend against reinventing a wheel - don't write your own hack, just use what other people have already done.
Two situations you need to consider:
App needs to be self-updatable and keep running even during update (server app, embedded apps). Go with OSGi: Bundles or Equinox p2.
App is a desktop app and has an installer. There are many installers with update option. Check installers list.
I've written a Java application that can load plugins at runtime and start using them immediately, inspired by a similar mechanism in jEdit. jEdit is open source so you have the option of looking to see how it works.
The solution uses a custom ClassLoader to load files from the jar. Once they're loaded you can invoke some method from the new jar that will act as its main method. Then the tricky part is making sure you get rid of all references to the old code so that it can be garbage collected. I'm not quite an expert on that part, I've made it work but it wasn't easy.
First way: use tomcat and it's deploy facilities.
Second way: to split application on two parts (functional and update) and let update part replace function part.
Third way: In your server appliction just download new version, then old version releases bound port, then old version runs new version (starts process), then old version sends a request on application port to the new version to delete old version, old version terminates and new version deletes old version. Like this:
This isn't necessarily the best way, but it might work for you.
You can write a bootstrap application (ala the World of Warcraft launcher, if you've played WoW). That bootstrap is responsible for checking for updates.
If an update is available, it will offer it to the user, handle the download, installation, etc.
If the application is up to date, it will allow the user to launch the application
Optionally, you can allow the user to launch the application, even if it isn't up to date
This way you don't have to worry about forcing an exit of your application.
If your application is web based, and if it is important that they have an up to date client, then you can also do version checks while the application runs. You can do them at intervals, while performing normal communication with the server (some or all calls), or both.
For a product I recently worked on, we did version checks upon launch (without a boot strapper app, but before the main window appeared), and during calls to the server. When the client was out of date, we relied on the user to quit manually, but forbid any action against the server.
Please note that I don't know if Java can invoke UI code before you bring up your main window. We were using C#/WPF.
If you build your application using Equinox plugins, you can use the P2 Provisioning System to get a ready-made solution to this problem. This will require the server to restart itself after an update.
I see a security problem when downloading a new jar (etc.), e.g., a man in the middle attack. You always have to sign your downloadable update.
On JAX2015, Adam Bien told about using JGit for updating the binaries.
Sadly I could not find any tutorials.
Source in German.
Adam Bien created the updater see here
I forked it here with some javaFX frontend. I am also working on an automatic signing.
I am writing an android SSH Client. I have a terminal object that controls the view and an SSH object to send commands to the server.
My problem is that the terminal displays in color during all sessions but when an ncurses application opens, (tmux for example), the terminal displays in black and white.
I was able to find this: http://invisible-island.net/ncurses/ncurses.faq.html#white_black
I am not really sure what that means. Can anyone guide me on more documentation on this, or if there are any open source Java clients that support this feature. I am not really sure how to fix this.
Ok, so you launched the application without the TERM environmental variable set appropriately, and that meant that during the initialization routines the remote operating system believed it wasn't talking to a terminal that could support colors.
Now that you have it set correctly, your colors work. Congratulations! However, setting it inside the application is going to be quite a trick. This is because it needs to be set before you application launches. Otherwise, when the application launches, the low level libraries you are linking into will query the "environment" to see what kind of terminal it has, which determines what kind of terminal codes will be emitted by your application.
This all happens before you app launches; so, effectively, you can't really do it from your application. However, the real solution is a bit more interesting.
SSH makes very few assumptions about the display capabilities of the remote machine. The best way to "fix" this is to have the SSH client set the terminal type according to the SSH client's capabilities. Check your ssh client configuration to see if you can pass in a "better" terminal type.
In fact, having the host operating system assume the client's capabilities will create issues; however, demanding that every ssh client be configured to hand off it's terminal capabilities properly can be logistically impossible. So, you may want to strike a compromise. On the ssh server machine, try dropping a "wrapper script" to launch the application with a color terminal script. It would read something like
#!/bin/sh
TERM=xterm-256color
export TERM
exec launch-app "$#"
and be saved as launch-app-color or something similar.
want to make a check in my installer before starting installation if any other installation is running beforehand. Like I want to make a check if windows update or any other installer is running i'll not start my installer.
I'm planning to check if any msiexec instance is running before hand. Is there any better approach, and will that be same for checking windows update. FYI my installer is in java
You should know that msiexec.exe will still be running for a couple of minutes after an installation is finished. This is a default behavior in the OS, it keeps the process alive for a couple of minutes, in case the user will start another installation, to save time from starting it all over again. So checking for the process could give you incorrect data.
Also, if you have your installer written in Java can you please explain why do you need to check for msiexec.exe processes?
Since your installer is in Java, I see no reason to check whether other installers are running, moreover there's no robust way to do so.
Does your installer try to replace system files? It should not.
Does your installer try to update a file in use? It must do it gracefully. And ask user to close an offending application; if it's not possible or user does not want to close the application right away, your installer asks user to restart the system when it completed installation.
Too much to care about, without other installers running. That's why it's wiser to use a specialized installer tool.
To check the OS for installations in progress you can use the following registry entry:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\InProgress
Please note that Windows Installer does not allow multiple InstallExecuteSequences to be executed simultaneously, however you can launch multiple installation UIs from different packages. The package enters InstallExecuteSequence usually at the moment you press "Install" and grant all the permissions for starting the system changes (creating registry, copying files, etc...).
Here you can find more information about InstallUISequence and InstallExecuteSequence:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa372404(v=vs.85).aspx
Thank u guys for your suggestions, I final decided to go with creating a windows native dll to check the status of WindowsInstaller. The Windows Installer service is currently running if the value of the dwControlsAccepted member of the returned SERVICE_STATUS_PROCESS structure is SERVICE_ACCEPT_SHUTDOWN. Then used JNI to to call it from my java class.
I have a Java program using AWT which I would like to run on a headless system. The display for the program does nothing other than display stats. When the program finishes, it exits. There is no user interaction on the display. The program creates an output file which I use in my build system.
Is there a way to get the Java program to run without an X11 display configured? Can I force Java to run the program without trying to display anything? I do not have access to the source code (it is just .jar file), so I can't make modifications to the source.
Any thoughts on how I could get this to work?
The underlying question here is how to run Java applications without an X server; providing a "fake" X server is only one option. In Java 1.4 and up, you can do the following:
java -Djava.awt.headless=true
This allows applications which use AWT to run on headless systems even without an X server.
Xvfb can do what you ask for. I've not used it myself, but here is a link to wikipedia: http://en.wikipedia.org/wiki/Xvfb
You can use a vncserver.
vncserver :1001
export DISPLAY=localhost:1001
java..
The added advantages is that you can actually view the gui
using vncserver 'just in case'
Could also run Xvnc in a low resolution and color depth.
As mentioned by Charles Duffy the traditional method is to tell Java to go headless.
Note that you can always mount the jar in Eclipse and use jad+jadclipse to see what it actually does, and perhaps even override a class if you need to by putting another class-file in "front" of it in the classpath.
A facility that might be relevant if the program uses Java2D is that newer Java versions use optimizations in the X11 server to render faster. This alone might be a reason to devote an X11 server attached to a high performance graphics card to your graphics processing.
I've used with great success in the past the PJA libraries, they don't seem to be maintained anymore, but then again, just just want to run...
I was able to get headless mode in OpenJFX with the command line arguments
-Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw
I am using Tomcat 5.5.23, JDK 1.5 on HP Unix. We have an application which when invoked form tomcat starts an applet. It was working fine till JDK 1.4. But now we have moved to JDK 1.5 and the applet does not start. The exception thrown is -
java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
I then added JAVA_OPTS="-Djava.awt.headless=true" to catalina.sh file. But still I get the same Headless exception, but this time without the X11 Display message.
Any help would be appreciated.
Odd.. you're trying to run an applet (I assume you are talking about a subclass of java.awt.Applet) inside tomcat? Generally this won't work because there's no display on which to display the applet.
Assuming you don't want the applet to display anywhere and you just want to execute some portion of it programmatically, you may be able to get by using a virtual X server such as Xvfb or Xvnc. Once you have Xvfb or Xvnc running on your host running tomcat, you might try to set the DISPLAY inside the tomcat startup scripts to use the display of the virtual X server.
-Djava.awt.headless=false
add above in your Tomcat startup script. it will work 100%
You are maybe using something in your Java code that can not work on a headless system, such as graphics components (Swing objects, images, etc.). Some of these components, instead of being directly handled by Java, are handled by underlying platform (Windows kernel itself or X-Window server on Unix). This way the overall performance of application is boosted.
So the question now is, ok if it was working on Java 1.4, why doesn't it work on 1.5? My bet, given the peformance boost since Java 1.2 that Swing has received over time, is that Sun has moved the management of some graphic objets to OS level to increase performance. So if you can not stick to 1.4, then you should revise your code.
This good article will help you understand how to modify your application to make it headless-friendly.
Applets are going to have a hard-time running server-side. They are designed to run inside of a container, such as a web browser. The exception is getting thrown most likely because the applet is trying to draw it's GUI -- and the server is providing no support for this. I'm surprised that it worked in JDK 1.4 -- I don't know what changed between the two revisions which would have affected this.
You may also have to install the x11 libraries, or at least explicitly export the path to them.
/usr/X11R6/lib
Open $CATALINA_HOME/bin/startup.sh file with your preferred text browser
Paste this line export CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=false" at the beginning of the file
Save and close the file
Restart Tomcat
In spring boot with database access, when you specify asterisks: **** as username and password, it will try to prompt the user for a username and password (you read that right), and it will throw this HeadlessException if it's not a gui application.