I do have some serious troubles understanding the console in java. I am running Eclipse, and I wanted to write a small program which prompts a few text messages to the console and receives a few strings as input arguments from it. Problem is: When I run my program, it opens the command line window properly, but my outputs are only printed on the Eclipse-Console.
In some way, I do understand why this is the case. The Command Line Windows expects commands, and not just some kind of a string or something. But how do i manage to output my Strings into the Command Line Window and read Strings from it, and not just commands.
Or am I doing it the wrong way? Do I have to open another "Console" where all my messages will be prompted and from which i can read strings a user wrote?
This is the code i use to open a command line window on start:
public static void main(String args[]) throws Exception {
Process process = new ProcessBuilder(new String[] { "cmd", "/C",
"start", "cmd" }).start();
System.out.println(process.waitFor());
Edit: I did still not manage to get this to working. Somehow, when I compiled the program, and I run it, it properly opens a command window, but no messages are posted there. Seems like "System.out.println("xxx") does not have any effect on this window.
There's no "console" specified by your program, but an stdin, stdout and stderr for input, output and error output. When you run your program from windows, these streams are bound to a command window, and if you run it in eclipse, they will be associated to the eclipse console. To give a more obscure example, ff you were running it through ssh, the streams would be associated to ssh, and ssh associated to your command window, and so on.
So, you're not doing anything wrong, you just need to run the program from the command line if you want stdout and stdin to come from that command window.
How do you open a command window, by the way?
You might want to read through this page:
http://pages.cs.wisc.edu/~hasti/cs368/JavaTutorial/NOTES/JavaIO_Scanner.html
Basically what you need to is create the input stream, tell the user to input something, and then get the input. E.g.
private static Scanner newScanner = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Put your input here: ");
String inputValue = newScanner.nextLine();
System.out.println(inputValue);
}
Just remember to import the scanner library!
Related
I am making simple console app. My main loop looks like this.
var s = new Scanner(System.in);
while (appShouldRun) {
var action = s.nextLine();
// proccess action
}
It works fine when I run app with empty stdin.
java -jar app.jar
But I want to have some prepared scenarios in file. Run them and then wait for next user input.
Expected behaviour:
java -jar app.jar < scenario.txt
output of commands from file
| <- cursor, waiting for user input
// scenario.txt
cmd1
cmd2
cmd3
.
.
.
Problem is that when I run program with something od std in, it process commands correctly, but then it throws
java.util.NoSuchElementException: No line found
I think it's becouse stdin is closed after all lines from file is processed.
Am I wrong?
How to fix the code to get expected behaviour?
Thanks
When you redirect standard input with <, it is connected to the input file, and not connected at all to the console.
If you want your program to receive input on the console, then you can't redirect stdin. You should take the filename as a command-line argument instead. Open it, read it, close it, and then process stdin.
OR, if you really want to, and you're on a unix/linux/macOS system, you can run it like this, using the cat command to concatenate standard input to something else:
cat scenario.txt - | java -jar app.jar
I have tried do change as little code as possible. This reads the whole file like you wanted and ends without Exception
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean appShouldRun = true;
while (appShouldRun) {
String action = s.nextLine();
System.out.println("got: " + action);
appShouldRun = s.hasNext();
}
}
}
Here is a piece of code to read user input using Scanner.
Scanner inner = new Scanner(System.in);
Logger logger = Logger.getLogger("Test");
logger.info("Before");
int a = inner.nextInt();
logger.info("After");
......
When I use ant to run a java task and excute my code(with "fork=true"), the program get stuck after printing "Before". I can input anything but the "After" never get printed.
However, when using command line java:
java -cp build/BoxBugRunner.jar:lib/gridworld.jar com.perqin.boxbugrunner.BoxBugRunner
the input is accepted and everything works fine.
It seems that System input cannot be access when using ant to run java program, so how to solve this problem?
Instead of using System.in you should:
Split your program in the part before and after the input. In the build script execute the first part, then get the input via the Ant input task, and finally execute the second part with the entered parameters.
Or write your your program as Ant task that delegates to the Ant input task for prompting for input.
Basically I have 2 commands I need to execute via a java program the way you would if you were just typing it into terminal.
so like
cd /Users/nameOfUser/Desktop/someFolder/someSubFolder
and then another command I want to execute within that directory. Currently I am doing this:
Process navigate = Runtime.getRuntime().exec("cd /Users/nameOfUser/Desktop/someFolder/someSubFolder");
Process doSomething = Runtime.getRuntime().exec("commandInThatDirectory");
Which doesn't work, it doesn't throw an exception but the second process doesn't seem to take place in the directory specified before it. I am new to processes and runtimes so please bear with me :P.
Is their a way to execute the commands back to back within the same instance of terminal or at least a format for 1 command where you can specify the directory for another command to take place in? I'm a linux user so I don't know mac terminal very well sorry.
It can be done something like this. you can run any command by by placing a semicolon between the commands.
public class Main {
public static void main(String[] args) throws IOException {
ProcessBuilder pb1 = new ProcessBuilder(
"bash",
"-c",
"cd /Users/nameOfUser/Desktop/someFolder/someSubFolder;commandInThatDirectory");
pb1.redirectErrorStream(true);
Process p = pb1.start();
}
}
So I'm creating a Java program and I want to make it so that you can ask it to open a program.
But, here's the catch, I want the program it opens to be taken from the user input, right now I'm trying to change this
try{Process p = Runtime.getRuntime().exec("notepad.exe");}
catch(Exception e1){}
Into something that opens a program that you asked it to open.
Here's an example of what I want:
User: Can you open chrome?
Program: Of course, here you go!
chrome opens
Could anyone tell me how I would be able to do this?
You can do it in two ways:
1.By Using Runtime:
Runtime.getRuntime().exec(...)
So, for example, on Windows,
Runtime.getRuntime().exec("C:\application.exe -arg1 -arg2");
2.By Using ProcessBuilder:
ProcessBuilder b = new ProcessBuilder("C:\application.exe", "-arg1", "-arg2");
or alternatively
List<String> params = java.util.Arrays.asList("C:\application.exe", "-arg1", "-arg2");
ProcessBuilder b = new ProcessBuilder(params);
or
ProcessBuilder b = new ProcessBuilder("C:\application.exe -arg1 -arg2");
The difference between the two is :
Runtime.getRuntime().exec(...)
takes a single string and passes it directly to a shell or cmd.exe process. The ProcessBuilder constructors, on the other hand, take a varargs array of strings or a List of strings, where each string in the array or list is assumed to be an individual argument.
So,Runtime.getRuntime.exec() will pass the line C:\application.exe -arg1 -arg2 to cmd.exe, which runs a application.exe program with the two given arguments. However, ProcessBuilder method will fail, unless there happens to be a program whose name is application.exe -arg1 -arg2 in C:.
You can try it with like. Pass whole path of where you install chrome.
try{
Process p = Runtime.getRuntime().exec("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe");
}
catch(Exception e1){
}
When using exec, it is essentially the same as if you were using the command line on windows. Open Command Prompt, type open, and see if it gives details as to how it opens files. If not, find the opener. Usually when dealing with command line operations, there are multiple parameters that are required for opening files/applications. An example of this would be for opening the "TextEdit.app" application on a mac.
Process p = Runtime.getRuntime().exec("open -a TextEdit.app");
Terminal(for mac) would open the app using the -a flag, meaning "application." You could open a file doing:
Process p = Runtime.getRuntime().exec("open filename.file_ext -a TextEdit.app");
The second one will tell the computer to find the application named <app_name>.app and open the file filename.file_ext
I know this is not going to work for a windows machine, but it's only to show how to use the command line operations for opening files and applications. It should be similar for windows though.
Hope this helps
I usually run this program via a command line like so:
java Program <TestClass.java
Which as I understand, forces the contents of TestClass.java to the console as user input.
i.e. It would be like executing
java Program
and then typing what ever is in TestClass.java
My problem is getting this happening in Eclipse. I can't figure out how to do it.
I would have thought that adding
<TestClass.java
to the program arguments in the run configuration would work, but it seems not.
Any suggestions?
How about adding this on top of your main.
InputStream in;
if (args.length > 0) {
in = new FileInputStream(args[0]);
} else {
// fallback
in = System.in;
}
And then you add the filename as an argument, as if you're running java Program TestClass.java. This way, it will work whether you run it as before or using the filename as an argument.