users@glassfish.java.net

classloading issue?

From: Jakub Podlesak <Jakub.Podlesak_at_Sun.COM>
Date: Wed, 02 Sep 2009 14:55:51 +0200

Hi all,

Paul Sandoz has hit a strange issue with classloading in GlassFish V3,
and i am curious, if it is a bug.

Attached is a small maven based project, which builds a war including
[WEB-INF/lib/jsr311-api-1.1-ea.jar]
The web application then has a servlet, which tries to print out,
which classloader was used to load [javax.ws.rs.core.Application],
a class which is included in the above mentioned jar.

The same class is then included also in the
[glassfish/modules/jsr311-api.jar]
archive, which is part of GlassFishV3 (latest nightly).

Now, even if the class-loader delegate option
<class-loader delegate="false"/>
is set to false, the servlet shows, the [javax.ws.rs.core.Application]
has been loaded from the
[glassfish/modules/jsr311-api.jar] instead from the jar included
in the war file:

[#|2009-09-02T14:06:20.499+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;|FIND: javax.ws.rs.core.Application javax/ws/rs/core/Application.class|#]

[#|2009-09-02T14:06:20.499+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| Class loader of class|#]

[#|2009-09-02T14:06:20.500+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| bundle://113.0:1/javax/ws/rs/core/Application.class|#]

[#|2009-09-02T14:06:20.500+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| Context class loader|#]

[#|2009-09-02T14:06:20.502+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| jar:file:/export/home/japod/test/glassfishv3/glassfish/domains/domain1/applications/classloading311/WEB-INF/lib/jsr311-api-1.1-ea.jar!/javax/ws/rs/core/Application.class|#]

[#|2009-09-02T14:06:20.502+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| bundle://113.0:1/javax/ws/rs/core/Application.class|#]

[#|2009-09-02T14:06:20.506+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;|FIND: javax.ws.rs.ApplicationPath javax/ws/rs/ApplicationPath.class|#]

[#|2009-09-02T14:06:20.506+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| Class loader of class|#]

[#|2009-09-02T14:06:20.507+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| jar:file:/export/home/japod/test/glassfishv3/glassfish/domains/domain1/applications/classloading311/WEB-INF/lib/jsr311-api-1.1-ea.jar!/javax/ws/rs/ApplicationPath.class|#]

[#|2009-09-02T14:06:20.507+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| Context class loader|#]

[#|2009-09-02T14:06:20.508+0200|INFO|glassfish|null|_ThreadID=35;_ThreadName=Thread-2;| jar:file:/export/home/japod/test/glassfishv3/glassfish/domains/domain1/applications/classloading311/WEB-INF/lib/jsr311-api-1.1-ea.jar!/javax/ws/rs/ApplicationPath.class|#]


The corresponding find method is as follows:

    private void find(Class c) {
        try {
            String path = c.getName().replace(".", "/") + ".class";
            System.out.println("FIND: " + c.getName() + " " + path);

            System.out.println(" Class loader of class");
            Enumeration<URL> e = c.getClassLoader().getResources(path);
            while (e.hasMoreElements()) {
                System.out.println(" " + e.nextElement().toExternalForm());
            }

            System.out.println(" Context class loader");
            e = Thread.currentThread().getContextClassLoader().getResources(path);
            while (e.hasMoreElements()) {
                System.out.println(" " + e.nextElement().toExternalForm());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


To reproduce this, just build the war file, deploy it, and hit: http://localhost:8080/classloading311/NewServlet
you should then see the statements in the [glassfish/domanins/domain/logs/server.log] file.

Could anybody explain what is wrong?

Thanks,

~Jakub