3

I am accessing a Java resource to use in my JavaFX application..

URL resource = getClass().getClassLoader().getResource("/image.jpg");
File file = new File(resource.getFile());
if (!file.exists()) {
    throw new FileNotFoundException("No image: " + file)
}

Everything works fine and the resource is found when running as the Java application.

However, now I am bundling my JavaFX application in a native Mac app using zenjava's Maven plugin:

<plugin>
    <groupId>com.zenjava</groupId>
    <artifactId>javafx-maven-plugin</artifactId>
    <version>2.0</version>
    <configuration>
        <mainClass>
            com.seaniscool.foobar.FooBar
        </mainClass>
    </configuration>
</plugin>

I build with the native plugin using:

mvn clean jfx:native

Now, when I run the application by running the Mac .app file, this resource can no longer be resolved to a file. getResource returns this URL:

jar:file:/Projects/foobar/target/foobar.app/Contents/Java/foobar-jfx.jar!/image.jpg

But it cannot be found when used as a File path.

Sean Connolly
  • 5,692
  • 7
  • 37
  • 74
  • 1
    Why do you need it as a `File`? – Sotirios Delimanolis Oct 15 '13 at 19:15
  • ..? To do things with it? – Sean Connolly Oct 15 '13 at 19:18
  • 1
    What _kind_ of things? You already have access to the `InputStream` through `openStream()` on the `URL` object. It's not actually a file in the `jar`. – Sotirios Delimanolis Oct 15 '13 at 19:19
  • A embedded resources is not a File, it can not be accessed as one. Instead, you need to either use the URL reference passed back by getResource or the InputStream reference passed back by getResourceAsInputStream. The reference you have is nothing more then a pointer to Zip entry within your Jar file... – MadProgrammer Oct 15 '13 at 19:22
  • Wow, I never knew that. I've always treated them as 'file references' or something. I'll reconsider how I access the content then, cheers! PS: you should post a response so I can accept and others can learn from my mistakes eh? – Sean Connolly Oct 15 '13 at 19:24

2 Answers2

1

The URL in

URL resource = getClass().getClassLoader().getResource("/image.jpg");

is a uniform resource locator. In this case it locates the resource identified by /image.jp in a .jar file. Which, as it turns out, is a type of zip file.

jar:file:/Projects/foobar/target/foobar.app/Contents/Java/foobar-jfx.jar!/image.jpg

A zip entry is not a file, it's just a bunch of bytes that have some meaning to a zip file. If you want to get those bytes as an InputStream, inflated, you can simply call

InputStream inputStream = resource.openStream();

See the javadoc of URL#openStream().

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • @Sean You are welcome. Note that, with Java 7 NIO package, you can do some funky things to access jar/zip entries as `FileSystem` `Path` objects. [See an example here](http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html) This helps if you need to remove/add things to the jar. The entry is _still_ not a file, however. – Sotirios Delimanolis Oct 15 '13 at 19:40
0

You must use the fully qualified name meaning : /package1/package2/.../file-name not /file-name directly