LWJGL Forum

Programming => General Java Game Development => Topic started by: Eternity on June 01, 2011, 23:28:16

Title: Java web start and resources in Jars.
Post by: Eternity on June 01, 2011, 23:28:16
Hi.

I've got my game to read all resource files from jars. This works fine in eclipse where i added the jar that contains the resources to the build path of my project.

I cant however get it to read the resources from the Jar in java web start. Im guessing there might be something wrong in my JNLP file? (ive never done any of this before btw) Please take a look :D and if its not the JNLP file what else could it possibly be? seeing as it reads frim the Jar just fine when i run it localy.

the source for lwjgl is also compiled into SpheresOfMadness.jar.

<!-- test jnlp file -->
<jnlp
  spec="1.0+"
  codebase="http://www.distantmelody.net/temp/">
  <information>
    <title>Spheres of Madness</title>
    <vendor>DMStudio</vendor>
    <homepage href="http://www.distantmelody.net/"/>
    <description>Spheres of Madness</description>
    <description kind="short">Spheres of Madness</description>
    <icon kind="splash" href="logo.png" />
  </information>
  <security>
    <all-permissions/>
  </security>
  <resources>
    <j2se version="1.6+"/>
    <jar href="SpheresOfMadness.jar" main="true"/>
    <jar href="data.jar"/>
  </resources>
  <resources os="Windows">
    <j2se version="1.6+"/>
    <nativelib href="native-windows.jar"/>
  </resources>
  <application-desc main-class="spheres_of_madness.SpheresOfMadness">
    </application-desc>
</jnlp>

Title: Re: Java web start and resources in Jars.
Post by: Endolf on June 02, 2011, 06:15:06
What code are you using to get the resources?, webstart fiddles with the classloader, so you will probably want to do Thread.currentThread().getContextClassLoader().getResourceAsStream(resource) or something like that depending on if you want the stream or url.

HTH

Endolf
Title: Re: Java web start and resources in Jars.
Post by: Matthias on June 02, 2011, 06:51:56
From my experience it's best not to use the context class loader at all.

Put the resources in the same (or a sub folder) of one of your classes. Or make a Resources class where your resources are.
Resources.class.getResource("gfx/logo.png");

This works for all cases where you would be able to load/use class too, which makes it very easy to use and low maintenance.

NOTE: Class.getResource() works with relative paths, it can only reliable access resources in the same JAR as the class file.
NOTE: Some tools related to signing / verification have issues with data only JARs, so the above approach also works these issues.
Title: Re: Java web start and resources in Jars.
Post by: Eternity on June 02, 2011, 07:28:12
Thnx! il try that solution when i get home from work today.
Title: Re: Java web start and resources in Jars.
Post by: Endolf on June 02, 2011, 07:28:57
Quote from: Matthias on June 02, 2011, 06:51:56
From my experience it's best not to use the context class loader at all.

Ok, so now the poor chap has 2 conflicting views :), do you use webstart?

for further reference, google the context class loader v.s. the current class loader (or something along those lines). See http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html (http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html) for someone elses view :)

Endolf
Title: Re: Java web start and resources in Jars.
Post by: Endolf on June 02, 2011, 07:34:32
Ok, this link is straight from the webstart docs :)

http://download.oracle.com/javase/1.5.0/docs/guide/javaws/developersguide/faq.html#211 (http://download.oracle.com/javase/1.5.0/docs/guide/javaws/developersguide/faq.html#211)

HTH

Endolf
Title: Re: Java web start and resources in Jars.
Post by: Matthias on June 02, 2011, 07:49:31
Quote from: Endolf on June 02, 2011, 07:28:57
...
Ok, so now the poor chap has 2 conflicting views :), do you use webstart?
...
Endolf
Yes - I use Webstart and both signed and unsigned applets (with LWJGL Appletloader). And my approach above has always worked perfectly in all environments.
And I nearly always use getResource() over getResourceAsStream() because this allows me to reference other resources using relative paths.
Title: Re: Java web start and resources in Jars.
Post by: Endolf on June 02, 2011, 08:19:18
Quote from: Matthias on June 02, 2011, 07:49:31
Yes - I use Webstart and both signed and unsigned applets (with LWJGL Appletloader). And my approach above has always worked perfectly in all environments.
I had troubles waaaay back when I first started with resources, I've used the context classloader ever since, it works perfectly in webstart and when running in eclipse. It's also necessary when doing webapps in JEE land, but that's a different environment :)

Quote
And I nearly always use getResource() over getResourceAsStream() because this allows me to reference other resources using relative paths.

Me too, I just happened to have that example to hand and didn't want to post something that didn't compile (couldn't remember that capitalisation and CBA to look at the javadoc :))

Endolf
Title: Re: Java web start and resources in Jars.
Post by: Eternity on June 02, 2011, 19:52:13
OK. i placed everything in one jar file and i used Thread.currentThread().getContextClassLoader(). The result is my java web start application runs fine on some pc's but on others it stops finding resources as soon as it creates more than one thread. (the first resource that it loads is a little config file for the engine at wich time no threads apart from the main thread has been created so that still works)

I tried using the main thread to get the contextclassloader regardled of wich thread tries to load something but that didint work either. I unfortenetley have 2 threads that might need to load resources. my main thread that loads small config files and scripts and my resource loader thread that that loads model/sounds/textures etc.

As for the other suggestion. I realy need to be able to work from the root... Else it would just make my life miserable. so adding a blank class to some random package wont do as the path would then become relative to that package. (real pity we cant import from the root anymore!!)
Title: Re: Java web start and resources in Jars.
Post by: Matthias on June 02, 2011, 20:24:18
You could also try this:
Resources.class.getClassLoader().getResource("path/to/logo.png");
But never use a leading slash ('/') with a class loader.
Title: Re: Java web start and resources in Jars.
Post by: Endolf on June 03, 2011, 05:59:03
Quote from: Eternity on June 02, 2011, 19:52:13
OK. i placed everything in one jar file and i used Thread.currentThread().getContextClassLoader(). The result is my java web start application runs fine on some pc's but on others it stops finding resources as soon as it creates more than one thread.

That is very strange, I use threads in my application and it loads fine. What jdk, os and architecture are they running on when it fails?, there must be a common factor in where it fails and where it doesn't.

Endolf
Title: Re: Java web start and resources in Jars.
Post by: Endolf on June 03, 2011, 06:00:23
Also, if you are the one creating the new threads you could always check what the context class loader is on the new threads and compare it to the context class loader on the main thread.

Endolf
Title: Re: Java web start and resources in Jars.
Post by: broumbroum on June 03, 2011, 18:16:58
open Java configuration panel ->advanced tab, and enable all console tracing. you should see when the classloader is not finding the resources properly.
also you can try <jar download="eager" ...> which will force downloading the jar file on resource loading.
Title: Re: Java web start and resources in Jars.
Post by: Eternity on June 07, 2011, 15:44:34
It started working on the pc it didint run after wiping the cache and restarting it. seems that somehow it kept on using outdated jars.

Both the Resources.class.getClassLoader() and then Thread.currentThread().getContextClassLoader() solutions work fine.

Thnx for the help! :D