I'm writing a program which monitors Java Applications. I'd like to monitor the state of the native processes and know when they exit. This is fine; Java gives me the Process object and I can waitFor() on it.
However, the problem that arises is that if my program dies, I would like it to get the reference to the process back - which it can't do in Java because it never created the process. My first guess was to send the process object over RMI and have the client app send it back when a reconnection occurs, but that won't work because Process isn't serializable.
I can think of a way to do this natively using JNA on Windows, but does anyone know if there is an existing library which will do this?
Cheers!
You can use WMI to implement this on Windows and command line utilities on Unix (if you need).
I know the following tools to work with WMI: JaWin, WIntegra, JInterop.
If your monitor is running in windows too you can use JaWin. It is a JNI wrapper over COM+ API. If you want to be cross platform and be able to monitor Windows machine from Unix machine use JInterop. It is open-source library that implements DCOM protocol in pure java. JIntegra is similar but commercial.
EDIT: probably even simpler solution. If you want to monitor java application just use JMX. Connect to this application using JMX either remotely or locally.
Good luck.
Related
I work on a Macbook and I would like to close some running applications such as Remote Desktops through using Java.
I'm quite new to programming in Java and other than Google and StackOverflow I'm not sure where to go. I already looked for a solution on Google but all I can find are instruction on how to close Java on Mac OS, not actually how you close a running application through Java code.
So I am looking for some pointers on what Java commands I should use to close a running application in Mac OS. Thank you very much :)
While programming in Java, you only have access to do things inside the JVM. But your code inside the JVM wouldn't usually have permissions to affect other processes running on the operating system.
You can definitely call an external command with something like this:
Process process = Runtime.getRuntime().exec("kill 12345");
That would run the kill command on process id 12345. This would work, assuming you have the right permissions.
You can get more information on the exec command in the docs: https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#exec(java.lang.String)
I'm running a J2SE application that is somewhat trusted (Minecraft) but will likely contain completely un-trusted (and likely even some hostile) plugins.
I'd like to create a plugin that can access the GPIO pins on the Raspberry PI.
Every solution I've seen requires that such an app be given sudo-superpowers because gpio is accessed through direct memory access.
It looks like the correct solution is to supply a command-line option like this:
-Djava.security.policy=java.policy
which seems to default you to no permissions (even access to files and high ports), then add the ones your app needs back in with the policy file.
In effect you seem to be giving Java "sudo" powers and then trusting java's security model to only give appropriate powers out to various classes. I'm guessing this makes the app safe to run with sudo--is this correct?
Funny that I've been using Java pretty much daily since 1.0 and never needed this before... You learn something new every day.
[Disclaimer: I'm not very convinced by the Java security model.]
The way I would solve this is to have the code that needs to access the hardware run as a separate privileged process, then have your Java application run as an unprivileged process and connect to the privileged process to have it perform certain actions on its behalf.
In the privileged process, you should check with maximum distrust each request whether it is safe to execute. If you are afraid that other unprivileged processes might connect to the daemon too and make it execute commands it shouldn't, you could make its socket owned by a special group and setgid() the Java application to that group by a tiny wrapper written in C before it is started.
Unix domain sockets are probably the best choice but if you want to chroot() the Java application, a TCP/IP socket might be needed.
I wrote Java SE program which has deal with really huge dataset of matrices(10^12 matrices). I am generating them through iterator and saving special ones (which satisfy some criteria) either to Java heap or database. So, I understand that it's gonna take a lot of time (probably a few days). In order to operate with all this stuff I decided to run the program on computer which is not at my apartment and has access to the Internet. I want to control runnig process of the program (for me is very important to know is everything OK with the program? Is the program still running?)
My question is how to control that my program is still running (for this purpose I want to use computer at my appartment and the Internet)?
Maybe my program should periodically post (via Java IO API ) messages to websites ( Google Docs and so on). Thanks in advance for all your responses.
Run your application with JPDA enabled. This way you can connect it remotely, examine threads, etc.
JPDA has a number of other advantages as well, for example hot code replace.
Specification for JPDA is here, the most important is that you have to pass a few JVM options on startup, it will open a port, and you can use Eclipse or NetBeans to attach it from anywhere on the net. You have to make sure that the opened port is accessible through firewalls (local and network).
I would go for VisualVM & remote JMX. Setup the server box to allow remote jmx connections. With VisualVM you'll be able to connect to the JVM and check the activity.
You can also set up MBeans to keep stats of the running process. Which you'll be able to check also with VisualVM.
First you should try a remote desktop connection. Here's link to MS documents for Windows 7 remote desktop.
If the remote computer is Linux/Unix, and your program is console application, ssh+screen is the old, true and tested solution to leave interactive console programs running and accessible from anywhere, while you frolic in the real world.
Is it possible to stop an application in windows using java code ?
I'd like to create a program which is like a shortcut to stop an application on my pc. Is it possible using ProcessBuilder ? Thank you
Plain Java, without native access? No.
ProcessBuilder lets you control processes that you started from within the Java application, but it doesn't give you control to processes that were started by other processes.
As per user988052's comment, you can use pskill from the Sysinternals Suite to accomplish this through Runtime.exec. pskill uses the TerminateProcess function call. You can also call this function with JNI (or some other native caller, like JNA, NLink, etc.), but you'll need to obtain a handle to the process via the OpenProcess function call.
Is it possible to stop an application in windows using java code ? ... Is it possible using ProcessBuilder ?
Only if you launched the application from the same Java application that you are trying to fill it from.
Other than that, you need to resort to running a Windows-specific command to do the killing ... or something based on JNI to make native Windows library calls.
The other complications are that you may not be able to kill certain processes due to permissions issues, and some process may refuse to be killed.
I believe the JRE does not provide an API for system processes. ProcessBuilder can create system processes, but it cannot provide you with a Process object for a process created outside the JVM. I believe that is a philosophical decision on the part of the Java folks, to avoid certain OS-specific tasks where possible. You might think that every OS has pids, or that they all have some kind of kill message, but Java runs on lots of OSes, some of them quite strange.
You could make native code to do it and wrap that with JNI, but that would be wasteful. As Mr 988052 says, I suggest you execute a system-specific command through Runtime.exec or ProcessBuilder. You would need to decide which OSes you want to support, and be sure to get the commands (and the OS-detection code) right for each one.
We have a curious problem with our java processes dying.
The application doesn't stacktrace, or write anything to the logs, the process just randomly dies. It's a heavily used application, but the problem only appears about once a month.
We're currently looking into using Process Monitor but any other suggestions would be welcome.
Edit:
It's a distributed Java application, running on Weblogic with an in-house web framework (Yes, this is a terrible idea, but it's been running for eight years), connecting to Oracle.
-
Out of Memory?
Our logs would catch java.lang.OutOfMemoryException, according to Brian Agnew.
Write crashes to a log? I don't think Java ever gets the chance, the death is happening at a process level, rather than Java exiting.
Can you wrap it in some shell script that captures the log files (stdout/stderr) and the exit code (which should give some indication as to how it died) ? On JVM exit you can also capture machine level stats using WMI
IF the VM itself is crashing it'll leave behind an hs_err_pid... file that contains stacktraces, machine-level debug info. You can then use that to diagnose the VM issue. See this blog entry for further information.
If the problem is related to the app's behaviour, it may be worth looking at JConsole, although from your description of the issue, this sounds much more like a low level VM issue.
(I assume you're on the latest VM for your Java version number etc.)
You can use a Linux NAGIOS Server to monitor the health of your Windows machines and services! Have a look at: nagios-monitoring-windows.
If you have such problems with your java app! You should test it and debug it! Applications shouldn't die without a trace! Look for logfiles! From which vendor is the app? Or is it self written? Try to enforce another Log4J/Logger/Debug Level. Monitor your System with cacti etc. to reduce the possibilities for such a crash. Talk to the software vendor.
Is enogh memory available? Maybe the app runs out of memory? Is it a standalone java process or a java process from a tomcat/jboss server?
Have you written down the crash times to a log? Appear they in different time-slices? Or appear they nearly time-circular?
VisualVM is a new tool which makes monitoring Java applications easier:
https://visualvm.dev.java.net/description.html
"VisualVM is a tool that provides detailed information about Java applications while they are running. It provides an intuitive graphical user interface that allows you to easily see information about multiple Java applications."