I am new to Java. And I find it really annoying to keep writing throws IOException in the "main" and all the methods that open a file. For example:
class something{
public static void main(String[] args) throws IOException{
myobj abc = new myobj();
abc.read_file("this_file.txt");
abc.insert("text");
}
}
class myobj{
....
public void read_file(String file_loc) throws IOException{
blablabla
}
}
In this case, I have already written "throws IOException" twice. Is there a way to handle this once and for all ?
Edit:
Thanks for all the good answers. A lot of people suggested using try-catch statements.
I read about try and catch statements and I got really confused. My question is where should I carry on writing my code i.e. abc.insert("text") into the try catch statements after abc.read_file("this_file.txt") ? Should I carry on in catch block or outside it ? This is what really puzzles me.
There's no catch-all "all methods in this class throw this exception," you'll have to declare the exception on each method (e.g., read_file, etc.) or handle it within the method. This is the point of checked exceptions: To ensure that at each stage, it's clear where they may come from and where they're handled.
Note: main shouldn't throw, you should catch the exception and handle it.
Who is main throwing to? No one.
Java has checked and unchecked exceptions. Checked exceptions leave you no choice: you either have to catch them or add them to your method signature in a throws clause.
Unchecked exceptions don't require handling.
You always have the option of catching a checked exception and rethrowing it as a custom unchecked exception.
I'd write it this way:
class something{
public static void main(String[] args)
try {
myobj abc = new myobj();
abc.read_file("this_file.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}
class myobj{
....
public void read_file(String file_loc) throws IOException{
blablabla
}
}
I am new to Java.
Hi, I hope you enjoy your learning. Learning a new programming language effectively implies learning the idiomatic ways in which to code in that language (even the ones that we subjectively find annoying.)
This is not unique to Java. Whether you do C# or Python or C++ or Haskell, you will be bound to find something that is annoying. Then the question is, what value do you get in the effort to avoid that annoyance.
If you become more productive by avoiding the annoyance, then more power to you. Otherwise, I would follow Maya Angelou's advice: "If you don't like something, change it. If you can't change it, change your attitude."
And I find it really annoying to keep writing
throws IOException in the "main" and all the methods that open a file.
In real life development, you will be handling far more non-main exceptions that main ones (probably only one main.)
So what is the threshold, the ration of main/(all other functions) by which the annoyance is justifiable and constructive? One main and one function? One main and a dozen? One main and a hundred?
Of all the plumbing and elbow grease that needs to be done with Java, declaring exceptions on the main function is an exercise in emotion of very little use.
So take it with a grain of salt, but in my professional opinion (18 years, Java, C++, Python and a lot of other crap) is this: declare your exceptions, even on main.
Why? Because it is possible that other programs might invoke your main. That is, your Java program might be invoked from the console, or it might be embedded (invokable?) from another program.
I've done this a lot for testing or for developing systems that are embeddable. So, in this case,
you want to declare those exceptions. However, since such a program is intended for standalone and embedded use, this is the general pattern I follow (java-like pseudocode, far more simplified than real-life code):
class UtilityDelegate {
UtilitytDelegate(){ .... }
void performWork(File f) throws IOException {
// do something with file
}
}
public class SomeUtility {
public static void main(final String[] args) throws IOException {
File f = null;
try{
// do something that could throw an exception
f = new File(args[0]);
performWork(f);
} finally {
// do necessary clean-up, if any, such as closing file handles,
// sockets, flushing database changes, pray to Lord Xenu, whatever
if( f != null ){
try{
f.close();
}catch (IOException e){
e.printStackTrace(); // or use a logging mechanism or whatever
}
}
}
}
}
Now, your program can be called from the command line:
java SomeUtility myfile
Or from another java class:
public class SomeUtilityClient{
public static void main(final String[] args){
// for brevity, I'm omitting the case when the utility might
// call System.exit() itself.
try{
SomeUtility.main("a-pre-defined-filename");
} catch(IOException e){
someLog("call to utility failed, see exception", e);
System.exit(-1);
}
System.exit(0);
}
}
An argument could be made that such a java client should call the embedded program via another method name, not main. That is fair, and in many cases, it is the better approach.
But just consider this one reason or approach of why to declare your exceptions everywhere, even on your main.
The main method doesn't need to throw anything.
class something{
public static void main(String[] args)
try {
myobj abc = new myobj();
abc.read_file("this_file.txt");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
}
I know you may find this language feature annoying but trust me, it is far less frustrating than managing code which does not propagate exceptions. You spend hours and hours wondering why your code is not doing something and then you stumble across this:
try {
doSomethingImportant();
}
catch(Exception e) {
// Nah can't be bothered
}
Simply put, no.
There are two ways to deal with exceptions:
You either handle that exception in your current method (main in your case) by surrounding the API that throws the exception with try-catch and writing code in the catch block to handle it OR
Add "throws IOException" on the method signature in which case you force the callers of your method to deal with it.
Related
I am new to programming and trying to insert the mp3 file on Mac, but I have errors with these codes. I have been looking for solutions for a long time but I was not able to find the right answers. I would like to know what I did wrong.
import javazoom.jl.player.Player;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
public class Music {
public static void main(String [] args) {
String filename = "src_music_typing.mp3";
MusicPlayer music = new MusicPlayer(filename);
music.play();
}
}
class MusicPlayer {
private final String mp3File;
private Player jlPlayer;
public MusicPlayer(String mp3File) {
this.mp3File = mp3File;
}
public void play() {
try {
FileInputStream fis = new FileInputStream(mp3File);
BufferedInputStream bis = new BufferedInputStream(fis);
jlPlayer = new Player(bis);
} catch (Exception e) {
System.out.println("problem file is " + mp3File);
System.out.println(e.getMessage());
}
new Thread() {
public void run() {
try {
jlPlayer.play();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}.start();
}
public void close() {
if(jlPlayer != null) jlPlayer.close();
}
}
Problem:
problem file is src_music_typing.mp3
src_music_typing.mp3 (No such file or directory)
Cannot invoke "javazoom.jl.player.Player.play()" because "this.this$0.jlPlayer" is null
The error is telling you simply that src_music_typing.mp3 does not exist; evidently you aren't running this in the directory you think you're running it in. Trivial solution: Make that path string (String filename = "src_...") an absolute path instead.
NB: It's a cavalcade of problems, here. Your code is bad and it leads to inefficient error messages. Inefficient enough to confuse you, for example.
You should never catch an exception just to log it and then blindly continue; I know a ton of code snippets do this, but that part of them is just bad. You don't want to do that - dealing with an error by blindly continuing on is, obviously, a really silly thing to do!
The right way to deal with exceptions that you don't explicitly know how to handle is instead to just throw them on. your play method should be declared as throws IOException, as this is inherent to your API design, this is fine (it's inherent because your music player class as a property that represents a file name, and anything file related is expected to throw IOExceptions, hence, fine - not leaking an abstraction).
Then the whole try/catch bit can just go away, yay! Your code is better and shorter and easier to understand, win win win!
Because you didn't do that, and you just run blindly on, you get a second error that is complaining about attempting to invoke play() on a null pointer. This error is meaningless, in that it's merely a symptom, not the cause. The cause is the first error message. This is one of a few key reasons why 'keep blindly going' is a really bad idea - it means you get a ton of meaningless, confusing errors after the actual problem, resulting in a ton of error output, most of which is just hiding the actual problem.
If you can't throw them on, a distant second best solution is to put this in your catch blocks: throw new RuntimeException("uncaught", e);. This preserves all error information (type, message, stack trace, causal chain - all of it), and still ensures code does not blindly continue when your method is an unknown (to you) state. If you have an IDE that inserts catch blocks for you, update its template.
NB: main can and usually should be declared as static void main(String[] args) throws Exception {.
I want to individually log every unique error I have, as searching though a dozen log files each +10k lines in length is time wasting and tedious.
I catch all exceptions I possibly can, but oftentimes other threads or libraries will shoot off their own errors without any way to process them myself.
Is there any workaround for this?
(E.G. an event for when printStackTrace() is called.)
Is there any workaround for this?
(E.G. an event for when printStackTrace() is called.)
Remap System.err to intercept throwables. If you look at the source code for Throwable.printStackTrace() you'll see that it indirectly calls System.err.println(this);
For example:
import java.io.PrintStream;
public class SpyPrintStream extends PrintStream {
public static void main(String[] args) {
System.setErr(new SpyPrintStream(System.err));
System.setOut(new SpyPrintStream(System.out));
new Exception().printStackTrace();
}
public SpyPrintStream(PrintStream src) {
super(src);
}
#Override
public void println(Object x) {
if (x instanceof Throwable) {
super.println("Our spies detected "+ x.getClass().getName());
}
super.println(x);
}
}
Keep in mind there is all kinds of issues with using this code and it is not going to work in cases where printStackTrace is called with stream that is not standard stream.
You could always do a deep dive into java.lang.instrument if you really want to trap all exceptions.
I catch all exceptions I possibly can, but oftentimes other threads or libraries will shoot off their own errors without any way to process them myself.
Most libraries either throw exceptions back to the caller or use a logging framework. Capture the exception or configure the logging framework.
I want to individually log every unique error I have, as searching though a dozen log files each +10k lines in length is time wasting and tedious.
Logging frameworks include options to deal with this. DuplicateMessageFilter is an example.
Food for thought:
public class DemoClass {
private Map<String, Exception> myExceptions = new HashMap<>();
public void demoMethod() {
try {
// throwing an exception for illustration
throw new IOException("some message");
} catch (IOException e) {
myExceptions.putIfAbsent(e.getLocalizedMessage(), e);
// actually handle the exception
...
}
}
public void finished() {
for (Exception e : myExceptions.values()) {
e.printStackTrace();
}
}
}
You could store any exception you haven't seen yet. If your specific scenario allows for a better way to ensure you only save an exception only once you should prefer that over mapping by Exception.getLocalizedMessage()
Is the following static helper function an anti-pattern?
public class CustomException extends RuntimeException {
// ...
public static void rethrow(String s, Exception e) throws CustomException {
throw new CustomException(s + "\n" + "Exception: " + e.getMessage());
}
}
Couldn't see it on http://javapeanuts.blogspot.com/2012/02/exception-management-antipatterns.html or elsewhere.
One immediate problem is that static warnings get broken, eg I can't do the following anymore:
final Blah blah = null;
try {
blah = foo();
}
catch (Exception e) {
CustomException.rethrow("Couldn't blah", e);
}
bar = blah.bar(); // ERROR: Variable 'blah' might not have been initialized.
Hmmmm, I think I solved it. :-) I should create a constructor for CustomException that takes a String and Exception as args.
Yes, catching the RuntimeException and creating a new path inside your application isn't allowed, because it's completely wrong to catch the RuntimeException, as the main reason that it has been thrown has to mainly do with things like the resources of your system for example and such other things, not related with your code.
Instead, you should terminate the specified code's flow and inform the user respectively.
But, there are some cases that the depicted anti-pattern may sound better, so, you would better go through the following threads, in order to develop a better idea, according to your problem, at any given time:
Extending Exception/RunTimeException in java?
Need to create a new RunTimeException for EmptyStacks
Why would I extend java.lang.RuntimeException
When to choose checked and unchecked exceptions
The above are not more than words, which means that in the end, the final design (i.e. following the language specification/creating anti-patterns) is up to you, but what you should always keep in mind (and decide/act accordingly, per case) is that one layer's runtime exception is another layer's checked (and acted upon) exception.
Some 3rd party library swallowed an Exception:
String getAnswer(){
try{
// do stuff, modify instance state, maybe throw some exceptions
// ...
return computeAnswer();
}catch (SomeException e){
return null;
}
}
As much as I want to change it into:
String getAnswer() throws SomeException{
// do stuff, modify instance state, maybe throw some exceptions
// ...
return computeAnswer();
}
I can't, because the library is already packaged into a jar. So, is there a way to bring the exception back?
I don't need to rethrow, a stacktrace with exception and message would work too.
I don't think reflection would help here, Unsafe perhaps?
Yes I know I can use a debugger to find out what's happening, but that wouldn't be very useful if I need the exception at runtime for logging and stuff like that
You can do it without reflection or AOP. The main idea is to throw another (unchecked) exception in the constructor of SomeException. There are some limitations (see at the end of this answer) but I hope it fits your needs.
You need to replace the SomeException with a new version (just create a SomeException.java file in the original package but in your src directory) with something like :
package com.3rdpartylibrary;
public class SomeException extends Exception {
public static class SomeExceptionWrapperException extends RuntimeException {
public SomeExceptionWrapperException(final SomeException ex) {
super(ex.getMessage(), ex);
}
}
public SomeException(final String message) {
super(message);
throw new SomeExceptionWrapperException(this); //<=== the key is here
}
}
The SomeExceptionWrapperException has to be unchecked (inherit from RuntimeException or Error). It will be our wrapper to carry the SomeException accross the ugly 3rd party catch(...)
Then you can catch the SomeExceptionWrapperException in your code (and eventually rethrow the original SomeException:
//original, unmodifiable 3rdParty code, here as a example
public String getAnswer() {
try {
//some code
throw new SomeException("a message");
} catch (final SomeException e) {
return null;
}
}
//a wrapper to getAnswer to unwrapp the `SomeException`
public String getAnswerWrapped() throws SomeException {
try {
return getAnswer();
} catch (final SomeExceptionWrapperException e) {
throw (SomeException) e.getCause();
}
}
#Test(expected = SomeException.class)
public void testThrow() throws SomeException {
final String t = getAnswerWrapped();
}
The test will be green as the original SomeException, will be thrown.
Limitations:
This solution will not work if either :
if SomeException is in java.lang as you cannot replace java.lang classes (or see Replacing java class?)
if the 3rd party method has a catch(Throwable e) (which will be horrible and should motivate you to ignore the full 3rd party library)
To solve this based on your constraints I would use aspects (something like AspectJ) and attach it to the creation of your exception, logging (or having it call some arbitrary) method then.
http://www.ibm.com/developerworks/library/j-aspectj/
If all you're looking for is to log the stacktrace + exception message, you could do that at the point you're throwing your exception.
See Get current stack trace in Java to get the stack trace. You can simply use Throwable.getMessage() to get the message and write it out.
But if you need the actual Exception within your code, you could try and add the exception into a ThreadLocal.
To do this, you would need a class like this that can store the exception:
package threadLocalExample;
public class ExceptionKeeper
{
private static ThreadLocal<Exception> threadLocalKeeper = new ThreadLocal<Exception>();
public static Exception getException()
{
return threadLocalKeeper.get();
}
public static void setException(Exception e)
{
threadLocalKeeper.set(e);
}
public static void clearException()
{
threadLocalKeeper.set(null);
}
}
... then in your code which throws the Exception, the code that the 3rd party library calls, you can do something like this to record the exception before you throw it:
package threadLocalExample;
public class ExceptionThrower
{
public ExceptionThrower()
{
super();
}
public void doSomethingInYourCode() throws SomeException
{
boolean someBadThing = true;
if (someBadThing)
{
// this is bad, need to throw an exception!
SomeException e = new SomeException("Message Text");
// but first, store it in a ThreadLocal because that 3rd party
// library I use eats it
ExceptionKeeper.setException(e);
// Throw the exception anyway - hopefully the library will be fixed
throw e;
}
}
}
... then in your overall code, the one that calls the third party library, it can setup and use the ThreadLocal class like this:
package threadLocalExample;
import thirdpartylibrary.ExceptionEater;
public class MainPartOfTheProgram
{
public static void main(String[] args)
{
// call the 3rd party library function that eats exceptions
// but first, prepare the exception keeper - clear out any data it may have
// (may not need to, but good measure)
ExceptionKeeper.clearException();
try
{
// now call the exception eater. It will eat the exception, but the ExceptionKeeper
// will have it
ExceptionEater exEater = new ExceptionEater();
exEater.callSomeThirdPartyLibraryFunction();
// check the ExceptionKeeper for the exception
Exception ex = ExceptionKeeper.getException();
if (ex != null)
{
System.out.println("Aha! The library ate my exception, but I found it");
}
}
finally
{
// Wipe out any data in the ExceptionKeeper. ThreadLocals are real good
// ways of creating memory leaks, and you would want to start from scratch
// next time anyway.
ExceptionKeeper.clearException();
}
}
}
Beware of ThreadLocals. They have their use, but they are a great way of creating memory leaks. So if your application has a lot of threads that would execute this code, be sure to look at the memory footprint and make sure the ThreadLocals aren't taking up too much memory. Being sure to clear out the ThreadLocal's data when you know you no longer need it should prevent that.
JVMTI agent can help. See the related question.
I've made an agent that calls Throwable.printStackTrace() for every thrown exception, but you may easily change the callback to invoke any other Java method.
A rather dirty trick that could do the job with less effort than AOP or de-/recompile the JAR:
If you can copy the source code, you can create a patched version of the class in question with your version of the getAnswer method. Then put it on your classpath before the third party library that contains the unwanted version of getAnswer.
Problems could arise if SomeException is not a RuntimeException and other third party code calls getAnswer. In this situation I am not sure how the resulting behavior will be. But you could circumvent this by wrapping SomeException in a custom RuntimeException.
Could you not just use a reference variable to call that method, if the result is a null, then you can just display a message/call an exception, whatever you want?
if you're using maven, you would exclude packages of the library.
Dependency Exclusions.
I hope to be helpful
If you have the source to the throwing class, you can add it "in the original package but in your src directory" using the technique as #BenoƮt has pointed out. Then just change
return null;
to
return e;
or
e.printStackTrace();
etc.
This would be quicker then making a new Exception.
I'm reviewing a midterm I did in preparation for my final exam tomorrow morning. I got this question wrong, but there's no correct answer pointed out, and I neglected to ask the prof about it.
Consider the following code snippet:
public static void main(String[] args) throws FileNotFoundException
Which of the following statements about this code is correct?
The main method is designed to catch and handle all types of exceptions.
The main method is designed to catch and handle the FileNotFoundException.
The main method should simply terminate if the FileNotFoundException occurs.
The main method should simply terminate if any exception occurs.
I had chosen the second option.
Answer is number 4,
4.- The main method should simply terminate if any exception occurs.
The throws clause only states that the method throws a checked FileNotFoundException and the calling method should catch or rethrow it. If a non-checked exception is thrown (and not catch) in the main method, it will also terminate.
Check this test:
public class ExceptionThrownTest {
#Test
public void testingExceptions() {
try {
ExceptionThrownTest.main(new String[] {});
} catch (Throwable e) {
assertTrue(e instanceof RuntimeException);
}
}
public static void main(String[] args) throws FileNotFoundException {
dangerousMethod();
// Won't be executed because RuntimeException thrown
unreachableMethod();
}
private static void dangerousMethod() {
throw new RuntimeException();
}
private static void unreachableMethod() {
System.out.println("Won't execute");
}
}
As you can see, if I throw a RuntimeException the method will terminate even if the exception thrown is not a FileNotFoundException
Dude, a little late, but answer is Number 3.
Number 1 is false because it is not handling FileNotFoundException
Number 2 is false for the same reason.
Number 3 is true. If a FileNotFoundException is thrown, the main method will terminate.
Number 4 is false. It would not terminate in case of ANY exception. It would terminate only in case of unchecked exception or FileNotFoundException. If there are not other checked exceptions declared in the 'throws' clause, it means they are being handled within the method.
The main method is not catching any exceptions, instead it handles the FileNotFoundException by throwing it to the source which invoked the main method.
The system runtime launches the JVM classes, one specific class among the JVM classes invokes the main method.
The handling for the main method's throws is at the mercy of the JVM classes in that case.
You can read about it in the Java language specification provided by Oracle.
Additionally you can view the source code for some of the JVMs available out there, going that path though takes you away to other programming languages,OpenJdk.
I thought of sharing my small humbled research crust in that topic, hope it helps curious ones :)
I agree with some other answers that the correct answer to the question is option 3. Option 4 says:
The main method should simply terminate if any exception occurs.
Note the "any" in this option. Here's an example of code in which an exception occurs, but main() does not terminate:
public static void main(String[] args) throws FileNotFoundException {
try {
methodThatThrowsACheckedException();
} catch (SomeCheckedException e) {
// do something to handle this exception
}
}
In this code an exception occurs, but the method does not terminate, as it's been setup to handle this exception. If the exception were an uncaught UncheckedException, then the method would terminate, of course. The point of option 4, though, is that any counter-example invalidates it, since it says "any" exception occurs.
Option 3, however, limits this termination to only occur when the exception in the method's signature is thrown:
The main method should simply terminate if the FileNotFoundException occurs.
The reason option 3 makes more sense is because code like the following does not make sense in practice:
public static void main(String[] args) throws FileNotFoundException {
try {
methodThatThrowsFileNotFoundException();
} catch (FileNotFoundException e) {
// do something to handle this exception
}
}
It doesn't make much sense to declare that a method throws an exception, but catch that exception in the method (unless, perhaps, you re-throw it after doing something, in which case option 3 still holds, as the method terminates eventually).
With only the declaration of main(), it is impossible to say which answer is objectively correct. Any of the statements could be true, depending on the definition of the method.
The main method is designed to catch and handle all types of exceptions.
The main method is designed to catch and handle the FileNotFoundException.
Both of the above statements are true of the following:
public static void main(String[] args) throws FileNotFoundException {
while (true) {
try {
doSomething();
}
catch (Exception e) {}
}
}
The declared exception is never thrown by main(), but that is not an error; just pointless and misleading.
The main method should simply terminate if the FileNotFoundException occurs.
The main method should simply terminate if any exception occurs.
Both of the above statements are true of the following:
public static void main(String[] args) throws FileNotFoundException {
try {
doSomething();
}
catch (Exception e) {
return;
}
}
Of course, we can guess at the intention of the question based on what a decent and reasonable programmer might intend to communicate with this method signature. Which would be that they intend for the method to throw FileNotFoundException, and necessarily handle other checked Exceptions. We can also reasonably assume that "handle" does not just mean "process", but specifically that it will not (re-)throw such an exception.
These assumptions immediately rule out #1 and #2.
The remaining question is whether "simply terminate" includes throwing an exception, or only an explicit return/System.exit(). In the former case, both of #3 and #4 could still be true:
public static void main(String[] args) throws FileNotFoundException {
try {
doSomething();
}
catch (FileNotFoundException fnfe) {
throw fnfe;
}
catch (Exception e) {
return;
}
}
In the latter case, neither #3 nor #4 can be true while also satisfying the assumption that main() will throw FileNotFoundException.
In sum, the options are not worded well. If I had to pick an answer, it would be #3 based on the logic of MartinV's answer. My assumption would be that the word "should" in #3 was an unfortunate choice by the professor, and that something like "may" would have been a better option. It would also have been a good idea to use more precise language than "simply terminate" (and, arguably, "handle").
The answer is both 2 & 3.
2.The main method is designed to catch and handle the FileNotFoundException.
3.The main method should simply terminate if the FileNotFoundException occurs.
But if fails to handle the exception even though it is designed to handle it and the programs gets terminated abnormally.
throws keywords is used to make JVM handle the exceptions which we are lazy to handle, it compiles successfully but shows the exception during runtime(if u handle it in main method then it compiles and runs successfully).
4.The main method should simply terminate if any exception occurs.
Is not correct always because the exceptions which occurs may be handle in the main method.
1.The main method is designed to catch and handle all types of exceptions.Is incorrect as JVM doesn't handle unchecked exceptions.