WebStart Woes (and Debuggery)

After I got a test package together and deployed it via WebStart ( http://www.greatworkgames.com/testdistro ), I decided to package up a demo of the KISS Combat Engine so that others could get their hands on it and check it out.  However… after a bit of Eclipse project reoganization to specify my asset directories so that the jar would include them, I continue to run into a problem where the asset locations are not found within the jar.  Its strange in that both projects are set up in the same way (or so I think) and yet the second one fails using the exact same class to load models.  I have verified that the jar indeed includes all resources that are requested by the program and at the locations specified in the code.



The basic project set up looks like this:



ProjectName

  *Src

       * PackageName

              * Assets (directory)

              * Classes (directly under package)

              * Some textures (directly under package)

   * Other stuff (references to other packages, etc.)



The WebStart error points to the line in my model loading code that looks basically like:



(FormatConverter) converter.convert(model.openStream(), BO);



where model is the URL of the model (which should be PackageName/Assets), but apparently is not found in the WebStart – although it runs just fine when executed from Eclipse.



I haven't given a whole lot of time to this yet, but wanted to start the thread in case someone has run across the same sort of thing before.



Also, as a nifty little piece of info, you can debug WebStart locally (to save on re-uploading a jar to your website every time you want to test) by specifying your local codebase directory in the jnlp file as:



codebase="file:///c:/subdir/codebasedir" (for Windows – and I presume this will work with the other directory formats for linux and MacOS).












how do you get the model url, with ResourceLocator ?

Core-Dump said:

how do you get the model url, with ResourceLocator ?


I don't have ~that~ code with me right now, but I believe that its pretty much set up like in HelloModelLoading where the URL looks like:

URL model=ProjectName.class.getClassLoader().getResource("/package/assets/"+ modelName + ".ms3d");

I'll copy the code to here after I get home.  The thing about it is... is that the same code works in the first case but not in the second, even though both projects are set up to access an assets directory in the same way and at the same project location.

And here's the LoadModel code – read the comments for variations I've gone through to look at this.  I tried using the ResourceLocatorTool.locateResource but that yeilds the same result: works fine from Eclipse, doesn't work from WebStart.  The WebStart error is below the code – line 58 is the "converter.convert(model.openStream(), BO);" line.



public class LoadModel {
   private static final Logger logger = Logger.getLogger(WorldTwoGS.class.getName());
   private Node loadModel;

   
   public Node LoadModel(String name){
      

      try {
               ResourceLocatorTool.addResourceLocator(
                       ResourceLocatorTool.TYPE_TEXTURE,
                       new SimpleResourceLocator(WorldTwoGS.class.getClassLoader().getResource("worldtwo/assets")));

           } catch (URISyntaxException e1) {
               logger.log(Level.WARNING, "unable to setup texture directory.", e1);
           }
 
           try {
               ResourceLocatorTool.addResourceLocator(
                       ResourceLocatorTool.TYPE_MODEL,
                       new SimpleResourceLocator(WorldTwoGS.class.getClassLoader().getResource("worldtwo/assets")));

           } catch (URISyntaxException e1) {
               logger.log(Level.WARNING, "unable to setup texture directory.", e1);
           }
          
                // the following line is the original way that I was building the URL for the converter
                //
           //URL model=WorldTwoGS.class.getClassLoader().getResource("worldtwo/assets/"+name+".ms3d");

                // changed handling to the following line before making this post, just to see...
                //
           URL model = (URL) ResourceLocatorTool.locateResource(ResourceLocatorTool.TYPE_MODEL,"worldtwo/assets/" + name+".ms3d");
          
         FormatConverter converter = new MilkToJme();
         ByteArrayOutputStream BO=new ByteArrayOutputStream();
         
         
         
         try {
            converter.convert(model.openStream(), BO);
            loadModel=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

         } catch (IOException e) {   // Just in case anything happens
            logger.logp(Level.SEVERE, this.getClass().toString(),
                    "BaseGame()", "Exception", e);
            System.out.print("Severe Error: " + e);
            System.exit(0);
         }
         return (loadModel);
   }
   
}



WebStart error:

java.lang.NullPointerException
at worldtwo.LoadModel.LoadModel(LoadModel.java:58)
at worldtwo.WTLab2.buildWTLab2(WTLab2.java:619)
at worldtwo.WTLab2.buildWTLab2Env(WTLab2.java:429)
at worldtwo.WTLab2.<init>(WTLab2.java:421)
at worldtwo.BaseGameState.<init>(BaseGameState.java:53)
at worldtwo.WorldTwoGS.main(WorldTwoGS.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Java Console Error:

(... everything before ...)
INFO: Node created.
Mar 9, 2009 6:01:49 PM com.jme.scene.Node attachChild
INFO: Child (FPS label) attached to this node (FPS node)
buildWTLab2Env...
Mar 9, 2009 6:01:49 PM com.jme.util.resource.ResourceLocatorTool locateResource
WARNING: Unable to locate: worldtwo/assets/wtLab2-floor-3.ms3d
#### Java Web Start Error:
#### null

Hi



Fully undertsand your frustrations - simply webstart is nasty … its makes a private sandbox super dooper wont harm your pc cache …



have written a deployable like this with webstart, i used the hard location route which required the user accepting to trust the app - eg put resources in a known directory. its not running anymore but see the ws for www.forthestars.com



Think that you should look to use webstart only as a deployment tool for instalation, then use getdown or something to actually install it.


Well… for what it's worth… I recreated the project, made sure it ran okay from Eclipse, and then packaged up everything into a FatJar… and that threw the same error.  So, I'm wondering if I don't have my project structure right for executing a jar?  But that doesn't seem right since it runs okay from within Eclipse… and yet… ??? ARGH!!!



EDIT/UPDATE:



Here's the most recent error (from a FatJar, but its the same as the WebStart error):



buildWTLab2Env…

Mar 9, 2009 7:42:25 PM com.jme.util.resource.ResourceLocatorTool locateResource

WARNING: Unable to locate: worldtwo/assets/wtLab2-floor-2.ms3d

Exception in thread "main" java.lang.NullPointerException

        at worldtwo.LoadModel.LoadModel(LoadModel.java:66)

        at worldtwo.WTLab2.buildWTLab2(WTLab2.java:619)

        at worldtwo.WTLab2.buildWTLab2Env(WTLab2.java:429)

        at worldtwo.WTLab2.<init>(WTLab2.java:421)

        at worldtwo.BaseGameState.<init>(BaseGameState.java:53)

        at worldtwo.WorldTwoGS.main(WorldTwoGS.java:32)



And here are the entries from the jar file itself when viewed with



jar tvf worldtwogsz.jar



  795 Mon Mar 09 19:34:48 PDT 2009 worldtwo/assets/wtlab2-floor-2.ms3d

  1206 Mon Mar 09 19:34:48 PDT 2009 worldtwo/assets/wtlab2-floor-3.ms3d



They certainly look like they exist in the jar at the right locs to me!  Does anyone see anything wrong with this???

have you tried executing the jar from the command line…

if it fails to load the models there then it is an issue with the location of the resources in the jar file…

also your paths in a jar must be given according to a root…

ie



URL      url = MyClass.class.getResource("/" + asssetLocation);

ncomp said:

have you tried executing the jar from the command line...
if it fails to load the models there then it is an issue with the location of the resources in the jar file....
also your paths in a jar must be given according to a root....
ie


URL      url = MyClass.class.getResource("/" + asssetLocation);




If I use a slash in front of my path I get a null exception (from straight URL) and "baseDir cannot be null" from ResourceLocator.  I have also tried dot-slash and the asset directory "as is" and both generate errors.  I have no doubt that there is something amiss with my project setup; but its odd in that what works from Eclipse fails from the jar... and that I have that other project set up in the same way and it works both from Eclipse and the jar.  See a post I made above for what my project set up looks like.  Maybe I need to move my asset directory out of the package and place it directly under src, or create a separate package for it.

I dunno (and my time is short after tonight as I have to endeavor "court head" to deal with a custody/visitation matter about one of my kids and will be out of the loop until mid next week).  That aside, any further suggestions, or maybe project template set ups (showing proper placement of code and asset directories/locations), would be appreciated.

you need a slash / at the end of the path:



Thats how iuse resource locator in stardust,and that works in eclipse and webstart:


ResourceLocatorTool.addResourceLocator(
        ResourceLocatorTool.TYPE_AUDIO,
           new SimpleResourceLocator(Start.class.getClassLoader().getResource(
                        "com/jmedemos/stardust/data/sounds/")));

Core-Dump said:

you need a slash / at the end of the path:

Thats how iuse resource locator in stardust,and that works in eclipse and webstart:


ResourceLocatorTool.addResourceLocator(
        ResourceLocatorTool.TYPE_AUDIO,
           new SimpleResourceLocator(Start.class.getClassLoader().getResource(
                        "com/jmedemos/stardust/data/sounds/")));




By Jove, it works (for both WebStart and FatJar)!  Thanks, core-dump and ncomp!

Of course, it also seems that running it through Eclipse (on Windows) was not respecting case-sensitivity in model names but the jar execution was -- which was an additional problem, but easily fixed.

Now... prepare to feel the fury of four little witches!!!  Haha... stay tuned....

EDIT:

The fury is here: http://www.jmonkeyengine.com/jmeforum/index.php?topic=9575.msg80671#msg80671 ; - )

I am having the same issue and simply putting a / on the end of the path didn't work for me. Could you post your code for this so I can check I'm doing stuff right?



Cheers




swuth said:

I am having the same issue and simply putting a / on the end of the path didn't work for me. Could you post your code for this so I can check I'm doing stuff right?

Cheers


Here's the code.  I note that the texture directory has to be set up different than the model directory...


      try {
               ResourceLocatorTool.addResourceLocator(
                       ResourceLocatorTool.TYPE_TEXTURE,
                       new SimpleResourceLocator(WorldXXX.class.getClassLoader().getResource("worldxxx/assets")));
           } catch (URISyntaxException e1) {              
              System.out.println("WARNING: unable to setup texture directory." + e1);              
               logger.log(Level.WARNING, "unable to setup texture directory.", e1);
           }
 
           try {
               ResourceLocatorTool.addResourceLocator(
                       ResourceLocatorTool.TYPE_MODEL,
                       new SimpleResourceLocator(WorldXXX.class.getClassLoader().getResource("worldxxx/assets/")));

           } catch (URISyntaxException e1) {              
              System.out.println("WARNING: unable to setup model directory." + e1);              
               logger.log(Level.WARNING, "unable to setup model directory.", e1);
           }
          
           URL model = (URL) ResourceLocatorTool.locateResource(ResourceLocatorTool.TYPE_MODEL,"worldxxx/assets/" + name+".ms3d");
          
      FormatConverter converter = new MilkToJme();
      ByteArrayOutputStream BO=new ByteArrayOutputStream();

      try {
         converter.convert(model.openStream(), BO);
         loadModel=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

      } catch (IOException e) {   // Just in case anything happens
         logger.logp(Level.SEVERE, this.getClass().toString(),
                 "BaseGame()", "Exception", e);
         System.out.print("Severe Error: " + e);
         System.exit(0);
      }

Also, and I think I mentioned this somewhere on the forum before, but you can test your webstart apps locally before uploading to your internet webspace so as to save all the upload time when trying to get everything to work.  To do this, just point the jnlp codebase to something like the following:




<jnlp spec="1.0+"
      codebase="file:///c:/somedir/anotherdir/targetdir"
      href="webstartapp.jnlp">

(... the rest of the jnlp ...)



I hope all of this helps.
ashtonv said:

swuth said:

I am having the same issue and simply putting a / on the end of the path didn't work for me. Could you post your code for this so I can check I'm doing stuff right?

Cheers


Here's the code.  I note that the texture directory has to be set up different than the model directory...


      try {
               ResourceLocatorTool.addResourceLocator(
                       ResourceLocatorTool.TYPE_TEXTURE,
                       new SimpleResourceLocator(WorldXXX.class.getClassLoader().getResource("worldxxx/assets")));
           } catch (URISyntaxException e1) {              
              System.out.println("WARNING: unable to setup texture directory." + e1);              
               logger.log(Level.WARNING, "unable to setup texture directory.", e1);
           }
 
           try {
               ResourceLocatorTool.addResourceLocator(
                       ResourceLocatorTool.TYPE_MODEL,
                       new SimpleResourceLocator(WorldXXX.class.getClassLoader().getResource("worldxxx/assets/")));

           } catch (URISyntaxException e1) {              
              System.out.println("WARNING: unable to setup model directory." + e1);              
               logger.log(Level.WARNING, "unable to setup model directory.", e1);
           }
          
           URL model = (URL) ResourceLocatorTool.locateResource(ResourceLocatorTool.TYPE_MODEL,"worldxxx/assets/" + name+".ms3d");
          
      FormatConverter converter = new MilkToJme();
      ByteArrayOutputStream BO=new ByteArrayOutputStream();

      try {
         converter.convert(model.openStream(), BO);
         loadModel=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

      } catch (IOException e) {   // Just in case anything happens
         logger.logp(Level.SEVERE, this.getClass().toString(),
                 "BaseGame()", "Exception", e);
         System.out.print("Severe Error: " + e);
         System.exit(0);
      }





Thanks, could you post your project  dir "tree" so that I can see if I am doing something wrong there?

Cheers

CH

BTW I am testing this locally  using the "offline" radio button in the Webstart for eclipse plugin.


swuth said:

BTW I am testing this locally  using the "offline" radio button in the Webstart for eclipse plugin.


I have not worked with the Webstart plugin for eclipse, so I don't know what other issues that might introduce for you.  During my tests, I execute Webstart from the command line.  I would suggest that you go back to the wiki tutorial on Webstart and try to follow that as much as possible.

My directory structure is basically:

ProjectName
  *Src
      * PackageName
              * Assets (directory)
              * Classes (directly under package)
  * Other stuff (references to other packages, etc.)

And note that the Assets directory (where all models and textures are kept) is registered in eclipse as a folder and a part of the project -- if this is not done, then the contents of directory will not be added to your final jar that Webstart uses, which will throw errors because none of the directory contents are accessable at runtime.

OK, still pulling my hair out with this!!! 



1> When I unpack the jar of my project I can clearly see the dirs  I am referring to in my resource code are there.



2> If I comment out the resource allocator code and just let it fail on the textures, the whole app runs I just don't have any textures.





3> Is there ANY newbie gotchas that I am missing here





My Project tree is



CubeMobile

      SRC






OK, still pulling my hair out with this!!! 



1> When I unpack the jar of my project I can clearly see the dirs  I am referring to in my resource code are there.



2> If I comment out the resource allocator code and just let it fail on the textures, the whole app runs I just don't have any textures.





3> Is there ANY newbie gotchas that I am missing here





My Project tree is



CubeMobile

      src

        cube

        assets

       

My code for the resource loader (which works in eclipse…)





try {

            ResourceLocatorTool.addResourceLocator(

                    ResourceLocatorTool.TYPE_TEXTURE,

                    new SimpleResourceLocator(CubeMobile.class.getClassLoader().getResource("cube/assets/")));

        } catch (URISyntaxException e1) {        

        System.out.println("WARNING: unable to setup texture directory." + e1);        

        //  logger.log(Level.WARNING, "unable to setup texture directory.", e1);

        }



My process is



export

Make Runnable Jar



export

Make Webstart JNLP version using Webstart for eclipse.

(I have all the natives, jars etc setup)



Run the jnlp



Everytime I get the "basedir cannot be null"… I know the dir is there because the models will load from it…



AAAAAGGGGGHHHH  :slight_smile:






Did you try replacing

new SimpleResourceLocator(CubeMobile.class.getClassLoader().getResource("cube/assets/")));



with


new SimpleResourceLocator(CubeMobile.class.getResource("cube/assets/")));

I had it that way originally but figured it was wrong as everyone else was doing it the other way. I traced thru the code and found that the resource locator was using /bin in its dir. When I export my Runnable Jar from eclipse there is no bin dir in the jar. I am guessing this is the problem. Anyone know how to add the bin dir to the runnable Jar?



Cheers