A Java Deployment question

This is really bugging me. Have searched over the last day on the net, looked up class loading and and bits…



trying to deploy an application in jars



there are 2 jars

  1. game.jar which contains java classes
  2. art.jar which contains one class called Art.class and lots of images



    Classes in game.jar get images from art.jar by Art.class.getClassLoader().getResource(), this works fine in eclipse



    the problem is, and they are just jars on the classpath, it throws up null pointers trying to get the images.



    Does anyone know if i can distribute aretwork in thi way or should the resources of type image always be included in the jar file of the class requiring it - what does eclipse do ??



    Variations tried include

    Art.class.getResource()

    Game.class.getResource() "this is using a the calling class"








Art.class.getResource() should work fine, even Art.class.getClassLoader().getResource() should be fine. While both jars are in the vm-classpath, thus the classes and images are loaded via the system class loader, even Game.class.getClassLoader().getResource() and Game.class.getResource() should work.



Maybe you have not set up your classpath correctly for starting it externally? How do you start it?

Thanks Irrisor,



i had totally mashed my patience on this one and your post gave me encouragemnt not to give up programming and go work down the local Macdonalds



In eclipse its not fussy wether your URL's have // or / as path separators in a string, as my the code before worked within eclipse. the outside world is a little more senitive though



Strangely also Art.class.getClassLoader().getResource isnt working but Art.class.getResource is ???, im wondering wether its somethng to do with security policies on obtaining the class loader



Thanks again

maybe you could post a little of the code you are using to try to load the image?


Package 1 art.jar
-images.yellowdot.png
-loader.Art.class

Package 2 game.jar
-com.Game.class

Art has no code - just a marker class

Game is as fiollows  :-


package com;
import javax.swing.ImageIcon;
import loader.Art;
public class Game {
   public Game() {
      try {
         System.out.println("1 As Art.class.getResource");
         ImageIcon i = new ImageIcon(Art.class.getResource("images/yellowdot.png"));   
         System.out.println("1 success " + i);
      } catch (Exception e) {
         System.out.println("1 Art.class.getResource throw " + e);
      }
      
      try {
         System.out.println("2 As Art.class.getClassLoader().getResource");
         ImageIcon i = new ImageIcon(Art.class.getClassLoader().getResource("images/yellowdot.png"));
         System.out.println("2 success " + i);
      } catch (Exception e) {
         System.out.println("2 Art.class.getClassLoader().getResource " + e);
      }

      try {
         System.out.println("3 root slash As Art.class.getResource");
         ImageIcon i = new ImageIcon(Art.class.getResource("/images/yellowdot.png"));
         System.out.println("3 success " + i);
      } catch (Exception e) {
         System.out.println("3 root slash Art.class.getResource throw " + e);
      }
      
      try {
         System.out.println("4 root slash As Art.class.getClassLoader().getResource");
         ImageIcon i = new ImageIcon(Art.class.getClassLoader().getResource("/images/yellowdot.png"));
         System.out.println("4 success " + i);
      } catch (Exception e) {
         System.out.println("4 root slash Art.class.getClassLoader().getResource " + e);
      }      
   }   
   
   public static void main (String [] args) {
      new Game();
   }
}



run above on command line using windows xp - java 1.5
java -classpath jargame.jar;jarart.jar com.Game


out put is


C:webstart>java -classpath jargame.jar;jarart.jar com.Game
1 As Art.class.getResource
1 Art.class.getResource throw java.lang.NullPointerException
2 As Art.class.getClassLoader().getResource
2 success jar:file:/C:/webstart/jar/Art.jar!/images/yellowdot.png
3 root slash As Art.class.getResource
3 success jar:file:/C:/webstart/jar/Art.jar!/images/yellowdot.png
4 root slash As Art.class.getClassLoader().getResource
4 root slash Art.class.getClassLoader().getResource java.lang.NullPointerException




So, it seems that its ok to use
a) Art.class.getClassLoader().getResource() if the url has no leading slash ("images/yellowdot.png")
b) Art.class.getResource() if there is a leading slash ("/images/yellowdot.png")


I oddly get the same results in eclipse, however i was experiencing a difference before hand

Out of A and B, can anyone think of a reason to / not to use either...


Incidently, possibly an issue - please confirm, on running any jmetests from a command line using the following library and classpaths

java -Djava.library.path=c:webstartjarlib -classpath c:webstartjarjme.jar;c:webstartjarlibopenal-windows.jar;c:webstartjarliblwjgl-windows.jar;c:webstartjarliblwjgl_util_applet.jar;c:webstartjarliblwjgl_util.jar;c:webstartjarliblwjgl_fmod3.jar;c:webstartjarliblwjgl_devil.jar;c:webstartjarliblwjgl_applet.jar;c:webstartjarliblwjgl.jar;c:webstartjarlibjorbis-0.0.12.jar;c:webstartjarlibjogg-0.0.5.jar;c:webstartjarlibjinput.jar; jmetest.shape.TestGeoSphere



I get the dreaded Could not load image...  URL was null.
this is the initialisation texture loaded in textureState


 public TextureState() {
        correction = CM_PERSPECTIVE;

        if (defaultTexture == null)
            try {
               URL url = TextureState.class.getClassLoader().getResource("notloaded.png");
                defaultTexture = TextureManager.loadTexture(url, Texture.MM_LINEAR,
                        Texture.FM_LINEAR, 1.0f, true);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }





A ClassLoader resides at the root of it's context. A Class however, has it's own place in the tree. That explains the differences between the relative paths you use.



In the case of the error with TextureState, look if the png is actually in the jar, or if it got filtered out (maybe a build file bug?).