resource leak 'Nommy' is never closed error - java

i'm new to java so please do explain in full were i'm going wrong
thank you.
import java.util.Scanner;
class apples {
public static void main (String args[]){
Scanner Nommy = new Scanner (System.in);
System.out.println (Nommy.nextLine());
}
}

To understand what's wrong, you should learn more about streams stuff.
Briefly, if you open stream, then, you should close it, or a memory leak appears.
See http://www.tutorialspoint.com/java/java_files_io.htm for details.
Good luck!

You should close the scanner after using it. Otherwise, you'll get the warning from the compiler.
The simplest way is to add Nommy.close() after the last statement.
You should, however, call it in a finally block or using the try statement: see https://stackoverflow.com/a/15613676/1547337

Related

life and death of an object explanation

The code below gives me a warning on Eclipse: "resource leak, input is never closed":
Code: 1
import java.util.Scanner;
public class Ex {
public void sum() {
Scanner input = new Scanner(System.in);
}
}
I found that declaring the input variable in the class level does the trick, the warning is gone.
But, is this the right way of fixing this issue? And what is the difference between the second code and the third code? Does code 3 means that I have abandoned the first object?
Code: 2
import java.util.Scanner;
public class Ex {
private Scanner input;
public void sum() {
input = new Scanner(System.in);
}
}
Code: 3
import java.util.Scanner;
public class Ex {
private Scanner input = new Scanner(System.in);
public void sum() {
input = new Scanner(System.in);
}
}
but , is this the right way of fixing this issue - No its not... The input is still not closed, only that Eclipse is not able to detect it anymore... The issue is still present...
That being said, it's not a good idea to close the Standard input System.in too (closing the Scanner object would close the underlying stream too as I understand)... Hence it would be better to leave it like that even though there is a warning...
Yes, since in code 3 you have reinitialized input, you have abandoned the first object.
The presence of a warning is almost always a sign of a problem. But the absence of a warning doesn't mean there is no problem.
The first snippet warns you that you're not closing the Scanner object when you're done with it. The proper fix would be to close it. Not to make your code worse by using a field instead of a local variable, and still not closing the scanner when you're done with it. That will make the warning disappear, but not the problem. Variables should always have the narrowest possible scope.
That said, A Scanner opened with System.in as argument, although it implements Closeable (that's why you have the warning), should in fact not be closed, because that would close the underlying stream: System.in. File or Socket streams must be closed, but System.in should generally not. If you close it, the user won't be able to enter anything anymore to your program.
You are getting the warning because the scanner instance is never closed. Modify the code: 1 as below to eliminate the warning,
public void sum() {
Scanner input = null;
try {
input = new Scanner(System.in);
// do operation
} finally {
input.close();
}
}
Regarding code:2, declare any variable at Object level only when its required. i.e if it needs to be accessed by multiple member functions defined in the class.
To answer your question is this the right way of fixing this issue , and what is the difference between the second code and the third code ? Does code : 3 means that i have abandoned the first object ?
No, Code: 3 is not the right way way to fix the issue. And yes, code:3 creates a new instance of scanner inside the member function "sum" and the reference of the member variable input will point to the newly created scanner instance.
In summary, create a member variable (object level) only when its absolutely required, otherwise create a local variable - this will ensure that the objects get collected much earlier. (i.e. these objects will become eligible for GC when the method execution completes). Also, make sure that, call close() on almost all of the IO classes (stream classes) that we operate on.
Also, Note that if you close System.in, you won't be able to read from it again

How to avoid try-catch when validating text input

While working on a code, I was wondering if I could avoid try n catch and used something else. For example, if i have a value(from console) of type double and if user enters a string or something else then there should be a prompt to re-enter the value.
I know this can be done very easily using try-n-catch but how can we do it without it, is there any way out?
Please give an example if possible.
Sadly, the JDK lacks the TryParse method that some other libraries provide. I wouldn't be surprised to find something in Apache Commons or Guava that does it.
Alternately, you might use a Scanner and use its hasNextDouble to do the check.
If you're asking how to avoid dealing with exceptions in general: Don't try. Exceptions are a powerful way of handling exceptional conditions in programs, and the "handle-or-declare" provided by checked exceptions (e.g., your code must handle the exception, or declare that it doesn't) is very useful.
But there are some use-cases, like your example, where you might well want to avoid an exception being thrown because, after all, a user entering invalid input isn't an exceptional condition, it's an all-too-common one. :-)
Throw Exceptions are less robust but a good way to deal avoiding with try/catch statements.
import java.io.*;
public class UsingThrows {
public static void main(String args[]) throws FileNotFoundException {
FileInputStream fis = new FileInputStream("def.txt");
System.out.println("OK 1");
}
}

Close a Scanner linked to System.in

I have a Scanner linked to System.in. Now, after using the Scanner, I should close it, as it is bad coding practice to leave it open. But, if I close the Scanner, I will also be closing System.in! Can anyone tell me how I can close the Scanner without closing System.in (if there is any way).
The simplest thing is to not close Scanner if you don't want to close the underlying stream.
Ideally you should create just one Scanner which you use for the life of the program. In any case, it appears you don't have a good reason to close it.
One option is to wrap your System.in stream in a CloseShieldInputStream that prevents it from being closed. Your reader would then use the CloseShieldInputStream rather than the raw System.in stream.
Here is the API for the class:
http://commons.apache.org/io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html
Instead of adding shield classes and stuff like that, just put a nice comment and a
#SuppressWarnings("resource")
That's good enough. And I don't seem to see a lot of drawbacks to this approach. Don't forget the comment.
I have vague memories of strange, undiagnosable problems long ago with using the same Scanner of System.in twice, so this is what I use (even though you should probably just use one scanner for the duration of the program):
static String input() {
try {
return new Scanner(System.in).nextLine();
} catch (NoSuchElementException e) {
throw e;
}
}
For some reason this works without warnings, whereas if I don't do the catch-throw, Eclipse will complain Resource leak: '<unassigned Closeable value>' is never closed.
According to the API for InputSteam "The close method of InputStream does nothing.", so since System.in is an instance of InputStream, you don't need to worry about close() being called on it.

Best practice way to read input in Java 5

I'm writing a tutorial for kids, to learn programming on the Java 5 platform.
What's the best way to read in text data from a console program?
By "best" I mean the most common way this would be done at the Java 5 level. I realize reading text input from the command line is fraught with challenges and that a well guarded method would have to incorporate several levels of exceptions, that's fine. At this point in the tutorial, I've covered basic output, basic program structure in Java, exception handling. If you think additional things need to be covered before user input, I'd welcome suggestions.
It's interesting that doing a web search on this question doesn't give an immediate answer, there's a lot to weed through and there's no sense of a best practice. I guess it's because there are so many hidden caveats, it's not as simple as it first seems.
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
class Example {
private BufferedReader br;
private String inputString;
public static void main(String[] args) {
String inputString = null;
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("\n > ");
try {
inputString = br.readLine();
} catch (IOException ioe) {
System.out.println("\n IOException called.");
}
System.out.println("\n Input was: " + inputString);
}
}
You would compile this using: javac Example.java
Run it using: java Example
Is there a better way you can think of that might be more instructive for children? Funny how basic these things seem to be, but when you really look at it, that's a lot of code for gathering one line of text with a minimal amount of error checking.
If you want to add an optional comment about how you first got interested in programming, I'd be hugely grateful. For me, it was chance (my father had to bring home a dumb terminal to do work from home, connecting to his work's mainframe over a dial-up connection to a unix system, and when he showed me how to list 'games' I was hooked).
Thanks for your help.
Scanner is pretty basic and less code.
import java.util.Scanner;
class Example{
public static void main(String args[]){
Scanner s = new Scanner(System.in);
String inputString = s.nextLine();
//Output stuff
}
}
I think a Scanner is a bit easier than a BufferedReader, personally. That's how I learned user input initially.
You have to do some of the same things but you can leave off the exception handling and try/catch for a later day.
Some rhetorical questions:
What age are the kids?
What are you aiming to achieve in terms of educational outcomes? Or is this mainly about giving them something fun to do.
What is your level of experience with Java?
My gut feeling is that you should not be going overboard with the "best practice" stuff. Assuming that these are school age kids, they don't need it, they probably don't have the outlook to understand it. So for most of them it is going to be boring blah blah, and a good way to turn them off IT.
Besides, it is difficult to teach "best practice" if you don't fully understand it yourself. The way I see it, "best practice" is about techniques that are best most of the time. To teach them properly you need to understand (and be able to explain) why they work, and when they don't work. It also helps if you understand a bit about the "not best practice" ways of doing things too ... so that you can explain the difference.
(I'd also question why you are restricting yourself to Java 5 ... but that's not particularly relevant.)
When I asked about "educational outcomes" I was mean things like:
student gets/stays enthusiastic about programming, or
student achieves such and such a level of proficiency, or
...
It is one of the first questions that someone in the business of teaching should be asking themselves.
Having said that, I think I'll stick with my advice above. If you want to beat the drum about "best practice", try to structure your material so that it is easy for the average kid to skip over the "boring" bits.
My idea is that , kids are going to be more exited when they see their result with a new screen using JOptionPane.
import javax.swing.JOptionPane;
public class test{
public static void main(String[] args){
String name=JOptionPane.showInputDialog(null,"Enter your name");
JOptionPane.showMessageDialog(null, "Your Name: " + name);
}
}

What is the exception I should be catching on the dotted line?

I have a problem at school. I'm new to programing and I need some help. Please complete the dotted line:
import java.net.*;
import java.io.*
public class Test{
public static void main (String arg[]}
int x=0;
try {
ServerSocket s=new ServerSocket ( k );
s.close();
}
catch (..........................) {x++;}
catch(IOException e) {}
}
System.out.println( "Total "+ x); }
}
Look up in the documentation what exceptions the constructor of ServerSocket can throw and what exception the close function of ServerSocket can throw. One of them is probably IOException, just look up what else.
A hint: if you use a modern IDE, it'll tell you. For example, just write without the try and catch blocks
import java.net.*; import java.io.*
public class Test{
public static void main (String arg[]}
int x=0;
ServerSocket s=new ServerSocket ( k );
s.close();
System.out.println( "Total "+ x); }
}
The IDE will underline the code and give you a suggestion, click on it and it'll insert the appropriate Exceptions automatically.
The answer can be found at the JavaDoc for ServerSocket constructor that you use.
You need to catch (or declare that your method throws) every Checked Exception that is declared by the code that you are calling. These are documented in the JavaDoc and on the method signature. Unchecked exceptions, like IllegalArguementException, do not need to be caught.
To make the code compile, the line should read:
catch (StackOverflowError exc) {x++;}
If you use an IDE, such as Eclipse, you can easily fix those problems and many others, as the IDE will point out exactly what Exceptions need to be caught, saving you from a trip to the Javadoc page which, by the way, is easily accessed directly from the IDE.
#akf: That's not the opinion of the instructors of some major CS schools. For example, the "Introduction to Computer Science | Programming Methodology" course of Stanford uses a modified version of Eclipse. I think it's a much better way to learn a language, avoiding those situations where you are fixing a problem, compile, and then fix the new problem. This can be frustrating to newcomers. An IDE is just a tool to aid programming, it doesn't cause dependence, and it certainly won't stop you from coding without it.
I do agree, however, that it's important to know the basics, as far as using java or javac is concerned, just in case you ever find yourself with a terminal in front of you.
As you mention in your comment on Henri, you have to choose between either SecurityException or IllegalArgumentException.
The significance here lies in the variable x. What is x supposed to count? My guess would be the former, but there should be a hint in your assignment.
(BTW: I only see a mention of SecurityException besides IOException in the documentation)

Categories

Resources