Processing 2.0 Movie cannot open movie file when running from jar - java

I'm trying to run a movie using the Processing 2.0 Movie class.
If I run my program from my code editor (Eclipse in my case) everything works fine and the code runs flawlessly: it locates and starts the movie.
However, when I export my program to a jar and start it from my terminal, it does locate the file but it crashes on trying to open it.
I am currently using this code to find my movie path string.
public String locateMovie(String moviePath) {
String movie = MoviePlayer.class.getClassLoader().getResource(moviePath).getPath();
if (movie == null) {
System.out.println("FATAL ERROR --- Movie file not found: '" + moviePath + "'");
}
return movie;
}
As you can see I am using the classLoader to locate the file for me since the paths are different after I export it to a .jar file and do not wish to change the paths all the time myself. The .getPath() deletes the 'File:' in File:/Path/To/My/File as this is an unneeded side effect from using the above way.
A bit further in my code I've already added an extra check to see if nothing is wrong with the path that the classLoader is returning, I do this with the following lines.
File temp = new File(moviePath);
System.out.println("If I have something after this, the file exists: '" + temp + "'");
It always returns the right path, whether it's running from within my Eclipse (/Users/Path/To/My/Folder/2/java/Game/movies/introMovie.mp4) or from the executable .jar file (introMovie.mp4).
At first I thought it was strange that in the .jar file it was giving me a file straight away without the path leading to it because it does have some structure in my project but after using the
jar tf myProject.jar
command in my commandLine it returns the same file/pathname for the file so the path should be correct and all is still well here.
But now, when I try to load the movie via Processing' Movie class with the following code:
currentMovie = new Movie(parent, moviePath);
It throws an java.lang.StringIndexOutOfBoundsException exception and crashes. I have no idea what i'm doing wrong since this code runs flawlessly from within my code editor + I'm using the same way of locating files for my audio files and those run aswel, even from the executable .jar file.
As far as I can tell from reading the Movie class reference library it just needs a place to display it on and the path to the file which I am both giving.
I was hoping some veteran here could see what I am doing wrong and help me solve this problem that I'm been struggling with for a few days now. It's probably something stupid that I'm just overlooking right now.

I don't know exactly what's wrong but here's a couple things I would do:
check the permissions on the video file, make sure the program would have access to it.
I've read that it's a better idea to use
Thread.currentThread().getContextClassLoader()
than the class's classloader, but I don't know if that would help.
Processing libraries are open source. Maybe see exactly where that exception is being thrown and take a look at the source. It might help you pinpoint the issue.

Related

How to open Files from a Path that is not inside the Project in Java? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a problem or a question regarding Java and or Eclipse. I have a programm that does the following:
open up a UI where the user can search for a folder
if the folder is picked the absolut path is getting passed to the main
there are few folders in that chosen path
there are functions that read from the data and create a new excel with the read data
The path that I am getting is correct!
Gernerally the programm works... But it only works if:
The chosen Path from the User is a folder that is inside the project folder where I run the programm from.
OR
The Names of the files that are getting read are specified inside the project folder. What I mean with that is: if the file test.vcc is inside the package then I could open it from the desktop if there is a file that is also named test.vcc
So it seems like Java or Eclipse cant open up paths that are not inside the project or named in the project - is that true?
Running the programm gives me NullPointerExceptions for every File that is not especially named or inside the project.
Sincerly Faded
Update
Okay so I have noticed something that I am doing wrong definetly!
I was replacing the whole FILEPATH that the User choses with ".\" which obviouslly means that it will not care about the filepath and replace it with .\ instead of really taking the path.
String filePathS = filePath.replace(FILEPATH, ".\\");
When I am using this it works because it can find the files in the project Folder. So after seeing this I just took the real Path that the user choosed.
Its basically this:
String filePathSX = filePath.replace("/", "\\");
or this
String filePathSX = filePath.replace("\\", "/");
which either gives me a Path like this: C:\Users\me\dev\foldername\part\test.txt or like this C:/Users/me/dev/foldername/part/test.txt
I can check that in the destination the file test.txt does indeed exist and the path is correct. Still when it tries to do something with that file it gives me a NullPointerExeption.
IF I would leave the replace function for the whole path with .\, then it would take the test.txt file that is inside the package and it would run without any problems.
So I think that I am somehow accsessing the file in the wrong way. How should the path look like on windows if the user chooses something? c/user/... or c\user...
Because both ways do not work for me.
So it seems like Java or Eclipse cant open up paths that are not inside the project or named in the project - is that true?
Yes and no. But mostly no, that is not true.
Some OSes (most notably, Mac OS) have a security policy framework in place that denies any file access to all applications unless you explicitly allow it. If you're on a mac, that sounds like it could be the culprit.
Other than that, though - the answer is no: That is incorrect.
You'd have to ask a new question and provide a bunch of details if it's not the Mac OS thing: Show the code, show the result of printing the path, and show the actual file structure on disk, for example.
NullPointerException sounds even weirder, so maybe your code is just problematic.
This is not true...
File f = new File("C:\\path\\to\\your\\file");
// perform some checks here to make sure Desktop can actually open it
Desktop desktop = Desktop.getDesktop();
desktop.open(f);
EDIT: if you are getting NPEs, your path contains no file, try creating a file with a certain name at that location, and then opening it in your file explorer to see where it actually went

cannot create inputstream for ico file

I tried to create an InputStream pointing at an .ico file, which is in a directory in the src directory. I also create an InputStream for a different jar file in my src.
InputStream inIco = Installer.class.getResourceAsStream("/res/" + iconName + ".ico");
InputStream inApp = Installer.class.getResourceAsStream("/res/" + applicationName + ".jar");
that is how I tried to load it. The inputstream for the jar file works, but the other one is null.
Edit: Sorry for the confusion guys. I didn't build the jar, I just ran it from my editor, which obviously gives me different results, now it is working. Thanks for your answers.
getResourceAsStream (gRAS) loads from the same place java loads class files. That's great - it means you can ship your app as a jar and put these resources inside. If it's not working for you, you've misconfigured your build. Specifically, java is first going to determine the classpath root of your Installer.class file and looks there. If you're not sure what that is, run this code:
System.out.println(Installer.class.getResource("Installer.class"));
which will print something like jar:file:/Users/carlos/projects/FooBar/dist/foobar.jar!com/foo/Installer.class
and this tells you that gRAS is going to look in that foobar.jar file.
From there, the resource is loaded relatively to the root (because of that leading slash): Within that jar, it will look for /res/app.ico. Without it, it loads relative to the same dir/package of Installer class (in this example above, gRAS("hello.txt") is the same as gRAS("/com/foo/hello.txt").
To make this work out, your build system is responsible. For maven and gradle, have src/main/java/com/foo/Installer.java along with src/main/resources/res/icon.ico and all should be well. If this is not working out, explain how you've set up your environment because something is misconfigured if this isn't working. If you're using another build tool (such as perhaps ant, sbt, or relying on your IDE to take care of it), name the tool and perhaps we can help address the misconfiguration.

getResourceAsStream() returns null only when in jar file

I know the same question has been asked many many times, but going through all the answers already posted I couldn't find a solution.
First of all here's the code I'm using to test the issue after i encountered it in my project :
InputStream test;
System.out.println(this.getClass());
System.out.println(("classpath is: " + System.getProperty("java.class.path")));
test = getClass().getResourceAsStream("/pairs/images/100/back/back1.png");
if (test == null)
{
System.out.println("getClass().getResourceAsStream(\"/pairs/images/100/back/back1.png\") is null");
test = GridPanel.class.getClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}
if (test == null)
{
System.out.println("GridPanel.class.getClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");
test = ClassLoader.getSystemClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}
if (test == null)
{
System.out.println("ClassLoader.getSystemClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");
Thread.currentThread().getContextClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}
if (test == null)
System.out.println("Thread.currentThread().getContextClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");
So as per title everyone of these calls to getResourceAsStream() returns null, but only when executin the jar file, when launching inside the IDE (Netbeans 8.0.2) they all return the correct stream (tested individually not with this piece of code) and I can work with it.
The jar file contents are as follow:
While the src folder in the netbeans project folder is the following:
So I'm really baffled at the moment, I've tried using the default settings when building with netbeans but I'm losing my head around this issue.
Any hints or ideas would be much appreciated!
I think the getResourceAsStream is not reading from filesystem, the leading slash will try to read from the root of the classpath (if you add a directory will read from the root). If you don't put the leading slash, you will read from the package the class is from.
Did you add the directory/subdirectories you want to read the file from in the classpath?
TL;DR It was due some stupid issue with NTFS permission, moving the jar made it work
So I feel very stupid right now...
I tried running it in a Linux environment and everything worked as supposed.
Each one of those calls was returning a non-null InputStream pointing to the resource.
So I did something very simple: just moved around the compiled jar in Windows to check if it had something to do with NTFS permissions (keep in mind that I'm using an administrator account and I can freely write, read and execute in those folders).
Moving it to the root of the project didn't work, but moving it on the desktop WORKED.
What amazes me more is that in some other parts of the projects I'm doing
URL jarUrl = PairsDeck.class.getProtectionDomain().getCodeSource().getLocation();
to read the whole content of the jar file and that works every time even in the old directory, so that's why I hadn't thought of screwed permissions since the beginning (and I was launching it from a command prompt with admin privileges).
So I guess somehow the program can read its jar with that call but not load resources from it inside my netbeans project folder due to some issues with NTFS permissions.
To add some confusion
File file = new File(jarUrl.toURI());
file.canWrite();
file.canRead();
file.canExecute();
all of the above return true.
I'm just curious to know if there was a way to understand better the issue and maybe have a way to signal some permissions error from the java code.
Thanks wholeheartedly to everybody involved for the help!
There are two problems here.
Windows is case-insensitive. Other platforms and inside a jar names are case-sensitive.
The getClass() class determines in which jar/class path the resource is souught. Especially a unit test will not be put in a jar, or a child class might be located outside the jar. Either use a SomeClassInJar.class or use a ClassLoader which searches over all jars/class paths. A class loader uses only absolute paths, and you must not start the path with a /.

Illegal Argument Exception: URI is not hierarchical with runable .jar file

I know this question has been asked a bunch of times before, but I'm peeled through all the other threads and tried a bunch of stuff, but can't find anything that resolves my issue. I have a program that compiles and runs without issue in Eclipse, but when I export a runnable .jar file, it won't launch. I tried running it from the cmd prompt, and got the error Illegal Argument Exception: URI in not hierarchical. This is happening in an included sound file which I have as a classpath resource. The code is like this:
try {
pop = new File(IntroView.class.getResource("/model/pop.wav")
.toURI());
} catch (URISyntaxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
From what I've read it's a problem with the way that the file is being packed up into the .jar, but I'm having a hard time wrapping my head around it. Can anybody shed some light on this and possibly provide a solution? Thanks.
I am sorry but it seems you cannot represent a File object from inside a JAR. When locating a file using File object it checks for file in the OS directory structure only. The File object can locate the JAR itself in a directory but not what's inside.
You can get the InputStream to the file inside JAR like this as stated in a few places:
InputStream input = PlaySound.class.getResourceAsStream("Kalimba.mp3");
You could have these options:
Read the file from JAR and write it outside in your directory and
then get the File Object.
Extract the JAR to a folder and point to that with a File.
Simply get the InputStream and play the file as shown here:
How can I play sound in Java?
Alright so I got it working, but it's not really an ideal solution. What I ended up doing is creating a folder within the project, but outside of the source. So before, the resources were in
Project/src/Model/pop.wav
Now they are in
Project/Resources/pop.wav
I then just accessed then like this
pop = new File("Resources/pop.wav");
So as this stands, it still only works when launching from the IDE, but what I did was add a new folder within the same folder that the .jar is being run from which contained all the same resource files. The file reference looks for pop.wav relative to whichever directory the program(either in the IDE of from the .jar) is being run from, so it finds the files in this new folder and works fine. I don't feel it's the prettiest solution, but it works anyway.

Why is a file being saved to a different directory path in NetBeans?

For some unusual reason, when I am using FileWriter for Java Netbean, the file gets written into this directory:
C:\Users\myname\AppData\Roaming\NetBeans\7.2\config\GF3\domain1
rather than to my working directory, which is at the desktop.
I used this code to check my User Directory, and it returns this:
System.out.println(System.getProperty("user.dir"));
INFO: C:\Users\myname\AppData\Roaming\NetBeans\7.2\config\GF3\domain1
which is obviously NOT my working directory where my source code is. I thought I could have accidentally configured Netbeans to change the directory, but I checked through NetBeans menu and can't figure out how to undo this.
I have never had this problem before in my previous projects. As simple as the following code, the file should appear in my working directory.
File file = new File("myFile.xml");
Instead now I'm being forced to enter the path name to make the file save into my working directory, which is not going to be dynamic if I change computer.
String dir = "C:\\Users\\myname\\Desktop\\Assignment\\IRAssignmentJ\\";
File file = new File(dir + "myFile.xml");
Please enlighten me how do I solve this.
rather than to my working directory, which is at the desktop
No it isn't. The current working directory is whereever the file got saved, by definition. If Netbeans chooses to change directory to where it was saved, there's nothing you can do about it. If you want it in your home directory, there is a system property for that. If you want it saved somewhere else, use a full pathname.
But the behaviour of the application under Netbeans is of little interest. What matters is when you run it as though standalone, like a customer would.

Categories