Run Java class by passing parameters to Scanner

Asked

Viewed 424 times

3

Bestamos creating a programming championship in Java and we would like the students to make an algorithm that reads from a scanner and calculates a certain mathematical logic and returns in the system output.

Up to this point OK. The problem is that I am trying to perform an automatic corrector for the algorithms with this I need to run the java class and pick up the return to know if the calculation is right.

The central problem is that students use the scanner, so I can’t pass the parameters. With the class Rumtime.getRuntime().exec("java MinhaClasse); I cannot power Scanner, I tried to replace System.in by setting it to an inputStream with a text file created by me, but it does not work because another instance of Java is being started and the code does not run. I tried to find something related to Reflection but I haven’t found anything yet. If anyone has any tips I will be very grateful.

1 answer

4


Writing in the child process

The simplest way to solve the problem is by recovering the return of the method Runtime#exec(), who’s kind Process and then using the method Process#getOutputStream to be able to write directly on input of the process.

Example:

Process p = Runtime.getRuntime().exec("java MinhaClasse);
OutputStream stdin = process.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
writer.write("Valor 1\n");
writer.write("Valor 2\n");
writer.write("Valor 2\n");
writer.flush(); // pode chamar várias vezes, dependendo do volume
writer.close(); // opcional, somente quando acabar a entrada

The line break (\n) after the values serve to emulate the key Enter the user presses when entering a value for the Scanner.

Beware of buffers and deadlocks

Something very important is that whenever you write something for the child process you **should call the method flush() of OutputStream.

This is because the OutputStream may have some buffer that may not reach the child process immediately, leaving it blocked indefinitely.

And such care is even more important if the parent process reads the child’s exit, in which case the two may be blocked indefinitely.

ProcessBuilder

Another tip is to use the ProcessBuilder gives greater flexibility when building child process.

This can make a difference if there is a need to pass more parameters or something more complex.

Alternative #1 - using native resources

An alternative would still be to use the command line power of the operating system and do the pipe for input of the Java program from some text file. Example:

cat input.txt | java MinhaClasse

Alternative #2 - using a file as input

Another alternative to the competition is not to pass the data via programming in the main process. I believe this could influence the execution time of the program.

The idea would be to place the input file in a read-only directory on the disk and pass the path to this file as parameter to the program.

Then, just instruct the participants to create the Scanner based on a constructor that receives a file.

Example:

public static void main(String[] args) {
    Scanner input = new Scanner(new File(args[0));
    ...
}

Much simpler, without any implementation difficulty or risk to the execution.

  • Thank you very much, perfect.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.