javaeclipseresource-leak

Eclipse says Scanner is never closed when it is


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();
    }
}

Solution

  • 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);