When I run java -jar MidiTest.jar, input a MIDI file, it throws:
Exception in thread "main" java.lang.NullPointerException
at com.sun.media.sound.StandardMidiFileReader.getSequence(StandardMidi
leReader.java:209)
at javax.sound.midi.MidiSystem.getSequence(MidiSystem.java:802)
at MidiTest.playMidi(MidiTest.java:56)
at MidiTest.(MidiTest.java:44)
at MidiTest.main(MidiTest.java:25)
If I use java MidiTest instead it could play without issue. What wrong with the code? I have already add Main-Class: MidiTest with newline on Manifest file
My code:
private void playMidi() {
if(isPlaying.equals("0")) {
try {
song = MidiSystem.getSequence(
getClass().getResource(filename));
sequencer = MidiSystem.getSequencer();
sequencer.setSequence(song);
sequencer.open();
sequencer.addMetaEventListener(this);
sequencer.start();
} catch (InvalidMidiDataException e) {
System.out.println("Bad midi file: "
+ filename);
System.exit(1);
} catch (MidiUnavailableException e) {
System.out.println("No sequencer available");
System.exit(1);
} catch (IOException e) {
System.out.println("Could not read: "
+ filename);
System.exit(1);
}
displayMidiInfo(filename);
} else {
updateTempoFactor(speed);
}
}
You don't appear to be checking if the resource you're trying to get is returning something non-null. Specifically:
song = MidiSystem.getSequence(
getClass().getResource(filename));
is causing this particular problem. There might be a deeper issue, which is that unless the resource represented by filename is actually in the jar, on the Class-Path or in the same directory as the jar file getResource() is not going to find it. If you're trying to access a file anywhere in the general filesystem (not in the jar file) then you should be using File:
song = MidiSystem.getSequence(new File(filename));
Related
I have a java code that automatically create a file for the user after login. It works properly when I run it in netbeans/intellij. However when I compiled it into a jar file, the program works but the file is not created. Can someone please help me?
Here is my code:
private void createTxtFile(){
String loc = new File("").getAbsolutePath();
String dir = loc+"/src/lists/"+user+"-"+pass+".txt";
try {
File myObj = new File(dir);
if (myObj.createNewFile()) {
System.out.println("File created: " + myObj.getName());
}
else {
JOptionPane.showMessageDialog(this, "User already have an existing list file.");
}
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "An error occured in creating file for your list.", "Error",JOptionPane.ERROR_MESSAGE);
}
}
This is the code
public static void readCharacters() {
try (FileInputStream fi = new FileInputStream("main/characters.dat"); ObjectInputStream os = new ObjectInputStream(fi)) {
characterList = (LinkedList<Character>) os.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
This is the structure:
And this is the Error
java.io.FileNotFoundException: main\characters.dat (The system cannot find the path specified)
What I want is to include the characters.dat file in my jar, and be able to read and write it while the program runs. Is there a different way to write the path? or to put the .dat file in a different position.
Also the writing method:
public static void writeCharacters() {
try (FileOutputStream fs = new FileOutputStream("main/characters.dat"); ObjectOutputStream os = new ObjectOutputStream(fs)) {
System.out.println("Writing Characters...");
os.writeObject(characterList);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
You can't. You can do one or the other. JAR files are not file systems, and their entries are not files. You can read it with an input stream:
InputStream in = this.getClass().getResourceAsStream("/main/characters.dat");
Check it for null before proceeding.
The jar is for read-only resources. You can use it for the initial file, as a kind of template.
Path path = Paths.get(System.getProperty("user.home") + "/myapp/chars.dat");
Files.mkdirs(path.getParentPath());
if (!Files.exists()) {
try (InputStream in =
Controller.class.getResourceAsStream("/main/characters.dat")) {
Files.copy(in, path);
}
}
The above copies the initial.dat resource from the jar to the user's home "myapp" directory, which is a common solution.
System.getProperty("user.dir") would the running directory. One can also take the jar's path:
URL url = Controller.class.getResource("/main/characters.dat");
String s = url.toExternalForm(); // "jar:file:/.... /xxx.jar!/main/characters.dat"
From that you can also construct the jar's directory. Mind to check Windows, Linux, spaces and such.
URL url = Controller.class.getProtectionDomain().getCodeSource().getLocation();
The solution above risks a NullPointerException, and works a bit differenly running inside the IDE or stand-alone.
Important note:
When using getResourceAsStream, you must start your path by slash /, this specifies the root of your jar, .getResourceAsStream("/file.txt");
In my case my file was a function argument, String filename, I had to do it like this:
InputStream in = this.getClass().getResourceAsStream("/" + filename);
Today i tested "files" instead of a normal path.
Here is my code:
File path=new File(getFilesDir(),"uf");
File test = new File(path.getAbsolutePath(),"test.txt");
if(!path.exists()){
path.mkdir();
}
if(!test.isFile()){
try {
test.createNewFile();
} catch (IOException e) {
//TODO in errorlog -> filecreation
e.printStackTrace();
}
}else{
try {
OutputStreamWriter mywriter = new OutputStreamWriter(openFileOutput(test.getAbsolutePath().toString(),Context.M ODE_PRIVATE));
mywriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
In the error code comes everytime: illegal Arguments: contains a path seperator!
Thank you for your help in advance
Maybe add more info about your error. But...
This error is about that you are trying to full path (include you subdirectories) to access to private data area.
Solution is use FileOutputStream, more here. And use
new File(YOUR_FILE)
to create your file.
Keep on mind that you should call method mkDirs() to create all necessary directories and subdirectories. More about mkDirs() here
Note: There is also method mkDir(), here is doc. This one will create a single directory.
I am getting the exception java.io.FileNotFoundException: D:\Selenium Reports\Daily Reports\Merged file.xls when I am trying to access excel file through java program.
I have tried with:
absolute path
relative path
read/write access to the file
checked whether the file is open
Still, it is not working, is it not working because I have guest access to the machine?
keep the .java file and the .xls file in the same folder and use the code:
try {
File f = new File("Merged file.xls");
if (!f.exists()) {
System.out.println("File does not exist");
if (!f.createNewFile())
System.out.println("File cannot be created");
else
System.out.println("File created");
} else {
System.out.println("File exists");
if(!f.canRead())
System.out.println("Error in reading. Need permission");
if(!f.canWrite())
System.out.println("Error in writing. Need permission");
}
} catch (IOException e) {
e.printStackTrace();
}
}
I am dynamically generating midi files (in cache dir) with an android app.
After generation, I play the file with MediaPlayer within the same app.
When running the app for the first time, it already needs the file to be there in the cache directory (the app crashes). It works on the emulator if I use the filemanager to put a dummy file there first. How can I circumvent this?
I need the app to run on a tablet for the first time, without requiring the file.
I am using these commands now:
try {
filePath = getCacheDir() + "/optimuse" + song + ".mid";
file = new File(filePath);
inputStream = new FileInputStream(file);
if (inputStream.getFD().valid()) {
System.out.println("Valid!");
}
} catch (Exception e1) {
e1.printStackTrace();
System.exit(-1);
}
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(inputStream.getFD());
inputStream.close();
} catch (Exception e1) {
e1.printStackTrace();
System.exit(-1);
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Is there any way around this?
Thanks!
Maybe check whether the file exists before using it? You can achieve this using the File#exists() method.
First, you use the Context#getFileStreamPath(String) method - where the String is the filename of the file you are trying to access. Then you can call File#exists() on the returned object.