geronimo-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Shan Karthic" <shan.kart...@gmail.com>
Subject Re: Classloader Hierarchy and hidden-classes
Date Thu, 14 Sep 2006 22:43:04 GMT
>>  David Jencks wrote:
>>
>>  I'm getting confused by your description, and looking at the code in
>>  trunk what I think you're saying doesn't look too likely... so I'm
>>  pretty sure I'm confused about something here and misunderstanding

>>  what you are saying.

I regret that I was not clear about the problem.

>>  Could you outline what you are seeing in terms of a class
org.foo.X
>>  that is present in 3 classloaders:

>>  cl1
>>  parent of
>>  cl2
>>  parent of
>>  cl3

>>  where cl2 or cl3 has org.foo in hidden classes and either cl2 or cl3

>>  or maybe both have inverse classloading turned on?

>>  Seems like maybe we need some test cases to make sure what we think
>>  is happening, is actually happening.

The hidden-classes fragement is
        <sys:hidden-classes>
          <sys:filter>org.apache.commons.logging</sys:filter>
          <sys:filter>org.apache.log4j</sys:filter>
          <sys:filter>org.apache.geronimo.kernel.log</sys:filter>
        </sys:hidden-classes>

1) If I have org.foo hidden from cl2 (EAR/app level classloader) and not
from cl3 (WAR classloader) and no inverse-classloading, the org.foo classes
loaded by cl1 or above are visible to the application.

Following is what I get, if I have the above hidden-classes specified in
geronimo-application.xml and not in geronimo-web.xml.  AppLogManager is a
singleton in an utility jar in the application and is accessed from other
utilities, EJBs and WAR in the application.  In this case, I am
instantiating it from the controller servlet and accessing it.

The code segment that prints the messages shown below is
        Class l_clsClass = ...; //
        ClassLoader l_clrLoader = l_clsClass.getClassLoader();
        int i = 0;

        System.out.println("###" + l_clsClass.getName() + "###");
        while (l_clrLoader != null) {
            System.out.println("\t\t\tClass loader @ " + i + " is " +
l_clrLoader);
            if (l_clrLoader.getParent() != null &&
l_clrLoader.equals(l_clrLoader.getParent())) {
                break;
            }
            l_clrLoader = l_clrLoader.getParent();
            ++i;
        }

I am printing this trace from a method inside AppLogManager.  Class is first
set to getClass(), and then m_lfyFactory.getClass() (where m_lfyFactory is
declared to be of type commons-logging LogFactory and is initialized with
LogFactory.getFactory(), and then m_lfyFactory.getInstance(...) which
returns an object of type commons-logging Log.

    ###com.foo.bar.logging.AppLogManager###
                            Class loader @ 0 is [
org.apache.geronimo.kernel.classloader.JarFileClassLoaderid=default/App/1158265787982/car]
                            Class loader @ 1 is
sun.misc.Launcher$AppClassLoader@e80a59
                            Class loader @ 2 is
sun.misc.Launcher$ExtClassLoader@9f2a0b
    ###org.apache.geronimo.kernel.log.GeronimoLogFactory###
                            Class loader @ 0 is
sun.misc.Launcher$AppClassLoader@e80a59
                            Class loader @ 1 is
sun.misc.Launcher$ExtClassLoader@9f2a0b
    ###org.apache.geronimo.kernel.log.GeronimoLog###
                            Class loader @ 0 is
sun.misc.Launcher$AppClassLoader@e80a59
                            Class loader @ 1 is
sun.misc.Launcher$ExtClassLoader@9f2a0b

As you can see, the application sees classes from
org.apache.geronimo.kernel.log loaded by the server.

2) When I had org.foo hidden from both cl2 (EAR/app level classloader) and
cl3 (WAR classloader) and no inverse-classloading, there used to be a mixup
between classes loaded by cl2 and cl3.  I am no longer able to reproduce
it.  I have to retrace all my tries over the last couple of days to see what
I had done to get that.  Most probably I messed up the classpath while
trying various combinations.

Currently the behaviour is similar to 1.  Earlier, I used to have messages
that said log4j.Appender was loaded by EAR/app classloader while
log4j.DailyRollingFileAppender was loaded by WAR classloader.

3) If I have org.foo hidden from both cl2 (EAR/app level classloader) and
cl3 (WAR classloader) and inverse class loading at WAR level, then all the
classes are loaded at WAR level and logging works the way I want it.

###com.foo.bar.logging.AppLogManager###
                        Class loader @ 0 is [
org.apache.geronimo.kernel.classloader.JarFileClassLoaderid=default/App_AppWeb.war/1158272840771/car]
                        Class loader @ 1 is
sun.misc.Launcher$AppClassLoader@e80a59
                        Class loader @ 2 is
sun.misc.Launcher$ExtClassLoader@9f2a0b
###org.apache.commons.logging.impl.LogFactoryImpl###
                        Class loader @ 0 is [
org.apache.geronimo.kernel.classloader.JarFileClassLoaderid=default/App_AppWeb.war/1158272840771/car]
                        Class loader @ 1 is
sun.misc.Launcher$AppClassLoader@e80a59
                        Class loader @ 2 is
sun.misc.Launcher$ExtClassLoader@9f2a0b
###org.apache.commons.logging.impl.Log4JLogger###
                        Class loader @ 0 is [
org.apache.geronimo.kernel.classloader.JarFileClassLoaderid=default/App_AppWeb.war/1158272840771/car]
                        Class loader @ 1 is
sun.misc.Launcher$AppClassLoader@e80a59
                        Class loader @ 2 is
sun.misc.Launcher$ExtClassLoader@9f2a0b

But other utilities at EAR level/EJBs will not see these and will load their
own and the class in the utility is no longer a singleton at application
level.  I am also forced to keep multiple copies of property files at EAR
and WAR levels or keep them inside the JAR (which makes it necessary to
rebuild the JAR if I want to change some config or property).

Is there a way around this?

Thanks,
Shankar.

Mime
View raw message