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 {.
Related
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.
I've been working on a small bit of code and though the rest of the code works, there is an error with the logging system that I've written.
When the method log(String) is called, it throws a NullPointerException.
I thought this might be because the file might not be being created, but I'm not sure what I've done wrong and as far as I can tell the file should be being created (It's not) and even if I create the file and put it into the correct position, the exception is still thrown.
I've been tinkering around with it a bit, so some of it doesn't make sense, it's probably because it was while I was debugging.
Here's the code:
package UI;
import java.io.File;
import java.io.PrintWriter;
public class InputLogger {
//Necessary for interceptor pattern
private static PrintWriter output;
//For testing remove later
private static File logFile;
public InputLogger() {
initiate("log.txt");
}
public InputLogger(String anotherFile) {
initiate(anotherFile);
}
public void initiate(String filename) {
try {
/*File */logFile = new File(filename);
if(!logFile.exists()) {
if(!logFile.createNewFile())
System.err.println("Error creating log file. Please verify that files can be created.");
}
output = new PrintWriter(logFile);
} catch (Exception e) {
System.err.println("Error accessing log file. Please verify that files can be created.");
}
}
public static void log(String action) {
try {
output.println(action);
} catch (Exception e) {
e.printStackTrace(System.out);
System.err.println("Error printing to log file. Please verify that file exists or can be created.");
}
}
public void close() {
output.close();
}
}
I think it might have something to do with the fact that I call it as a static method, but I've been looking around and I can't seem to find an explanation elsewhere.
Edit:
I forgot to actually create an InputLogger object. Thanks guys.
Most likely you forgot to create an InputLogger object. Do this:
InputLogger logger = new InputLogger();
InputLogger.log( "hoooey" );
logger.close();
Not calling close may lose a line or two.
Mixing static with a constructor and proper methods is dangerous, and an antipattern. You might remain with static, with a lazy initialization which gives your program the chance to set the file name. Or, better, avoid the statics and do all in proper methods.
In the method initiate you initialize the output, but in your static method log it's not guaranteed to have been initialized before calling since.
To be safe you should always initialize the required static variables either in the static method or as a field declaration.
In this case in your initiate it is possible to throw an exception prior to the line output = new PrintWriter(logFile) which means output is null
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.
I have written a music player in Java, but I have a problem with finding an exception to throw. Basically, what I want the exception handler to throw is if a filename of a song stored in the playlist is altered or if the file is deleted, as naturally, in that case it won't play. I first thought it was an IOException I would need, but it gave me the error saying
exception IOException is never thrown in body of corresponding try statement
Now, I understand that that means that I'm working with the wrong Exception class, and so I tried to write my own that extends Exception, but it gives me the same error when I try to compile. Can anyone see what I'm doing wrong?
This is the method as it is right now:
public void play() throws NoMatchException
{
if(player != null) {
player.stop();
}
try{
int fileToPlay = tracklist.getSelectedIndex();
String filename = organizer.getFile(fileToPlay);
Media song = new Media(filename);
player = new MediaPlayer(song);
setVolume(currentVolume);
player.play();
player.setOnEndOfMedia(new Runnable() {
#Override public void run() { next(); }
});
}
catch (NoMatchException e){
//Some exception
}
}
When you are not sure what exception you need to catch, go to the documentation of the corresponding method. It turns out that the constructor of Media would throw MediaException - this is the exception that you need to catch. Scroll down to the "throws" section, and look for the exceptions that do not extend RuntimeException (runtime exceptions usually indicate programming errors; the need to catch this is rare).
When you are deciding to catch an exception at a particular level of your program, see if your code can do something meaningful about it. You shouldn't be catching exceptions unless you know what to do when to catch them.
This code makes no sense.
Your catch block is empty and does nothing. Your method says it throws a NoMatchException. Why don't you eliminate the try/catch and let it do so?
You catch exceptions when you have a viable strategy for recovering. Doing nothing is not a strategy. Just let it bubble up and let the caller deal with it.
If you do have a viable recovery strategy, implement it in the catch block and remove the throws clause from the method signature. Either one or the other, but not both.