0

Perhaps my title is not very clear, but I try to understand this problem.

Problem: I have many assignments and different persons solve them using their own way. They may need input from user process it and do what they want, I want to individually run their solutions as well as in a framework which run all solutions in one go. Below is the overall simplistic approach I designed as a framework.

But as this code straight showing me that I will get NoSuchElementException (using Scanner) StreamClosed (using BufferedReader) approach.

How can I achieve this or am I thinking very wrong or missing any core concepts?

I don't want a scanner in main and pass its instance to all my code,( is this the only approach I can solve it)

public class AssignmentRunner {

    public static void main(String[] args) {
        AssignmentRunner runner = new AssignmentRunner();
        AssignmentExecutor executor = new AssignmentExecutor();
        executor.execute();
    }
}

public interface Assignment {
    void execute();
}

class AssignmentExecutor {
    public List<Assignment> assignmentList ;

    private void addAssignments(){
        assignmentList = new ArrayList<Assignment>();
        assignmentList.add(new Assignment1());
        assignmentList.add(new Assignment2());
    }

    public void execute() {
        addAssignments();
        for (Assignment assigment : assignmentList) {
            assigment.execute();
        }
    }
}

public class Assignment1 implements Assignment {
    String inputString;

    @Override
    public void execute() {
        input();
        System.out.println(inputString);
    }

    private void input() {
        Scanner scanner = new Scanner(System.in);
        try {
            inputString = scanner.nextLine();
        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }
        finally {
            scanner.close();
        }
    }
}

public class Assignment2 implements Assignment  {
    String inputString;

    @Override
    public void execute() {
        input();
        System.out.println("Hello"+inputString);
    }

    private void input() {
        Scanner scanner = new Scanner(System.in);
        try {
            inputString = scanner.nextLine();
        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }
        finally {
            scanner.close();
        }
    }
}

EDIT: As per some comments and one answer I have made few modifications,kindly help me to understand is this the only best thing we can do or any other way to design my need.

NEED Different students can have different assignments for example (some may need input,others may not need any input)

  1. simply print hello world
  2. input string and show word count
  3. input number show factorial
  4. input number print its table

We want to execute each assignment class individually as well as from one Runner class as shown above.

MODIFICATION I did these modifications to all classes, showing sample for understanding what I did.

class AssignmentExecutor {
    public List<Assignment> assignmentList ;

    private void addAssignments(){
        assignmentList = new ArrayList<Assignment>();
        assignmentList.add(new Assignment1());
        assignmentList.add(new Assignment2());
    }

    public void execute() {
        Scanner scanner = new Scanner(System.in);
        addAssignments();
        for (Assignment assigment : assignmentList) {
            assigment.execute(scanner);
        }
        scanner.close();
    }
}



    public class Assignment1 implements Assignment {
        String inputString;

    public static void main(String args[]) {
        Assignment1 assignment1 =new Assignment1();
        Scanner scanner = new Scanner(System.in);
        assignment1.execute(scanner);
        scanner.close();
    }
    
        @Override
        public void execute(scanner) {
            input(scanner);
            System.out.println(inputString);
        }
    
        private void input(scanner) {
            scanner = new Scanner(System.in);
            try {
                inputString = scanner.nextLine();
            }
            catch (Exception e) {
                System.err.println(e.getMessage());
            }
        }
    }
dan1st
  • 12,568
  • 8
  • 34
  • 67
SSH
  • 1,609
  • 2
  • 22
  • 42
  • 2
    You should not close the [standard input stream](https://docs.oracle.com/javase/tutorial/essential/io/cl.html). Remove the `finally` block from method `input` in both classes `Assignment1` and `Assignment2` – Abra Dec 30 '22 at 16:18
  • 2
    You should also never wrap an input stream more than once, unless you really know what you are doing. See https://stackoverflow.com/questions/19766566/java-multiple-scanners. Use a singleton-like class to share a single instance of a Scanner. – tucuxi Dec 30 '22 at 16:21
  • 2
    If you explain the requirements better (how is this going to be used? if I type something into the application, which of your scanners should read it?), we may be able to help you to design your application better. Your code, as it is, is not fixable - until you improve the design. – tucuxi Dec 30 '22 at 16:24
  • 1
    Either prevent System.in from being closed, like explained [here](https://stackoverflow.com/questions/3229848/how-do-i-avoid-closing-an-inputstream-passed-to-my-method-that-i-wrap-in-reader) or replace System.in with your own Stream for better automated testing, like explained [here](https://stackoverflow.com/questions/14918372/change-system-in-and-make-scanners-use-one-bytearrayinputstream). – Tom Dec 30 '22 at 16:44
  • @tucuxi I have made some edits kindly update your kind thoughts – SSH Dec 30 '22 at 22:09
  • @Tom I have made some edits kindly update your kind thoughts – SSH Dec 30 '22 at 22:09
  • What is your result with these modifications? Does it fulfill your needs or not? Also, why do you still create another Scanner in the Assignment class? – Tom Dec 31 '22 at 20:21
  • @Tom yes it fullfils my needs for scanner , i need to pass scanner object, so if i want to run from same class i created main and new scanner to pass in, and if i am running from framework class its passing scanner as well – SSH Jan 01 '23 at 16:55

0 Answers0