How to write to OS system log in Java? - java

Mac OS has an application called Console, which contains logged messages, errors, and faults. I believe the Windows equivalent is Event Viewer. I'd imagine there is one on Linux as well, but I don't know anything about it or where it is.
Is it possible to get a message from Java output to a system log like this? I'm writing a GUI-based application, so there is nothing running from the command line. The standard System.out or System.err probably won't be of much use in this case, unless I'm missing something.
I have written a simple logging service for my application that writes to a dedicated log file, but I want to have some kind of failsafe in case an I/O error occurs while attempting to write to this file.
I know the IDE will display output via System.out and System.err just fine, but this is for if the end-user encounters a problem like this.
As an example: I've written "codeless language modules" for the application TextWrangler on the Mac. These modules are read by TW at application startup, and if there is an error while processing them, errors get logged and can be viewed in the Mac Console application.

On Linux it is called as syslog. One of the ways that you can achieve logging to console on Mac will be to use log4j 'org.apache.log4j.net.SyslogAppender'.
I think this link should give you some kickstart in this direction.

You can redirect System.out to a log file, and Mac's Console app is the default viewer for files ending in ".log".
One way this is commonly done is with a shell script that would invoke your Java program. In this Java 7 example, the output of invoking the main class MyClass is redirected to mylogfile.log. Everything that's written with System.out will be in mylogfile.log.
#!/bin/bash
for a in /path/to/my/jars/*
do
CLASSPATH=$CLASSPATH:$a
done
java -Xms128M -Xmx128M -XX:MaxPermSize=128M -cp ${CLASSPATH} com.example.package.MyClass >> mylogfile.log

Related

How to check if a Java application is running within a Terminal window (System.in/System.out are available) [duplicate]

If the input is interactive, i.e. from the console, I want to print a command prompt e.g. ">"
But if it is redirected e.g. from a file, then I do not want to prompt.
System.in is an abstract InputStream which does not appear to have any method for this.
Maybe you could use instanceof if the concrete type is different?
As well, if System.out is redirected to a file I also do not want to prompt
AFAIK, there is no way to do this in pure Java, and even doing it in JNI / JNA would be complicated.
An alternative might be to use the new Console API introduced in JDK 1.6. This allows you to try to get a reader/writer for the console. If it succeeds, the result is guaranteed to be interactive ... in the sense that you mean.
A second alternative would be to do the "check for interactivity" in the wrapper script that you use to launch your application, and pass the information to Java via the system properties. For instance, on a GNU/Linux system the tty(1) command can be used to tell if stdin is a connected to a "tty" device.
Note that there are other ways to deal with a requirement to avoid unwanted prompts when running non-interactively:
If System.out is redirected to a file I also do not want to prompt.
(I think you might mean that System.in is redirected. That is the normal way to non-interactively run an application that normally takes interactive input from the user ...)
The alternatives include:
You could modify the program to write the prompts to (say) System.err and redirect that to a different place.
You could modify the program to have options that mean "don't prompt" or "take input from a file".
Since Java 6 there is the method java.lang.System.console():
Whether a virtual machine has a console is dependent upon the
underlying platform and also upon the manner in which the virtual
machine is invoked. If the virtual machine is started from an
interactive command line without redirecting the standard input and
output streams then its console will exist and will typically be
connected to the keyboard and display from which the virtual machine
was launched. If the virtual machine is started automatically, for
example by a background job scheduler, then it will typically not have
a console.
If this virtual machine has a console then it is represented by a
unique instance of this class which can be obtained by invoking the
java.lang.System.console() method. If no console device is available
then an invocation of that method will return null.

Can someone without JDK run a program that uses the console for i/o (and has no other user interface or display)?

Essentially the question boils down to 'Is there a way to run a class/jar file using the console for input/output without having JDK'. I've written a program in Java for a colleague to use in his work, but he doesn't have/use JDK. I'm aware there are online compilers, but at this point my question has become focused on running a program directly for interest reasons.
Essentially the program is designed to output instructions to the user, the
user makes input in accordance with the instructions, and this goes back and forth for awhile before the program does some calculations based off the input and returns a final result.
I should mention that he has JRE.
My program doesn't use a GUI, it just prints instructions to the console and gathers input from responses typed in the console. It works fine on my computer when running it from the command line ('java myprogram'), but without jdk the java command isn't available to him, which seems to mean he can't run a class file.
My next attempt was to turn the program into an executable jar file, but using the command 'myprogram.jar' from the command line doesn't really do anything. The jar file does include a manifest. I added a blank screen to the code and running the jar file did create the screen, but still no i/o on the console. From what I've read, I think this is because jar files aren't automatically associated with a console, so there is nowhere for the program's output to go or input to come from. He can't use the 'java -jar myprogram.jar' command because he hasn't got the JDK, so even though that command runs the program the way I want it to, it's not an option.
Basically, I'm wondering if it's possible for someone without JDK to run a program and interact with it entirely using the console/command line and no other interface?

How do I write to the input stream of an already running java program?

I have a CentOS server which is currently running a java jar application. I need to write a php script to communicate with this running program via its input stream. The java program outputs its output to a log file so I don't need access to the output stream.
I don't want to restart the program, just access the running process and interact with it.
Can someone point me in the right direction?
If portability is not a big matter for you, why not creating your own pipe(s)? I don't know much about the java application but have a look at the "mkfifo" function/command.
First, find the ProcessID of the application. You may do it using:
ps -Af | grep java
Since you are using java, you may feel more convenient with the jps command for finding the PID.
I'll assume PID of the running application is 12345. It suffices to issue the command:
cat >/proc/12345/fd/0
And whatever you type in will be put in the standard input of that application. Note that fd contains the file descriptors used by the application, and I suppose the 0-th file descriptor would always be stdin.
Using PHP for writing into the file (and thus being consumed by the application as input) is possible as well.

Creating a console in Java

When I try to use java.lang.System.console(), I get a null pointer. I can still write to out and read from in, but this only works when I run straight from my IDE. When I run the .jar file directly, nothing happens. How can I create a console like I'd see using std::cout for use in Java?
Edit:
I was hoping to just create one, rather than understand why I don't have one, since I need one for my program's operation.
Perhaps you're trying to get the console by double-clicking in the jar
Try creating a batch file that opens the console for you.
You can however create a console using Swing and redirect standard input/output there.
Source: Create Java console inside a GUI panel
How are you running the JAR file exactly? That would be the expected behavior for double-clicking its icon in Windows Explorer, as Kelly alluded to, but not for firing it up from the command line.
From the Console entry in the API (emphasis mine):
Whether a virtual machine has a console is dependent upon the underlying platform and also upon the manner in which the virtual machine is invoked. If the virtual machine is started from an interactive command line without redirecting the standard input and output streams then its console will exist and will typically be connected to the keyboard and display from which the virtual machine was launched. If the virtual machine is started automatically, for example by a background job scheduler, then it will typically not have a console.
java.lang.System.out and java.lang.System.in are the input/output streams for console access. Java won't create a "console" but allows you to interact with the IO streams provided by the operating system.
When you run it from a jar file (like clicking on it from a folder) you'll get the I/O streams of the GUI which don't display anywhere.
Try creating a batch file with a 'java -jar ' command in it. When you run the batch file, you should see the command window. I'm assuming windows here. Another way is to run cmd.exe directly with arguments that keep the window open, i.e. "cmd.exe /c".
Instead of running the jar file directly, open a console (you didn't specify an operating system, but this would be the command line on Windows and a console on *Nix, or Terminal on OS X). Then, run java -jar /path/to/your.jar.
The equivalent of std::cout in Java would be System.out as you probably already know.
EDIT: With regards to your edit, there is code out there to do this. For example, you can use Swing. There's even a StackOverflow answer with more than one working code sample.
See JConsole, which is a general console in java, used for instance by groovy. Or see groovy directly.

Permission error while trying to access an (server) program started by a Java program

I am starting a server application (normally to be started from the Unix command line) by using Runtime.getRuntime().exec("path/mmserver"). My problem is now that as long as my Java program, which started that server runs, the server is correctly accessible (from command line and other programs). But when my Java program exits the sever is not accessible anymore (the process of the server is still running). I just get such a error message when trying to access the server: "Error: permission_error(flush_output(user_output),write,stream,user_output,errno(32))".
The server is a blackbox for me.
I am just looking for other ways to start a new process. And maybe someone has a hint why I get that permission error (even if one doesn't know what that server exactly is ... you rather won't know it).
I'm guessing your server program is trying to write to standard output or perhaps standard error (System.out / System.err in Java terms) which it implicitly inherited from your Java program but which turn into pumpkins when your Java program goes away.
A simple solution might be for your Java program to exec a shell script which starts your server as a background process (using START (Windows) or & (Unix)) with explicitly redirected I/O streams.
The Java library has recently gotten some nice updates to the Process class (I think) that allow you to do a lot of fiddling with the streams, but I don't have much experience there so I can't offer a detailed suggestion.
EDIT: My suggestion from the middle paragraph. Untested, sorry!
File server-runner.sh:
#!/bin/bash
/path/mmserver >/dev/null &
You'll need to chmod +x server-runner.sh, of course.
Then, from your Java program, you exec the script server-runner.sh rather than your mmserver.
If you want to kill mmserver, you'll have to find it in ps -ux and use kill on the process number.

Categories

Resources