So I need to add a new method to a program, it requires me accessing this zip folder. The first method downloads from a website and returns a File object.
So now in my method, I'm wanting to change this to be a ZipFile object. At the minute I just want to take in the File, create a ZipFile object using that File, then return it.
So everything is fine, but when I create the ZipFile object, it says an unhandled IOException is there. But if I put the try/catch around it I cannot return the ZipFile. So I create it first and then do the try catch but tells me that the ZipFile is not initialised. Any idea on what I'm missing in my thinking here or how I can sort this?
My code looks like;
ZipFile zipTestData;
try {
zipTestData = new ZipFile(testData)
}catch (IOException io)
log.debug(io.toString());
}catch(Exception e) {
log.debug(e.toString());
}
return zipTestData;
You should not 'swallow' an exception. If an exception occurs, you probably should pass it on for the caller to handle. Otherwise, how would the caller know the operation failed?
You may also use the approach you described, if the caller is prepared to handle the result correctly, like so:
ZipFile zipTestData = null;
try {
zipTestData = new ZipFile(testData)
} catch (IOException io)
log.debug(io.toString());
} catch(Exception e) {
log.debug(e.toString());
}
return zipTestData;
This will return null to the caller instead of a ZipFile if the zip cannot be created for whatever reason.
Although, in that specific case, you could just as well write
try {
return new ZipFile(testData)
} catch (IOException io)
log.debug(io.toString());
} catch(Exception e) {
log.debug(e.toString());
}
return null;
The reason for the error you get is that local variables are not initialized by default upon declaration. So when you declare a local variable (ZipFile zipTestData;) it is not assigned any value. Then, if at run time an exception is thrown at new ZipFile(testData), the variable will not get assigned and the return would try to return the value of that unassigned variable. In Java, that's forbidden.
probably you should initialize the
ZipFile zipTestData = null;
Without stacktrace this is what I could figure out
Related
The problem I'm trying to solve is like this: I'm trying to scrape some content from a web page, I'm using selenium, findElementByClassName to get the element content, and it works great until now. But considering that the website that I'm scraping changes one of those element classes in html, I don't want to get an could not find element exception making the rest of the code not execute and jumping straight into the catch block.
My idea was to put each line of code into a try catch block, but having about 15 fields that I want to scrape it makes the code look ugly. See for yourself:
String name = null;
String type = null;
String description = null;
try {
driver.get(link);
try {
name = driver.findElementByClassName(environment.getProperty("booking.propertyName")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
type = driver.findElementByClassName(environment.getProperty("booking.propertyType")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
description = driver.findElementByClassName(environment.getProperty("booking.propertyDescription")).getText();
}catch (Exception e){
log.error("error doing thing");
}
}catch (Exception e){
log.error("Error during scraping");
}
So if one of these things goes wrong, I still want the rest of the code to continue instead of when having one try-catch block where the first thing failing would stop the other things from executing.
The code above works just fine but it does not look good so my question do you have any ideas of how I could make this better looking.
There is no magic bullet for this. But the standard way avoid repetitive code is to refactor. For example:
try {
type = driver.findElementByClassName(environment.getProperty("something"))
.getText();
} catch (Exception e){
log.error("error doing thing");
}
can be rewritten as:
type = getElementTextIgnoringExceptions(driver, environment, "something");
where getElementTextIgnoringExceptions has been defined as something like this:
public String getElementTextIgnoringExceptions(
Driver driver, Environment env, String name) {
try {
String className = env.getProperty(name);
return driver.findElementByClassName(className).getText();
} catch (Exception ex) {
log.error("error getting " + name, ex);
return null;
}
}
However ... there are some bad things about the code that you are trying to simplify here:
Catching Exception is bad. You have no idea what you will catch, or whether it is safe or sensible to continue.
Not logging the exception is bad. How are you going to diagnose the problem if all you have an "error doing thing" message in your log file?
Continuing after the exceptions is (in the context of your application) liable to cause problems. The rest of your code will be littered with null checks to deal with the elements (or whatever) that couldn't be fetched. Miss one check and you are liable to get an NPE; e.g. in some edge-case that you didn't cover in your unit tests.
These issues are more significant than making the code look good.
If you are using Java 8+, it may be possible to refactor so that the logic is passed as lambda expressions. It depends on the nature of the variables used.
I load a xml content, and save it to the disk. Then I read it, and try to parse.
When I have successfully parsed xml, should I ignore IOException in 7 line?
catch (IOException ignore) {}
Or some problems may occured?
private HashMap <String, VideoDto> loadContent(String url){
try {
BufferedInputStream bStream = httpGateway.loadContents();
cachedContent = xmlParser.parseVideos(bStream);
try {
bStream.close();
} catch (IOException ignore) {}
return cachedContent;
} catch (XMLStreamException e) {
throw new IllegalStateException("I/O error during integration", e);
}
}
public BufferedInputStream loadContents() {
URL source = config.getContentPath();
URL target= config.getLastImportedFile();
try {
ReadableByteChannel rbc = Channels.newChannel(source.openStream());
FileOutputStream fos = new FileOutputStream(target.getFile());
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Wrong url format", e);
} catch (IOException e) {
throw new IllegalArgumentException("I/O error while saving "+target, e);
}
return createBufferStream(config.getLastImportedFile());
}
private BufferedInputStream createBufferStream(URL url){
try {
return new BufferedInputStream(url.openConnection().getInputStream());
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
There are three parts to this question:
Q1: Should one ever ignore (squash) an exception?
I think that the answer is ... "it depends".
If the exception cause is known AND it you can catch it precisely (i.e. without also catching exceptions with different causes) AND the correct thing to do is to ignore it then ... IMO ... Yes it is acceptable.
Otherwise. No.
Q2: What does and IOException mean in this case, and does it matter?
The answer is that it is not at all clear. Under normal circumstances, one would not expect an IOException when closing an input stream, and it is hard to know what it might mean. Intuitively it is probably harmless. On the other hand, if you don't know what might cause something it is hard to say whether or not it matters.
Q3: Should you simply ignore this IOException?
I would say no. But I would handle it like this:
} catch (IOException ex) {
// possibly log the exception here.
throw new AssertionError("Unexpected exception", ex);
}
The rationale is that if something totally unexpected does occur, then it would be a good thing if the developer / maintainer could find out, and figure out how to deal with it.
On the other hand, if you could make an a priori assessment that any IOException here is harmless, then simply logging (or even squashing) it might be sufficient.
Never ignore exceptions, even if nothing goes wrong. This is the seed of bugs.
The desired thing to do, if you don't need any actions to be done, is, print its stack trace.
e.printStackTrace();
You may ignore that at any time, but may help you in the long run.
Use the try syntax that exists since Java 7:
try (BufferedInputStream bStream = httpGateway.loadContents();) {
cachedContent = xmlParser.parseVideos(bStream);
}
With this you don't have to call .close() manually.
You should catch all exceptions that are thrown inside the try block, though.
This means that the stream will (probably) still be open, whether that is a problem in your program only you will know. At the very least you should log the exception, otherwise you might get strange results that are hard to detect.
You might also want to look at the try-with-resources syntax which doesn't pose this dilemma:
try (BufferedInputStream bStream = httpGateway.loadContents()) {
cachedContent = xmlParser.parseVideos(bStream);
}
In Effective Java Joshua Bloch gives this as an example of an exception you might want to log and ignore. He says, however, that in general you want to do more than just logging an exception.
private static Properties getProperties(File file)
{
InputStream in = null;
try
{
in = new FileInputStream(file);
return loadProperties(in);
}
catch (IOException ex)
{
return null;
}
finally
{
if (in != null)
{
try
{
in.close();
}
catch (IOException ex)
{
ex.printStackTrace();
// ignore
}
}
}
}
When I click on the save button to save my configuration then I get null pointer exception. I tried to debug the code, In that time I have found the value of object in is null. I do not understand why?
I have also checked that the path which I have pass as argument file is correct
I beileve there is only one reason the NPE happens -- it didn't find the file with the path you give.
I have also checked that the path which I have pass as argument file is correct
Sometimes even you're thinking you provided a correct file path, depends on the directory hierarchy, program may refer tt relative path which may be different from the path you give.
Then you got in = null.
try ClassLoader.getSystemResourceAsStream() instead of FileInputStream(), you can put your file under class path.
Try to make sure that the file object is exists using file.exists(). If the file exist it will return true. If the file object is null it will also raise NullPointerException.
I have file that I need to deserialize with multiple objects of the same type.
public static ArrayList<Dog> readDogs() {
ArrayList<Dogs> dogs = null;
ObjectInputStream in = null;
try {
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename)));
dogs = new ArrayList<Dog>();
while(true) {
dogs.add((Dog) in.readObject());
}
} catch (EOFException e) {
} catch (Exception e) {
System.err.println(e.toString());
} finally {
try {
in.close();
} catch (IOException e) {
System.err.println(e.toString());
}
}
return dogs;
}
With the current implementation, I rely upon a try clause to catch and ignore an end of file exception, this seems pretty ugly but I'm not sure how else to handle this?
Don't serialize/deserialize each dog. Serialise/deserialize a single List of Dogs.
All List implementations are themselves Serializable, and serializing them will automatically serialize all its elements.
EOFEception represents an exceptional condition that is caused by something outside of your code. If you are not capturing an Error or a RuntimeException which represents some bug that you could fix in your code, then using an Exception is the best way to deal with the problem.
If the problem is not in your code, which is correct, but outside of it (network down, file not found, file corrupted), it is OK and usually recommended to deal with the problems using exceptions.
There are cases where you should validate data before you use it. If there is a large chance of the data being received in an incorrect format (ex: user input), it might be more efficient to validate it first. But in rare cases where you might have a corrupted file among thousands, it's better to catch the exception when it occurs and deal with it.
You could improve your code logging the exceptions, so you can trace them later. You should also consider which class should be responsible for dealing with the exception (if it should catch it and fix the problem, or if it should declare throws and propagate it to the caller.
Use InputStream.available() to test whether data is available in the stream before reading the next dog.
The following code should work:
try {
FileInputStream fin = new FileInputStream(filename);
in = new ObjectInputStream(new BufferedInputStream(fin));
dogs = new ArrayList<Dog>();
while (fin.available() > 0) {
dogs.add((Dog) in.readObject());
}
} catch (EOFException e) {
Note that you should call available() on the FileInputStream object, not the ObjectInputStream object, which doesn't properly support it. Note also that you should still catch and handle EOFException, since it may still be raised in exceptional situations.
Is it possible to get Eclipse to ignore the error "Unhandled exception type"?
In my specific case, the reason being that I have already checked if the file exists. Thus I see no reason to put in a try catch statement.
file = new File(filePath);
if(file.exists()) {
FileInputStream fileStream = openFileInput(filePath);
if (fileStream != null) {
Or am I missing something?
Is it possible to get Eclipse to ignore the error "Unhandled exception type FileNotFoundException".
No. That would be invalid Java, and Eclipse doesn't let you change the rules of the language. (You can sometimes try to run code which doesn't compile, but it's not going to do what you want. You'll find that UnresolvedCompilationError is thrown when execution reaches the invalid code.)
Also note that just because the file existed when you called file.exists() doesn't mean that it still exists when you try to open it a tiny bit later. It could have been deleted in the meantime.
What you could do is write your own method to open a file and throw an unchecked exception if the file doesn't exist (because you're so confident that it does):
public static FileInputStream openUnchecked(File file) {
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
// Just wrap the exception in an unchecked one.
throw new RuntimeException(e);
}
}
Note that "unchecked" here doesn't mean "there's no checking" - it just means that the only exceptions thrown will be unchecked exceptions. If you'd find a different name more useful, then go for it :)
Declare that it throws Exception
Or put it in a try finally bolok
Here it is sir:
try
{
file = new File(filePath);
if(file.exists()) {
FileInputStream fileStream = openFileInput(filePath);
if (fileStream != null) {
// Do your stuff here
}
}
}
catch (FileNotFoundException e)
{
// Uncomment to display error
//e.printStackTrace();
}
You cannot ignore that as it is not due to Eclipse, it is a compiler error, your code will not compile without your calls being enclosed in a try/catch clause. You can, however, leave the catch block empty to ignore the error although it is not recommended...