Is there a way to determine if Java System.in is "interactive"? - java

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.

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.

How to write to OS system log in 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

java/c++ How does output work? cout<< System.out.print

I am mostly concerned with Linux but answers involving windows are welcome.
When I use System.out.println or cout<< what is actually happening and what happens when I do a cout in a gui application (does it go anywhere)?
One case that I am interested in is the Netbeans IDE. When I run a java program in Netbeans what makes it possible for the IDE to "steal" the output from the program and display it?
Update/Sidenote
http://www.linfo.org/standard_output.html
One of the features of standard output is that it has a default
destination but can easily be redirected (i.e., diverted) to another
destination. That default destination is the display screen on the
computer that initiated the program. Because the standard streams are
plain text, they are by definition human readable.
What is meant by "initiate the program"?
I'm not very familiar with how the execution of a program begins but in the case of my netbeans example it's pretty clear that the IDE initiated the program. So what does that mean? When the program is being setup to be executed is there some meta data that is floating around letting the OS know that Netbeans is initiating the program?
When the program gets executed, three special file descriptors: stdin, stdout and stderr are associated to some device to determine how input and output is managed. If you execute a program from a terminal shell, stdin is associated to the keyboard, stdout and stderr to the terminal window. When you execute the program in a development environment usually stdout and stderr are displayed in some special console tabs. In other situations the output goes to some log file or maybe get discarded...
System.out and cout are the objects representing the stdout stream in Java and C++.

daemonize java program - go background after input some data

I tried to find a solution for the following use case (on Linux):
Start the program, show some information to the stdout, input some information such as username/password.
The program validate the username/password, then goes to background and run as a daemon.
I did not find a way to do this in Java. There are several sulotions to daemonize java program (such as jsvc, or this: http://barelyenough.org/blog/2005/03/java-daemon/ ). But seems they all do not work for this situation, because the program just goes to background from the beginning, there is no chance to input information before it goes to background.
I don't believe that there's a way to do this purely in java. You could make it work by writing an init script which accepted the command line parameters before spawning the java process in the background. You could use -D command line arguments to pass the user input to the java process.

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.

Categories

Resources