How to Prevent IOException with the File Class [duplicate] - java

This question already has answers here:
Difference between java.lang.RuntimeException and java.lang.Exception
(12 answers)
Closed last month.
I've been trying to get an image to be saved as a BufferedImage in my program, but every time I try to set the file pathname it always results in an IOException error.
File grass = new File("C:\\\\Users\\user\\eclipse-workspace\\minecraft\\textures\\GRASS.png");
private final BufferedImage grassTexture = ImageIO.read(grass);
private final BufferedImage dirtTexture = ImageIO.read(new File("C:\\\\Users\\\\user\\\\eclipse-workspace\\\\minecraft\\\\textures\\\\DIRT.png"));
As you can see I tried a couple of different patterns of backslashes. ^
I use Eclipse for my IDE and it gave me this:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Unhandled exception type IOException
Unhandled exception type IOException
Unhandled exception type IOException
Unhandled exception type IOException
Unhandled exception type IOException
Unhandled exception type IOException
Unhandled exception type IOException
Unhandled exception type IOException
at minecraft.MinecraftGame.<init>(MinecraftGame.java:28)
at minecraft.MinecraftGame.main(MinecraftGame.java:151)
How can I prevent this error from occurring?

Get used to the fact that computer programs may face problems at runtime.
That means that not everything will be going as smooth as a developer might believe in.
Exceptions are a way to report errors. Preventing them would mean making sure that no exception will ever occur. Good, that is the perfect case a developer might have dreamt of. Reality is different.
So the compiler just warns you (the developer) that you have not designed your code for the fact that something might have gone wrong. The magic is not to prevent an exception but to define what should happen in case one occurs.
One way to deal with (and done by many beginners) is to just catch the exception and forget about it. A much better way is to mark your method that it might throw an exception. If you do this it would mean your application terminates on any error. But the user would be aware of it. And as developer you could learn when to come up with better strategies.
So change lines that look like this:
public static void main(String[] args) {
into that:
public static void main(String[] args) throws Exception {
until you know better.

Related

Java Scoping and how to perform writes to a common log file

How do you structure code to allow file writes from different code parts to a single log file? I thought it would be appropriate to have a single static object as the file handle, open the file once, and perform buffered writes to the file from any code section, using this static file handle.
How should the code be scoped, and how should exception handling be applied for the file writes (my attached simplified code shows multiple errors in my improper exception handling, and the static declarations seem wrong). The compiler insists on exception handling for the declaration [how?] so that exception handling can be used whenever the file handle is used (I'm totally missing something fundamental here).
Simplistically, I could choose to have every code section that needs to write to the log, merely open the file, write, and close, but that is inefficient. All examples of file writing I've seen merely bundle all open, write, close operations in a small code snippet but my file operations are distributed in multiple methods within the class.
What is the best way to declare a file handle object, and use it to write to the file from different code sections, and properly handle io exceptions?
public class MyApp3 {
// create the file handle
static FileWriter log = new FileWriter("Logfile.txt", true); // compiler flags ERROR on this line
// "unreported exception IOException; must be caught or declared to be thrown"
static BufferedWriter bufferedLog = new BufferedWriter(log);
static void Activity1() {
bufferedLog.write("Activity1 actions written to log"); // compiler flags ERROR on this line
// "unreported exception IOException; must be caught or declared to be thrown"
}
static void Activity2() {
bufferedLog.write("Activity2 actions written to log"); // compiler flags ERROR on this line
// "unreported exception IOException; must be caught or declared to be thrown"
}
public static void main(String[] args) {
Activity1(); // performs some file writes
Activity2(); // performs some file writes
try {
bufferedLog.write("Last write to file before close.");
} catch (IOException e) {
e.printStackTrace();
} finally {
bufferedLog.close(); // compiler flags ERROR on this line
// "unreported exception IOException; must be caught or declared to be thrown"
}
}
}
Consider using the logging library - they've solved all the issues you've raised in the question.
Log4j (2), Logback are examples of libraries as such
There is even one, built-in into JDK (although nearly no one really uses it - its called JULI - search for the package java.util.logging)
So, in terms of these libraries, you'll have multiple loggers associated with a file appended that will write into this "single" file in an efficient manner. You'll be able to rotate this file when it reaches a certain size, the library will delete obsolete files, etc.
Also, you will be able to define the format of the message, log exceptions, and so on and so forth. Bottom line, this is something that I highly recommend to not "re-invent the wheel" and use one of the aforementioned production ready solutions

I assert an error cannot happen in Java. How do I code that?

Here is my code:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
outputStream.write(signature.getR());
outputStream.write(signature.getS());
outputStream.write(signature.getV());
} catch (java.io.IOException exception) {
// WHAT GOES HERE?
}
The Java documentation tells me that this ByteArrayOutputStream might throw an IOException. And so the compiler requires me to put this in a try/catch block.
Based on the fact that I am concatenating only about 100 bytes, and I am not closing the stream in the meantime, I do not expect any errors.
Or more clearly, I don't want to handle or pass of any errors.
In Swift I would do this with an assertion (try!).
In Java how do I make it so that an exception here results in the program terminating and does not require me to bubble up exceptions the whole way?
Invalid/Inconsistent/Unexpected scenarios
Checked Exceptions - expected and caller should be aware (runtime course correction)
Unchecked Exceptions - unexpected and caller need not take course correction (back to coding, fix and redeploy)
Checked Exceptions
Possible invalid state of operation where the immediate caller can take a course correction
Or else propagate such exception up in call hierarchy by adding to throws
Or turn into a Unchecked exception due to this being an unacceptable state due to bug and decide on caller's decision
Silently consume(catch) and proceed as though nothing happened
Why IO operations are generally Checked?
The IO(network) could be unavailable temporarily so that caller can retry
IO(File) permission might be incorrect and hence caller can try an alternate action (different path or change permissions if allowed)
Insufficient resource(space) and the caller can free up some resource and retry
Invalid path and hence write to different path (or create the path)
Unchecked Exceptions
Invalid states which should not happen at runtime (say NPE)
Unexpected states like Stack overflow Error, Out of memory error (though caller can course correct by taking an alternate action like unreferencing to GC large objects or call iterative logic instead of recursive logic). These actions should be decided by developer at compile time and should not be generally handled at runtime.
Java states
Throwable - any invalid state - Unchecked
Exception - primarily predicted invalid states (unpredicted too with RuntimeException) - Checked for everyone except RuntimeException hierarchy
RuntimeException - a special type of Exception for unpredicted or should not happen or no alternative - Unchecked
Error - abnormal and could not handle - Unchecked
Assuming the call is for write(int), it is safe to ignore for this specific use case
ByteArrayOutputStream.write(int) will not throw checked exception
There is no checked exception defined for .write(int) Doc
But the parent class OutputStream has checked exception.
So, catch block can be left empty or its not even required unless you are using the OutStream as the reference to hold the ByteArrayOutputStream object
The following code works perfectly fine in JDK 11 compiler and runtime
public static void main(String[] args) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
b.write(65);
System.out.println(b.toString());
}
It can throw NPE for null input (technically this is unboxing error)
public static void main(String[] args) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
Integer input = null;
b.write(input);
System.out.println(b.toString());
}
If its write(byte[]), then OutputStream.write throws checked exception and hence it has to be caught.
But it can throw other runtime exceptions too.
public static void main(String[] args) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
try {
b.write((byte[])null); // NPE
} catch (IOException e) {
System.out.println(e);
} catch (RuntimeException e) {
System.out.println(e);
}
}
catch (java.io.IOException exception) {
throw new UncheckedIOException(exception);
}
One of the reasons for introducing UncheckedIOException in Java 8 was to hide the abuse of IOException in Java, and shut the compiler up. Very useful for lambdas that can't throw checked exceptions.

Haven't handled the FileNotFoundException file in Java program? [duplicate]

This question already has an answer here:
Unreported exception java
(1 answer)
Closed 2 years ago.
I have some trouble finding the file in a java program in mac system.
import java.io.File;
import java.util.Scanner;
import java.net.MalformedURLException;
import java.net.URL;
public class Data{
public static void main(String[] args){
File file = new File("/Users/project/test.txt");
Scanner sc = new Scanner(file);
while(sc.hasNextLine()){
System.out.println(sc.nextLine());
}
}
}
In the same directory, when I typed this command Javac Data.java, it would give this error
I have read multiple similar posts on StackOverflow, but unfortunately, I couldn't find a solution.
Data.java:9: error: unreported exception FileNotFoundException; must be caught or declared to be thrown Scanner sc = new Scanner(file);
^
1 error
I have tried setting the file path like:
"./test.txt"
"test.txt"
"/text.txt"
But still, the same error would occur.
I don't know if this is relevant, but I can only run the java command in the terminal in the ~ directory, and all the above java files are in the ~ directory too.
Does anyone have any suggestions?
Your code is not throwing an exception. Your error message does not mean that the FileNotFoundException is thrown.
You have a compile time error.
Whenever you open a file, it must be like this:
try {
File file = new File("/Users/tianrongzhen/project/test.txt");
} catch (Exception e) {
// handle exception here
}
Or like this:
public static void main(String[] args) throws FileNotFoundException {
File file = new File("/Users/tianrongzhen/project/test.txt");
// rest of your code
}
There are 2 kinds of exceptions: Checked and Unchecked.
A Checked exception can be considered one that is found by the compiler, and the compiler knows that it has a chance to occur, so you need to catch or throw it.
For example, opening a file. It has a chance to fail, and the compiler knows this, so you're forced to catch or throw the possible IOException or FileNotFoundException.
There is a huge difference between the two ways to handle exceptions above.
First one catches and handles Exception internally, so the caller doesn't have to do any exception handling.
Second one throws Exception, so the caller needs to handle the Exception.
Based on the question you have asked here, I would recommend you to read up on the basics on exception handling. Here is one resource, but feel free to explore.

Forcing java to make a compile error with the user input as message

I Don't know whether it is possible in java or not; I want to get an input from user (from System.in) and then throw a compile error with that input. I mean if the user inputted the text "HELLO" then the program should throw a compile error: Compile Error: HELLO. I want an error that actually make the program stop executing at that point with that message.
Is this possible? If yes, How?
Actually I want to make a compile error during run-time!
The code will be like this:
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
//compileError(str); this part must be completed
}
}
Is this possible?
What you are referring to is Exceptions not a compilation error. Compilation error is when there is something wrong in the syntax of your code and the Java compiler fails to generate byte code for your program for the JVM to execute it. So that happens before you can run the program.
So you can use an instance of a RuntimeException or any sub class of it in Java to terminate your program when "HELLO" is used as the input, here in my sample code InputMismatchException is thrown if the input is "HELLO", this exception being a sub class of RuntimeException or unchecked exception doesn't require the programmer to add a throws clause or handle it explicitly:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
if("HELLO".equals(str)){
throw new InputMismatchException("This input is not allowed");
}
}
You can make your program stop executing at that point. For example:
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
if (str.equals("HELLO")) {
System.out.println("Compile Error: " + str);
System.exit(1);
}
// Do something else.
}
}
Another way to do it is to throw an exception ... except than you will get an exception stacktrace as well as a message. In the context you are doing this, it probably doesn't matter.
Note that there are some potential problems with this:
If the judge intercepts all output, then it may not be possible to get hold of the messages that your application produces.
The judge may feed your application different inputs each time it judges it.
However, this is not a real compile error. Indeed, it doesn't make sense for your program to generate a real compile error.
Compile errors occur when code is being compiled, and they are output by the compiler. But a Java application cannot read input (from the user or the "judge") at compile time. It can read input at runtime ... but then it is too late for a compilation error.
You seem to have your terminology confused. I suggest you read these articles to understand what the various terms mean:
Compilation Error or Compiler Error - https://en.wikipedia.org/wiki/Compilation_error
Runtime Error - https://techterms.com/definition/runtime_error
Exception - https://techterms.com/definition/exception
Your commented thus:
Think that you are given a program that you don't know what it should do and it pass some tests on an online judge. You know what the input could be but don't know in which order they come and you should get the test cases without actually accessing the online judge's test cases. I want to make my program give me some errors to find out what is in each test case.
and
I just have a working program and want to extract the input from online judge.
That is not a compilation error you are talking about. That is a runtime error, because you want / need it to happen when your program runs. Please refer to the links above for explanations of these terms.
If your intent is to print a message and exit out of program you can do something like following
...
System.err.println("Your input has resulted in an error, program will terminate");
/* You can change the above text with whatever you want */
System.exit(1);
Alternately, you can always throw an object of Exception (or an object of a class derived from it) and don't catch it anywhere in your program when it bubbles, program will terminate.
/* add throws Exception in your main method */
throw new Exception("Your input has resulted in an error, program will terminate")
However it's not clear why you would specially look for throwing Compile error. Compile time errors are thrown by compiler when compiling a program. During execution you neither expect them nor try to throw them.
You cannot throw a compile error when your code is executing. I think you meant a Runtime error that cause your code to fail at runtime.
Try something like this:
throw new RuntimeException(str);
You can also catch this 'error' if you surround your code with try/catch clauses.
try {
// get the input
throw new RuntimeException(str);
} catch (RuntimeException ex) {
// ex contains the error details
// ex.getMessage() will give you the user's input
}
RuntimeException is the most general exception for errors at runtime, you can use other exceptions, list of exceptions.

Can't open java application when ran as executable jar

I had a strange problem today... I'm going to make a simplified example since it "worth a thousands words" :D
public class Application() {
public static void main(String[] args) {
try {
A a = new A(); // this may throw exceptions
// (which will cause an ExceptionInInitializerError)
} catch (Throwable t) {
JOptionPane.showMessageDialog(null, "Oooops!");
System.exit(1);
}
}
}
Since it's a stand-alone application with a Swing GUI, my goal is to give a message to the user in case of any problems (in this case at startup)... the code above works in Eclipse IDE but when I export the project as executable jar by double-clicking on it, well, it just won't open.
So I try to execute it in cmd with java -jar application.jar and it prints in the shell that there was an ExceptionInInitializerError.
Why the error was not caught?
It doesn't work even if I specify catch (ExceptionInInitializerError e).
EDIT:
After more indepth debugging, I found out that this problem only happens when two particular exceptions occur and the latter occurs in the catch block of the former.
I corrected the bug by changing the order of some checks that I do on startup.
The problem btw should never happen since it was originated by a volountary mistake of the JDBC driver class name to load in a static block.
Well, at least it made me clearly understand why constructors and static initialization blocks should not throw exceptions: it makes debugging almost impossible in the case in which the class that throws the exception is used by many classes, since it may become very hard to find out when the class is loaded.
I can think of three possible explanations for an ExceptionInInitializerError not being caught in your example:
It could be being thrown by JOptionPane.showMessageDialog(null, "Oooops!");
It could be thrown before main is called.
It could be thrown on a different stack.
In fact, I think that the 2nd one is the most likely, as ExceptionInInitializerError is thrown when some unchecked exception is thrown (and not caught) during the initialization of a class. That could well be happening before you enter the try block.

Categories

Resources