Search code examples
javaswtclassloader

ClassLoader on virtual machine


I have source code:

private Image getImage(String path, ClassLoader loader) {
    InputStream image = null;
    try {
        image = loader.getResourceAsStream(path);
        return new Image(PlatformUI.getWorkbench().getDisplay(), image);
    } finally {
        if (image != null) {
            try {
                image.close();
            } 
            catch (IOException e) {
                //OK
            }
        }
    }
}

On my computer this code works perfect. But, on virtual machine line:

loader.getResourceAsStream(path);

always returns null. Why?

EDIT:

Path is a relative path. For example: icons/tools/device.png. Application which I develop contains more than ten projects. I use Eclipse IDE. All projects have structure:

  • com.pkg.name - folder with classes icons
  • folder with icons and others files

Jar files have this structure too.

On my computer applications works perfect. On virtual machine (Windows Server(64-bit)) application can't loads images from Jar file.


Solution

  • If path is a relative path, then it should work, as long as the image resource has been copied along with the class files (as Itay already mentioned) and the folder or jar that contains the image resource is on the classpath (do you use CLASSPATH or -cp to specify the classpath? If you rely on CLASSPATH, make sure, the this environment variable is properly set for the user that executes the application)

    If it is an absolute path, double check if it is valid on the target VM.

    so basically, for a folder structure like

    ./classes
    ./images
    ./libs
    

    the command java -cp classes;images;libs/* my.app.Application should work (java 1.6 - in older versions the wildcard is not allowed), assuming a path value like images/myImage.jpg.

    Just another thought, the classpath delimter is ; on Windows and : on unix. That might be a problem if you prepared the app on a unix-type environment.

    Edit

    Do you read the image from the same library as you actual classfile? Then please give this a try:

    this.getClass().getResourceAsStream(path)
    

    Edit

    OK, it's OSGi. So there are some more reasons why the application works from inside the eclipse IDE but not when deployed as a RCP application. I think it has nothing to do with the target environment.

    In OSGi every bundle has it's own classloader and a class from bundle1 will not be able to see classes from bundle2 unless the packages are properly exported. This is true for resources as well. I guess that the image is stored in a different bundle. I don't know which classloader is passed to the getImage method, but that classloader definitely can't see the resource file.

    It might work inside eclipse, especially if you add the projects to each others build paths.

    After you've built the product, you said it fails (partially) on the VM but does the same product show the image on the local machine (outside eclipse)?