We have this code. SONAR is complaining about the main() function.
"main" should not "throw" anything
There's no reason for a main method to throw anything. After all, what's going to catch it?
Instead, the method should itself gracefully handle any exceptions that may bubble up to it, attach as much contextual information as possible, and perform whatever logging or user communication is necessary.
Q: Would adding a catch(IOException e) {} mitigate this issue?
public class EncryptionHelper {
private static final int NO_OF_ARGUMENTS = 3;
/**
* Ctor
*/
protected EncryptionHelper() {
// Empty Ctor
}
/**
* Main
*
* #param args
*
* 0 - Input text to be encrypted or decrypted
* 1 - Encrypt/Decrypt [0-Encrypt, 1-Decrypt]
* 2 - File to write the output
* #throws IOException
*/
public static void main(String[] args) throws IOException {
if (args.length != NO_OF_ARGUMENTS) {
throw new IllegalArgumentException("Expected 3 arguments to encrypt/decrypt.");
}
OutputStreamWriter fw = null;
Crypto crypto = CryptoFactory.getCrypto(CryptoType.KBE);
String en = "";
if ("0".equals(args[1])) {
en = crypto.encryptString(args[0]);
} else {
en = crypto.decryptString(args[0]);
}
try {
fw = new OutputStreamWriter(new FileOutputStream(args[2]), Charset.forName("UTF-8"));
fw.write(en);
} finally {
if (fw != null) {
fw.close();
}
}
}
}
Would adding a catch(IOException e) {} mitigate this issue?
No! I think, that's the worst solution available. By the way, if you would write that, Sonar would complain about the empty catch block - so one issue solved, and one new issue would be the result.
It's more of a design error.
Think about Microsoft Word, or LibreOffice, when you want to open a file, that not exist. (For example you write in the open dialog: notExistingFile.doc and press Enter). If there's not a file, called notExistingFile.doc, it raises some kind of exception (based on the programming language/framework they use).
But instead of, crashing the app, and throw that exception towards, they handle the situation - pop up a window to inform you about the not existent file.
If this is a test-app, or some private project, where you are 100% sure about the file would exist, I would do nothing about it. But if it's a public project, you should handle the exception in some way: write a log about the missing file, inform the user about the missing file (suggest some solution for the problem), etc.
If you want the issue to go away, you should mark that as solved (or hide that issue, there's some way for it). If you'd like to solve it from java code, you should write the following:
try {
// some methods that throw IOException
} catch (IOException ignored) {
// if you call your variable ignored, Sonar won't complain about it
// but you should provide some information about this, why did you ignore that exception
// for developers looking at this code later.
}
In short, yes. Adding a catch block and removing throws IOException from the signature would prevent the issue from being raised. But as Nagy Vilmos points out, that doesn't really solve the problem. Because this is a console application, you should use the catch opportunity to inform the user of the problem. Yes, barfing the exception out at the user (via throws IOException) does that, but it takes so little effort to do that nicely (via catch and logging, as recommended by the rule description).
Related
public static void generateOutput() {
File file = new File ("C:/Users/me/Desktop/file.txt");
PrintWriter outputFile = null;
outputFile = new PrintWriter(file);
}
Above is my code, I am trying to make a PrintWriter that writes to a file I have made on my desktop called file.txt, however I am getting the error "unhandled exception type, file not found exception". I have looked at other posts and I'm unsure why I am still getting this error. I have also tried doing so without the File object. I was hoping for some guidance as to where I went wrong
The most important idea you have to understand here, is that your file may:
not be found;
have its descriptor locked (which means, that some other process uses it);
be corrupted;
be write-protected.
In all above cases, your Java program, triggering OS Kernel, will crush, and the exception will happen at the runtime. In order to avoid this accident, Java designers decided (and well they did), that PrintWriter should throw (meaning, it is a possibility to throw) FileNotFoundException and this should be a checked exception at compile time. This way developers will avoid more serious run-time problems, like program crush crush.
Hence, you either have to:
try-catch in your method that PrintWriter; or
throw the exception one level up.
I think, your question was about why that happens. Here is the answer for both - (1) why? and (2) how to solve it.
Java has an exception catch mechanism that helps you program better. You will have to handle an exception FileNotFoundException to warn that what will happen if the program cannot find your file Or you can throws this exception. I recommend learning about exception handling in Java.
This code can help you
public static void generateOutput() {
File file = new File ("C:/Users/me/Desktop/file.txt");
PrintWriter outputFile = null;
try {
outputFile = new PrintWriter(file);
} catch (FileNotFoundException e) {
// Handle if your file not found
e.printStackTrace();
}
}
Or
public static void generateOutput() throws FileNotFoundException {
File file = new File ("C:/Users/me/Desktop/file.txt");
PrintWriter outputFile = null;
outputFile = new PrintWriter(file);
}
Assuming your file exists in the given location, you need one of the following,
public static void generateOutput() throws Exception {... Your code ...}
Or
try {
//Your code
}
catch(FileNotFoundException fnne) {
// Precise exception catching example
}
catch(Exception e) {
// Not required, but adding it to catch any other exception you might face
}
You can always use precise exception in throws/catch. You need it because, PrintWriter can has compile time exception. Basically, it means if file is not found then it can throw exception and it is known at compile time. Hence you need to use one of the approach.
In addition to that, you make 2 lines into 1 as follows,
PrintWriter output = new PrintWriter(file);
You don't need to initialize the output object to null, unless you have it on purpose.
I have the following code which I am running through fortify. Why it gets marked for poor error handling, throw inside finally?
private String getResourceContent(String fileName) throws IOException {
try (InputStream resource = ErrorResource.classLoader.getResourceAsStream(fileName)) {
return new String(resource.readAllBytes(), StandardCharsets.UTF_8);
} catch (NullPointerException n) {
throw new ErrorDescriptorException(
String.format("Error loading Error description data from Resource file [%s].", fileName), n);
}
}
Explanation
This is explained very well in the official documentation (see Poor Error Handling: Throw Inside Finally). Let me quickly quote the important sections:
Using a throw statement inside a finally block breaks the logical progression through the try-catch-finally.
In Java, finally blocks are always executed after their corresponding try-catch blocks and are often used to free allocated resources, such as file handles or database cursors. Throwing an exception in a finally block can bypass critical cleanup code since normal program execution will be disrupted.
So you can easily bypass cleanup code by doing that, which leads to resource leaks.
Although not directly visible in your code, you actually have a hidden finally block since you are using try-with-resources which automatically closes the resource in a finally block.
Also see Throwing an exception inside finally where this was already discussed.
Example
Here is an example from the official documentation:
public void processTransaction(Connection conn) throws FileNotFoundException {
FileInputStream fis = null;
Statement stmt = null;
try {
stmt = conn.createStatement();
fis = new FileInputStream("badFile.txt");
...
} catch (FileNotFoundException fe) {
log("File not found.");
} catch (SQLException se) {
// handle error
} finally {
if (fis == null) {
// This bypasses cleanup code
throw new FileNotFoundException();
}
if (stmt != null) {
try {
// Not executed if the exception is thrown
stmt.close();
}
catch (SQLException e) {
log(e);
}
}
}
}
The call to stmt.close() is bypassed when the FileNotFoundException is thrown.
Note
Why are you checking for null using a NullPointerException instead of a basic if-else? There is rarely ever a valid reason to catch a NullPointerException. Just do:
try (InputStream resource = ErrorResource.classLoader.getResourceAsStream(fileName)) {
if (resource == null) {
// TODO Throw your exception here
}
return new String(resource.readAllBytes(), StandardCharsets.UTF_8);
}
It might also help to improve the error message by telling the exact reason that the resource could not be found.
Consider the following code, which is loosely based on yours:
String throwing(InputStream inputStream) throws IOException {
try (InputStream resource = inputStream) {
return "good";
} catch (NullPointerException n) {
return "bad";
}
}
You see, no exceptions thrown here. Still, you cannot remove the throws IOException bit – how’s that? Well, InputStream#close() can throw it, and it will be in the implicit finally block that the try-with-resources statement created. I guess there’s not much you can do about it, it looks like a Fortify false positive.
Beyond the misleading message from your tool, there is actually is poor error handling in your code, for multiple of reasons:
catching NPE is really bad practice. Either it is a bug (something that is null and shouldn't), or your code is missing a check if (whatever == null) and the corresponding code to deal with that expected situation
assuming that this NPE has exactly that meaning that you express in your new Exception is well, just guessing
In other words: without further information, it is not clear what exactly your tool complains about. But: one doesn't need a tool to understand: this is poor error handling.
Beyond that, such tools typically give some sort of information about their warnings. Meaning: there might be an "error id" coming with that warning, and you should be able to look up that "error id" in the documentation of your tool for further explanations.
I want my program exceptions to be sent to each of the following, preferably simultaneously:
the console which starts it (not necessarily)
a gui
a txt file.
How can I achieve this?
My attempts:
System.setErr(PrintStream err) will forward all exceptions to a new stream. I am not able to state more than
one stream though.
Calling System.setErr(PrintStream err) on a manually written OutputStream:
"You can write your own stream class that forwards to multiple streams and call System.setOut on an instance of that class" – Jeffrey Bosboom
I found a way to do this. It is very nasty though. It "collects" PrintStream's write-bytes, puts them in a puffer (500 ms timeout) and finally shows it to the user (Proceed):
/* ErrorOutput.java */
public static t_ErrBuffer t_activeErrBuffer = new t_ErrBuffer("");
public static void setStdErrToFile(final File file) {
ps = new PrintStream(fos) {
#Override
public void write(byte[] buf, int off, int len) {
byte[] bn = new byte[len];
for (int i = off, j = 0; i < (len + off); i++, j++) {
bn[j] = buf[i];
}
String msg = null;
try {
msg = new String(bn, "UTF-8");
} catch (UnsupportedEncodingException e1) {}
if (msg.matches("[\\w\\W]*[\\w]+[\\w\\W]*")) { // ^= contains at least one word character
if( ! t_activeErrBuffer.isAlive() ) {
t_activeErrBuffer = new t_ErrBuffer(msg);
t_activeErrBuffer.start();
} else {
t_activeErrBuffer.interrupt();
t_activeErrBuffer = new t_ErrBuffer(t_activeErrBuffer.getErrBuffer() + "\n" + msg); // ^= append to buffer and restart.
t_activeErrBuffer.start();
}
}
}
};
System.setErr(ps);
}
/* t_ErrBuffer.java */
public class t_ErrBuffer extends Thread {
private String errBuffer;
public t_ErrBuffer(String buffer) {
this.errBuffer = buffer;
}
protected class Proceed implements Runnable {
public String msg = null;
public Proceed(String msg) {
this.msg = msg;
}
#Override
public void run() {
// todo PRINT ERROR MESSAGE: DO THINGS WITH msg: console, gui, JOptionPane
}
}
#Override
public void run() {
try {
Thread.sleep(500); // collect error lines before output. Needed because PrintStream's "write"-method writes ErrorMessages in multiple pieces (lines)
// each time some new exception line comes in, the thread is stopped, buffer is being appended and thread new started
} catch (InterruptedException e) {
return; // stop
}
// after 500 ms of wait, no new error message line has come in. Print the message out:
Thread t_tmp = new Thread(new Proceed("\n" + this.errBuffer));
t_tmp.start();
return;
}
public String getErrBuffer() {
return this.errBuffer;
}
}
is this what I am expected to do?
Create new exception class which does it for me. Would probably work, but other exceptions than that (IO, FileNotFound, ...) will still be treated the old way
Instead of stating [method name] throws Exception I could enclose all of my code in try/catch-blocks, get the exception and forward it to a method of mine, like this:
/* AnyMethod.java */
// ...
try {
// ... do everything here
} catch (IOException | FileNotFoundException e) { // as many as you like
ErrorOutput.crash(e);
}
// ...
/* ErrorOutput.java */
public static void crash(Exception e) {
FileOutputStream fos_errOutput = new FileOutputStream(new File("ErrorOutput.txt"), true);
// 1st
if (!System.out.equals(fos_errOutput)) {
System.out.println(e.getMessage() + " :"); // to console or the preferred StdOut
e.printStackTrace();
}
// 2nd
JOptionPane.showMessageDialog(Gui.frame, "THE PROGRAM HAS CRASHED!" + "\n\n" + e.getMessage() + "\n\nFor a more detailed report, see ErrorLog.txt"); // gui output
// 3rd
PrintStream ps = new PrintStream(fos_errOutput);
ps.print(new Date().toString() + ":"); // write to file
e.printStackTrace(ps);
ps.close();
// 4th
System.exit(0); // this could also be "throw new Exception" etc., but I don't know why one should do that.
}
this would probably also work, but I'd have to put everything into try/catch-blocks. This cannot be good programming style at all.
Using a logger:
"use log4j and set up a method to write to GUI and also to log to
stdout, and file" – Scary Wombat
Loggers only help me printing my exceptions into desired streams, but they don't help me catching them, right?
But you really should use a logging package for this -- even java.util.logging can do what you need – Jeffrey Bosboom
I have to tell my logging package where and what to log. But this is exactly what I am searching for.
I now can, as user3159253 suggested, use Thread.UncaughtExceptionHandler to catch unhandled exceptions specifically.
What is the right way to handle all thrown exceptions the way I want them to? What else do I have to consider apart from Thread.UncaughtExceptionHandler and System.setErr()(see above)?
First you need get hold of all exception instances thrown from/within your thread (may be try/catch or Thread.UncoughtExceptionHandler or ThreadPoolExecutor.afterExecute(Runnable r, Throwable t)).
Then once you have the exception instance you can simply log it using log4j but configure Log4j appenders to send your exception messages to multiple destinations. You can use File, Console, JDBC, JMS etc types of appenders depending upon your requirement. Also it is best to wrap them with Async appender.
Refer - https://logging.apache.org/log4j/2.x/manual/appenders.html
About pushing the exception message to GUI, it can be implemented in various ways depending upon what tech stack your are using in your application. In our application we are storing the message events (only critical ones) in database which are then picked by event monitoring threads from server and then pushed back to GUI (JQuery, JavaScript) using http://cometd.org/documentation/cometd-java.
Creating an object that extends PrintStream should work. Whenever it receives a line, it can display it and log it as required. Alternatively, all exceptions can be caught and redirected into a method that receives an Exception as a parameter, and the method can take care of logging/displaying the exception, and terminating the program cleanly.
I just write a simple commandwrapper in java, this is construction function:
Process process;
Thread in;
Thread out;
public CommandWrapper(Process process) {
this.process = process;
final InputStream inputStream = process.getInputStream();
// final BufferedReader
//final BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
final byte[] buffer = new byte[1024];
out = new Thread() {
// String line;
int lineNumber = 0;
public void run() {
try {
while (true) {
int count = inputStream.read(buffer);
System.out.println(lineNumber + ":"
+ new String(buffer, 0, count - 1));
// line=r.readLine();
// System.out.println(lineNumber+":"+line);
lineNumber++;
}
} catch (Exception e) {
}
}
};
final BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
final OutputStream outputStream = process.getOutputStream();
in = new Thread() {
String line;
public void run() {
try {
//while (true) {
outputStream.write((reader.readLine() + "/n")
.getBytes());
outputStream.flush();
//}
} catch (Exception e) {
}
}
};
}
public void startIn() {
in.start();
}
This is when it invoke:
public static void main(String[] args) {
try {
CommandWrapper command = new CommandWrapper(Runtime.getRuntime()
.exec("wget www.google.com"));
//command.startIn();
command.startOut();
} catch (Exception e) {
e.printStackTrace();
}
}
It works OK when I run simple command like ls -l or other local commander, but when I want to run wget command it is print out nothing as output. I do know why.
From the code you've shown and your description of how you use it, the best guess is that an exception occurs, and you silently swallow it. This happens whenever you have an empty catch-block, like this:
catch (Exception e) {
}
You happen to have one in the run() method of your out thread.
Silently swallowing exceptions is extremely bad practice.
You should never ever ever do this! Depending on your application the appropriate solution varies, but since you're writing a console application you probably want to print the stack trace of the exception. In Java, this is done with e.printStackTrace():
catch (Exception e) {
e.printStackTrace();
}
Another option (which might not be appropriate in this specific case) is to rethrow the exception, possibly after wrapping it in another exception (for example one you've written specifically for your application):
catch (Exception e) {
throw e;
}
// or
catch (Exception e) {
throw new MyOwnException(e);
}
Doing either of these two (printing stack trace or rethrowing) will ensure that no exceptions go unnoticed.
However, no rule without exceptions ;)
There are cases when it is appropriate to have empty catch-clauses. If you know that some operation might throw an exception and you just want to proceed when it happens, an empty catch-clause is a good way to do it. However, the cases where this is appropriated are limited to (at least) the following conditions:
You must know the specific type of the exception. You never want to catch a general exception (i.e. catch (Exception e) since that might be thrown for any reason which you cannot possibly predict. If you use empty catch clauses, always catch specific exception type (such as IOException).
You must know why the exception was thrown. You should only swallow exceptions that you know the origin of. If you swallow any other exceptions, you'll end up like in this situation, where your code doesn't do what you expect and you can't understand why. Swallowed exceptions are extremely difficult to debug, since they are, well, swallowed, and thereby hidden.
You must know that you don't care about the exception. The reason to use empty catch-clauses is mainly (read: only) to handle situations where the code you're using treats something as exceptional, while you do not. By exeptional in this context we mean "something that shouldn't really happen, and if it does, something is seriously wrong."
An example of when empty catch-clauses are appropriate:
Say that you are using someone elses code that opens a file for reading, given the absolute path of the file. Most such routines throw exceptions if the file does not exist - it is the job of the client code (i.e. the code that calls the "open file routine") to ensure that the file exists before trying to open it. Exceptions will also be thrown if, for example, the user running the program does not have permissions to read the file.
Now, you might not really care why the file couldn't be opened, but if it couldn't you just want to keep going - in that case, you swallow all exceptions related to reading the file (in Java, likely an IOException of some sort). Note that you do not swallow all exceptions - only the ones related to opening the file!
How do I use exceptions and exception handling to make my program continue even if an exception occurs while processing certain files in a set of files?
I want my program to work fine for correct files while for those files which cause an exception in program, it should ignore.
Regards,
magggi
for(File f : files){
try {
process(f); // may throw various exceptions
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
You have to use the try/catch/finally blocs.
try{
//Sensitive code
} catch(ExceptionType e){
//Handle exceptions of type ExceptionType or its subclasses
} finally {
//Code ALWAYS executed
}
try will allow you to execute sensitive code which could throw an exception.
catch will handle a particular exception (or any subtype of this exception).
finally will help to execute statements even if an exception is thrown and not catched.
In your case
for(File f : getFiles()){
//You might want to open a file and read it
InputStream fis;
//You might want to write into a file
OutputStream fos;
try{
handleFile(f);
fis = new FileInputStream(f);
fos = new FileOutputStream(f);
} catch(IOException e){
//Handle exceptions due to bad IO
} finally {
//In fact you should do a try/catch for each close operation.
//It was just too verbose to be put here.
try{
//If you handle streams, don't forget to close them.
fis.close();
fos.close();
}catch(IOException e){
//Handle the fact that close didn't work well.
}
}
}
Resources :
oracle.com - Lesson: Exceptions
JLS - exceptions
I guess your new to programming as execeptions are a fairly fundermental concept, as problems can happen out of your control and you need to deal with it.
The basic premise is a try catch block.
try
{
//Your code here that causes problems
}
catch(exception ex)
{
//Your code to handle the exception
}
You 'try' your code, and if an exception is raised, you 'catch' it. And do what you need.
There is also an addition to the catch block in that you can add finally{} below it. Basically even if no exception is raised the finally code is still run. You may wonder the point in this, but its often used with streams/file handling etc to close the stream.
Read more on java exceptions here in tutorials written by Sun (now Oracle)- http://download.oracle.com/javase/tutorial/essential/exceptions/
try
{
//Your code here that causes problems
}
catch(exception ex)
{
//Your code to handle the exception
}
finally
{
//Always do this, i.e. try to read a file, catch any errors, always close the file
}
The question you may ask is how do you catch different exceptions, i.e. is it a null reference, is it divide by zero, is it no file found or file not writeable etc. For this you write several different catch blocks under the try, basically one catch for each type of exception, the use of "exception" is basically a catch all statement, and like in stack of if statements if an "exception" is the first catch block it will catch everything, so if you have several catch blocks ensure exception is the last one.
Again, this is a useful but large topic so you need to read up about it.
Since you are doing multiple files, you need to basically do a loop and within the loop is contained the try/catch block.
so even if one file fails, you catch it, but carry on running, the code will then loop around onto the next file unhindered.
just catch the excpetion it may throw and do nothing with it; eat it as people say :)
But at least log it!
Very concise example:
try {
your code...
} catch (Exception e) {
log here
}
Typically, I would have done this.
ArrayList<Entry> allEntries = getAllEntries();
for(Entry eachEntry:allEntries){
try{
//do all your processing for eachEntry
} catch(Exception e{
ignoredEntries.add(eachEntry);
//if concerned, you can store even the specific problem.
} finally{
//In case of resource release
}
}
if(ignoredEntries.size() > 0){
//Handle this scenario, may be display the error to the user
}
FileSystemException may be the specific exception you are looking for.
Although, a better idea for beginners is to catch an exception and print it using
System.out.println(e);
where e is the caught exception.
public class Main
{
public static void main(String args[])
{
int a=10;
try
{
System.out.println(a/0); //Here it is not possible in maths so it goes to catch block
}
catch(ArithmeticException e)
{
System.out.println("Arithmetic Exception");
}
}
}
output:Arithmetic Exception
Exception in java are runtime error which can be handled by the program, the process is called as exception handling. Parent class of exception is Throwable.
Exception : Exception are those runtime error which can be handled by program.
Error : Those runtime error which can’nt handled by the program.
Tools used to handle Exception:
Try
Catch
Finally
Throw
Throws
more