0

I have this code and everything works as I expect it to:

package test;

import java.util.Scanner;

public class Nukes_for
{
    public static void main(String[] args)
    {
        Scanner scan = new Scanner(System.in);
        String code = "password123";
        String input;
        int i;
        for (i=0; i < 3; i++)
        {
            System.out.print("Enter Nuclear Launch code: ");
            input = scan.nextLine();
            System.out.println("Launch code: " + input);
            boolean passcheck = code.equals(input);
            if (passcheck == true)
            {
                System.out.println("Accepted");
                System.out.println("Missiles away");
                break;
            }
            else if (input.equals("exit"))
            {
                System.out.println("Exiting");
                break;
            }
            else
            {
                System.out.println("Rejected");
            }
        }
        if (i > 2)
        {
            System.out.println("Maximum tries exceeded");
            System.out.println("Exiting");
        }
        scan.close();
    }
}

And Eclipse says that the scanner in line 9 is never closed. But I do close it in line 40. Why is eclipse complaining?

I have another example where I use a do while loop and it's almost exactly the same, but Eclipse doesn't complain there, so I don't understand what's wrong with the above example. I'm still learning the very basics, so please try to keep explanations simple.

Other example

package test;

import java.util.Scanner;

public class Nukes_do_while
{
    public static void main(String[] args)
    {
        Scanner scan = new Scanner(System.in);
        String code = "password123";
        String input;
        int counter = 0;
        boolean passcheck;
        do
        {
            System.out.print("Enter Nuclear Launch code: ");
            input = scan.nextLine();
            System.out.println("Launch code: " + input);
            passcheck = code.equals(input);
            counter++;
            if (passcheck == true)
            {
                System.out.println("Accepted");
                System.out.println("Missiles away");
            }
            else if (counter > 2)
            {
                System.out.println("Maximum tries exceeded");
                System.out.println("Exiting");
                break;
            }
            else if (input.equals("exit"))
            {
                System.out.println("Exiting");
                break;
            }
            else
            {
                System.out.println("Rejected");
            }
        }
        while (passcheck==false);
        scan.close();
    }
}
Karan Vess
  • 15
  • 4
  • Does this answer your question: https://stackoverflow.com/questions/12519335/resource-leak-in-is-never-closed ? – akarnokd Jun 23 '22 at 09:15
  • 4
    Although closing scanner is generally advisable, it is better to not close it if it is a scanner around `System.in`. And if you do want it, use try-with-resources, so it is closed even if exceptions occur. I guess Eclipse is warning because there are possible paths (exceptions thrown) where the scanner will not be closed. – Mark Rotteveel Jun 23 '22 at 09:17
  • @akarnokd No, it does not. – Karan Vess Jun 23 '22 at 09:20
  • @MarkRotteveel I understand that that's an option. My question is why eclipse is complaining that it's not closed when it IS closed. – Karan Vess Jun 23 '22 at 09:21
  • 2
    This looks like some sort of problem with the Eclipse loop analysis rather than your code. Using try-with-resources gets rid of the warning. – greg-449 Jun 23 '22 at 09:30

1 Answers1

3

This appears to be a problem with the Eclipse loop analysis rather than your code. Eclipse is trying to make sure all paths through the code close the resource but it seems to have made a mistake.

The minimum code to show the problem is just:

Scanner scan = new Scanner(System.in);

int i;
for (i = 0; i < 3; i++)
 {
   //
 }

scan.close();

Just changing this to:

Scanner scan = new Scanner(System.in);

for (int i = 0; i < 3; i++)
 {
   //
 }

scan.close();

gets rid of the error, so it seems to be something to do with the int i declaration.

Changing the code to use try-with-resources would be the best fix:

 try (Scanner scan = new Scanner(System.in))
  {
    ... your code
  }

But as mentioned in the comments closing a scanner on System.in is not really a good idea as it will also close System.in. You can just tell Eclipse not to generate the warning with:

@SuppressWarnings("resource")
Scanner scan = new Scanner(System.in);
greg-449
  • 109,219
  • 232
  • 102
  • 145
  • removing the int i and then declaring it in the for condition doesn't completely remove the warning eclipse gives me. And it also creates a problem in line 35 where the final if can't find the i anymore. But I think it's enough for me to know that it just seems to be an eclipse bug. – Karan Vess Jun 23 '22 at 10:03
  • @KaranVess I am only talking about my minimal example, since your full code is more complex it would need additional work. The change is just intended to show roughly where Eclipse is getting confused. – greg-449 Jun 23 '22 at 10:05