You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Lakmali Baminiwatta <la...@gmail.com> on 2013/05/02 13:44:29 UTC

Clarification of Juli - ClassLoaderLogManager

Hi all,

I am using Tomcat Juli.

In org.apache.juli.ClassLoaderLogManager class, when reading the
configuration from the specified classLoaders through below method,

*readConfiguration(ClassLoader classLoader)*
*
*
*It checks whether the current classLoader and System Class Loader is same
before reading the global logging configuration file. *
*
*
 if ((is == null) && *(classLoader == ClassLoader.getSystemClassLoader()*))
{
            String configFileStr =
System.getProperty("java.util.logging.config.file");
            if (configFileStr != null) {
                try {
                    is = new FileInputStream(replace(configFileStr));
                } catch (IOException e) {
                    // Ignore
                }
            }
            // Try the default JVM configuration
            if (is == null) {
                File defaultFile = new File(new
File(System.getProperty("java.home"), "lib"),
                    "logging.properties");
                try {
                    is = new FileInputStream(defaultFile);
                } catch (IOException e) {
                    // Critical problem, do something ...
                }
            }
        }

I am really greatful if the reason why such a check [*classLoader ==
ClassLoader.getSystemClassLoader()*] is required, can be clarified?

I am asking this because, I have a scenario which this condition fails due
to unequality of the classLoaders. But removing that check fixed the issue
and logging happens as expected.

Appreciate if you can point me out the possibility of an issue with my
change or why that check is there.

Thanks,
Lakmali

Re: Clarification of Juli - ClassLoaderLogManager

Posted by Lakmali Baminiwatta <la...@gmail.com>.
Hi Kolinko,


On Thu, May 2, 2013 at 6:26 PM, Konstantin Kolinko
<kn...@gmail.com>wrote:

> 2013/5/2 Lakmali Baminiwatta <la...@gmail.com>:
> > Hi all,
> >
> > I am using Tomcat Juli.
> >
> > In org.apache.juli.ClassLoaderLogManager class, when reading the
> > configuration from the specified classLoaders through below method,
> >
> > *readConfiguration(ClassLoader classLoader)*
> > *
> > *
> > *It checks whether the current classLoader and System Class Loader is
> same
> > before reading the global logging configuration file. *
> > *
> > *
> >  if ((is == null) && *(classLoader ==
> ClassLoader.getSystemClassLoader()*))
> > {
> >             String configFileStr =
> > System.getProperty("java.util.logging.config.file");
> >             if (configFileStr != null) {
> >                 try {
> >                     is = new FileInputStream(replace(configFileStr));
> >                 } catch (IOException e) {
> >                     // Ignore
> >                 }
> >             }
> >             // Try the default JVM configuration
> >             if (is == null) {
> >                 File defaultFile = new File(new
> > File(System.getProperty("java.home"), "lib"),
> >                     "logging.properties");
> >                 try {
> >                     is = new FileInputStream(defaultFile);
> >                 } catch (IOException e) {
> >                     // Critical problem, do something ...
> >                 }
> >             }
> >         }
> >
> > I am really greatful if the reason why such a check [*classLoader ==
> > ClassLoader.getSystemClassLoader()*] is required, can be clarified?
> >
> > I am asking this because, I have a scenario which this condition fails
> due
> > to unequality of the classLoaders. But removing that check fixed the
> issue
> > and logging happens as expected.
> >
> > Appreciate if you can point me out the possibility of an issue with my
> > change or why that check is there.
> >
>
> Thanks for your explanation.

>
> The code there tries
> a) per-webapp configuration (aka per-classloader configuration)
> which is given by classLoader.getResourceAsStream("logging.properties")
>
> b) global configuration, which is specified by
> System.getProperty("java.util.logging.config.file") setting.
> That is the fragment that you cited.
>
> c) asks parent classloader
>
> Note that c) also happens in different places like in getProperty(String).
>
> The condition in b) that you are asking about is needed for c) to
> work. That is, the global configuration is read only by the top
> classloader in the chain. If you change that, there will be several
> copies of configuration,  such as several Loggers writing to the same
> file in parallel.
>

ok, understood the requirement of that condition.

>
> It seems that there is assumption that the root of classloaders chain
> is the system classloader. Is that not true for you?
>

Yes, system classloader and webapp classloaders are in seperate hierachies.


>
> I should also note that "getClassLoaderInfo(current)" during c)
> results in readConfiguration( ) call for that parent classloader,  and
> "getClassLoaderInfo(null)" would read the one for the system
> classloader.  So maybe one has to add such call to the loop in c)
> instead of fixing the condition in b), but I cannot say without
> looking how this configuration is used in other methods.
>

So what you suggest is to pass null to the , getClassLoaderInfo instead of
current as below? It also gave the expected logging.

            if (is == null) {
            // Retrieve the root logger of the parent classloader instead
            ClassLoader current = classLoader.getParent();
            ClassLoaderLogInfo info = null;
            while (current != null && info == null) {
                info = getClassLoaderInfo(null);
                current = current.getParent();
            }
            if (info != null) {
                localRootLogger.setParent(info.rootNode.logger);
            }
        }

Thanks,
Lakmali

>
> Best regards,
> Konstantin Kolinko
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>

Re: Clarification of Juli - ClassLoaderLogManager

Posted by Konstantin Kolinko <kn...@gmail.com>.
2013/5/2 Lakmali Baminiwatta <la...@gmail.com>:
> Hi all,
>
> I am using Tomcat Juli.
>
> In org.apache.juli.ClassLoaderLogManager class, when reading the
> configuration from the specified classLoaders through below method,
>
> *readConfiguration(ClassLoader classLoader)*
> *
> *
> *It checks whether the current classLoader and System Class Loader is same
> before reading the global logging configuration file. *
> *
> *
>  if ((is == null) && *(classLoader == ClassLoader.getSystemClassLoader()*))
> {
>             String configFileStr =
> System.getProperty("java.util.logging.config.file");
>             if (configFileStr != null) {
>                 try {
>                     is = new FileInputStream(replace(configFileStr));
>                 } catch (IOException e) {
>                     // Ignore
>                 }
>             }
>             // Try the default JVM configuration
>             if (is == null) {
>                 File defaultFile = new File(new
> File(System.getProperty("java.home"), "lib"),
>                     "logging.properties");
>                 try {
>                     is = new FileInputStream(defaultFile);
>                 } catch (IOException e) {
>                     // Critical problem, do something ...
>                 }
>             }
>         }
>
> I am really greatful if the reason why such a check [*classLoader ==
> ClassLoader.getSystemClassLoader()*] is required, can be clarified?
>
> I am asking this because, I have a scenario which this condition fails due
> to unequality of the classLoaders. But removing that check fixed the issue
> and logging happens as expected.
>
> Appreciate if you can point me out the possibility of an issue with my
> change or why that check is there.
>


The code there tries
a) per-webapp configuration (aka per-classloader configuration)
which is given by classLoader.getResourceAsStream("logging.properties")

b) global configuration, which is specified by
System.getProperty("java.util.logging.config.file") setting.
That is the fragment that you cited.

c) asks parent classloader

Note that c) also happens in different places like in getProperty(String).

The condition in b) that you are asking about is needed for c) to
work. That is, the global configuration is read only by the top
classloader in the chain. If you change that, there will be several
copies of configuration,  such as several Loggers writing to the same
file in parallel.

It seems that there is assumption that the root of classloaders chain
is the system classloader. Is that not true for you?

I should also note that "getClassLoaderInfo(current)" during c)
results in readConfiguration( ) call for that parent classloader,  and
"getClassLoaderInfo(null)" would read the one for the system
classloader.  So maybe one has to add such call to the loop in c)
instead of fixing the condition in b), but I cannot say without
looking how this configuration is used in other methods.

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org