Java: подпроцесс, который с помощью Scanner генерирует исключение NoSuchElementException

Извините за неловкий английский; Это не мой родной язык.

Я разрабатываю Online-Judge для использования в следующем семестре.

Это получит один файл.java от студента и скомпилирует его,

и запустите.class и протестируйте его с предопределенными тестовыми примерами профессора.

Но когда я отправляю java-файл ниже, Enter.java, возникает ошибка выполнения, и.java-файл оценивается как ExecutionError.

import java.util.Scanner;

public class Enter {

    public static void main(String[] args) {
    // TODO Auto-generated method stub

        int i=0;
        int max=0;
        int min=10000000;

        while(true)
        {
            System.out.print("Enter integer :");

            Scanner input = new Scanner(System.in);
            i = input.nextInt();

            if(i==-1)
                break;

            else if(i>max)
            {
                max=i;
            }
            else if(i<min)
            {
                min=i;
            }

        }
        System.out.printf("Smallest Integer is : %d",min);
        System.out.println();
        System.out.printf("Largest Integer is : %d", max);
    }

}

Конечно, это не правильный исходный код, но я считаю, что система оценила его как ExecutionError (это означает, что возникает исключение, когда система запускает.class для проверки его с помощью testcases). И NoSuchElementException также происходит в input.nextInt(); Но он должен быть оценен как Fail(работает и заканчивается хорошо, но выдает неправильный вывод).

Вот источник JudgeModule.java

private Judgement judge() {

    // some works before compile & test //

    // phase 1. compile //
    CompileResult compileResult = tester.doCompile(compiler, fd);

    if( !compileResult.isSuccess() )    // compile fail
    {
        // some works
        Judgement judgement = new Judgement(compileResult.getResult());
        return judgement;
    }

    // pahse 2. execute
    ExecuteResult executeResult = tester.doTest(compiler, fd, testcases);

    if( executeResult.getException() != null )
    {
        // some works
        Judgement judgement = new Judgement(executeResult.getResult());
        return judgement;
    }

    // some works after compile & test//

    Judgement judgement = new Judgement(executeResult.getResult());

    return judgement;
}

tester является просто экземпляром SourcecodeTester, не имеет переменных-членов и просто содержит doCompile() и doTest().

Ниже приведен источник SourcecodeTester. Я опускаю doCompile() вещи.

public class SourcecodeTester {

    static long executeTimeout = 1000;
    public class ExecuteResult {
        JudgeResult result;
        Exception exception;
        ArrayList<TestResult> testResults;
    }
    public class TestResult {
        JudgeResult result;
        Exception exception;
        String output;
    }


    public ExecuteResult doTest(Compiler compiler, FileDescription fd, Testcase[] testcases )
    {
        // pahse 2. execute
        JudgeResult result = JudgeResult.Pass;
        Exception exception = null;
        ArrayList<TestResult> testResults = new ArrayList<>();

        try {
            for( Testcase testcase : testcases )
            {
                testResults.add( execute(compiler, testcase, fd ) );
            }

        } catch( Exception e ) {
            e.printStackTrace();
            result = JudgeResult.SystemError;
            exception = e;
        }
        // do some works

        return new ExecuteResult(result, exception, testResults );
    }


    private TestResult execute(Compiler compiler, Testcase testcase, FileDescription fd ) 
    {
        Runtime runTime = Runtime.getRuntime();

        String executeCommand = assembleExecuteCommand(compiler, fd);

        JudgeResult executeResult = JudgeResult.Fail;
        Exception executeException = null;
        String executeOutput = "";
        try {
            boolean timeout = false;
            long startTime = System.currentTimeMillis();

            Process executeProcess = runTime.exec(executeCommand);
            writeToProcessInput(executeProcess, testcase.getInput());       // write to process input
            while( executeProcess.isAlive() && !timeout )
            {
                Thread.sleep(10);
                if((System.currentTimeMillis()-startTime) > executeTimeout )
                    timeout = true;
            }

            if( timeout )
            {
                executeProcess.destroy();
                throw new JudgeException("execution timeout!" + (System.currentTimeMillis()-startTime) + "ms", JudgeResult.ExecutionTimeout);
            }

            // exam exitValue
            int exitValue = executeProcess.exitValue();

            // read from process output
            char[] processOutput = readFromProcessOutput(executeProcess);

            // read from process error
            char[] processError = readFromProcessError(executeProcess);

            if( exitValue != 0 ) {
                throw new JudgeException("execution fail with exitvalue : " + exitValue + " >\n" + String.valueOf(processError), JudgeResult.ExecutionError);
            }
            else if( processError.length != 0 ) {
                throw new JudgeException("execution fail with error : " + String.valueOf(processError), JudgeResult.ExecutionError );
            }

            String output = String.valueOf(testcase.getOutput()).replaceAll("\r\n", "\n");
            executeOutput = String.valueOf(processOutput);

            if( Arrays.equals(processOutput, output.toCharArray()) ) {
                executeResult = JudgeResult.Pass;
            }
            else {
                executeResult = JudgeResult.Fail;
            }
        } 
        catch( JudgeException e ) {
            e.printStackTrace();
            executeResult = JudgeResult.ExecutionError;
            executeException = e;
        }
        catch( Exception e ) {
            e.printStackTrace();
            executeResult = JudgeResult.SystemError;
            executeException = e;
        }
        return new TestResult( testcase.getId(), executeResult, executeException, executeOutput );
    }


    private void writeToProcessInput(Process _process, char[] _dataToWrite ) throws IOException
    {
        OutputStreamWriter osw = new OutputStreamWriter(_process.getOutputStream() );
        BufferedWriter writer = new BufferedWriter( osw );
        writer.write( _dataToWrite );
//      osw.write(_dataToWrite);
        writer.close();
        osw.close();
    }

    private char[] readFromProcessOutput(Process _process) throws IOException
    {
        return readFromStream(  new InputStreamReader( _process.getInputStream() )  );
    }

    private char[] readFromProcessError(Process _process) throws IOException
    {
        return readFromStream(  new InputStreamReader( _process.getErrorStream() )  );
    }

    private char[] readFromStream(InputStreamReader isr) throws IOException {
        int numOfByteRead;
        char[] readBuffer = new char[1024];
        StringBuffer standardOutput = new StringBuffer();
        while ((numOfByteRead = isr.read(readBuffer)) > 0) {
            standardOutput.append(readBuffer, 0, numOfByteRead);
        }

        return standardOutput.toString().toCharArray();
    }

}

Когда я компилирую и выполняю Enter.java из командной строки или Eclipse, он работает нормально, и я могу поставить несколько номеров из консоли, и исключений не возникает.

Но я отправляю его в OnlineJudge, и тогда возникает NoSuchElementException. Входной массив символов для тестирования просто содержит несколько чисел, разделенных пробелом.

Наконец, я хочу спросить,

  1. В чем разница и как она работает по-разному между

    • запускает Enter.class и печатает несколько входов из консоли.
    • запускает Enter.class с помощью Process.exec() и записывает массив char в качестве входных данных в выходной поток подпроцесса.

    Почему scanner.nextInt() в Enter.java генерирует исключение NoSuchElementException или нет?

  2. Как я могу изменить OnlineJudge для Enter.java работает так же.

0 ответов

Другие вопросы по тегам