Also, for some context: all classes in log4-core.jar share the same ClassLoader in OSGi, so using one from class A can be used to load class B. LoaderUtil tends to rely on getting whatever ClassLoader is in the current Thread's context ClassLoader which by default is whatever ClassLoader was used to create the Thread. In OSGi, the current thread can easily be one created by a class outside log4j-core. The same rule applies to log4j-api and any other log4j modules doing dynamic class loading.
I think some uses of LoaderUtil should be looked at again as this issue is probably present in a couple other places as well. I'll see what I can find. On 6 December 2016 at 22:52, Matt Sicker <boa...@gmail.com> wrote: > In an OSGi environment, the best ClassLoader to use for something in > log4j-core is one obtained from a class in log4j-core. Come to think of it, > it'd be better to do something like this: > > LoggerContext.class.getClassLoader().loadClass(...); > > On 6 December 2016 at 22:39, Gary Gregory <garydgreg...@gmail.com> wrote: > >> I think one of the points here is that a class is loaded from a specific >> class loader. This is not clear from the code or comments. I am not sure >> this 100% correct either but if that fixes at least the null class loader >> NPE then that is a good thing. Especially if the fix is less hacky than >> inially proposed. I am open to better comments and code ;-) >> >> Gary >> >> >> On Dec 6, 2016 8:24 PM, "Matt Sicker" <boa...@gmail.com> wrote: >> >> I'm not sure if that LoaderUtil line will work properly everywhere. You >> already implicitly load the class by referencing the class's .class >> property I think. Either way, a more amusing and surefire way to make it >> load would be: >> >> ExecutorServices.class.getClassLoader().loadClass(ExecutorSe >> rvices.class.getName()); >> >> Or use one of the LoaderUtil/Loader methods that takes a ClassLoader >> argument to avoid an NPE if log4j is loaded as a bootstrap class somehow. >> >> ---------- Forwarded message ---------- >> From: <ggreg...@apache.org> >> Date: 6 December 2016 at 18:07 >> Subject: logging-log4j2 git commit: [LOG4J2-1642] >> To: comm...@logging.apache.org >> >> >> Repository: logging-log4j2 >> Updated Branches: >> refs/heads/master 2eb02c827 -> bdac7f223 >> >> >> [LOG4J2-1642] >> >> DefaultShutdownCallbackRegistry can throw a NoClassDefFoundError. >> >> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo >> Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit >> /bdac7f22 >> Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/bdac7f22 >> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/bdac7f22 >> >> Branch: refs/heads/master >> Commit: bdac7f223b41dfbbf204ca924d08e6ed86c76769 >> Parents: 2eb02c8 >> Author: Johno Crawford <jo...@sulake.com> >> Authored: Tue Dec 6 16:07:52 2016 -0800 >> Committer: Gary Gregory <garydgreg...@gmail.com> >> Committed: Tue Dec 6 16:07:52 2016 -0800 >> >> ---------------------------------------------------------------------- >> .../apache/logging/log4j/core/LoggerContext.java | 16 >> +++++++++++++--- >> .../core/util/DefaultShutdownCallbackRegistry.java | 9 +++++++-- >> src/changes/changes.xml | 3 +++ >> 3 files changed, 23 insertions(+), 5 deletions(-) >> ---------------------------------------------------------------------- >> >> >> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b >> dac7f22/log4j-core/src/main/java/org/apache/logging/log4j/co >> re/LoggerContext.java >> ---------------------------------------------------------------------- >> diff --git >> a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java >> b/log4j-core/src/main/java/org/apache/logging/log4j/core/Log >> gerContext.java >> index 6902ade..4c4845e 100644 >> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/Log >> gerContext.java >> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/Log >> gerContext.java >> @@ -16,6 +16,8 @@ >> */ >> package org.apache.logging.log4j.core; >> >> +import static org.apache.logging.log4j.core. >> util.ShutdownCallbackRegistry.SHUTDOWN_HOOK_MARKER; >> + >> import java.beans.PropertyChangeEvent; >> import java.beans.PropertyChangeListener; >> import java.io.File; >> @@ -52,10 +54,9 @@ import org.apache.logging.log4j.spi.AbstractLogger; >> import org.apache.logging.log4j.spi.LoggerContextFactory; >> import org.apache.logging.log4j.spi.LoggerRegistry; >> import org.apache.logging.log4j.spi.Terminable; >> +import org.apache.logging.log4j.util.LoaderUtil; >> import org.apache.logging.log4j.util.PropertiesUtil; >> >> -import static org.apache.logging.log4j.core. >> util.ShutdownCallbackRegistry.SHUTDOWN_HOOK_MARKER; >> - >> /** >> * The LoggerContext is the anchor for the logging system. It maintains >> a list of all the loggers requested by >> * applications and a reference to the Configuration. The Configuration >> will contain the configured loggers, appenders, >> @@ -63,7 +64,16 @@ import static org.apache.logging.log4j.core. >> util.ShutdownCallbackRegistry.SHUTDO >> */ >> public class LoggerContext extends AbstractLifeCycle >> implements org.apache.logging.log4j.spi.LoggerContext, >> AutoCloseable, Terminable, ConfigurationListener { >> - >> + >> + static { >> + try { >> + // LOG4J2-1642 preload ExecutorServices as it is used in >> shutdown hook >> + LoaderUtil.loadClass(ExecutorServices.class.getName()); >> + } catch (final Exception e) { >> + LOGGER.error("Failed to preload ExecutorServices class.", e); >> + } >> + } >> + >> /** >> * Property name of the property change event fired if the >> configuration is changed. >> */ >> >> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b >> dac7f22/log4j-core/src/main/java/org/apache/logging/log4j/co >> re/util/DefaultShutdownCallbackRegistry.java >> ---------------------------------------------------------------------- >> diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/uti >> l/DefaultShutdownCallbackRegistry.java b/log4j-core/src/main/java/org >> /apache/logging/log4j/core/util/DefaultShutdownCallbackRegistry.java >> index 48d54b6..d2be690 100644 >> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/uti >> l/DefaultShutdownCallbackRegistry.java >> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/uti >> l/DefaultShutdownCallbackRegistry.java >> @@ -72,8 +72,13 @@ public class DefaultShutdownCallbackRegistry >> implements ShutdownCallbackRegistry >> for (final Runnable hook : hooks) { >> try { >> hook.run(); >> - } catch (final Throwable t) { >> - LOGGER.error(SHUTDOWN_HOOK_MARKER, "Caught >> exception executing shutdown hook {}", hook, t); >> + } catch (final Throwable t1) { >> + try { >> + LOGGER.error(SHUTDOWN_HOOK_MARKER, "Caught >> exception executing shutdown hook {}", hook, t1); >> + } catch (final Throwable t2) { >> + System.err.println("Caught exception logging >> exception"); >> + t1.printStackTrace(); >> + } >> } >> } >> state.set(State.STOPPED); >> >> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b >> dac7f22/src/changes/changes.xml >> ---------------------------------------------------------------------- >> diff --git a/src/changes/changes.xml b/src/changes/changes.xml >> index a6279b2..4fa7e54 100644 >> --- a/src/changes/changes.xml >> +++ b/src/changes/changes.xml >> @@ -147,6 +147,9 @@ >> <action issue="LOG4J2-1687" dev="ggregory" type="fix" >> due-to="Robert Christiansen"> >> NPE in ThrowableProxy when resolving stack in Java EE/OSGi >> environment. >> </action> >> + <action issue="LOG4J2-1642" dev="ggregory" type="fix" >> due-to="Johno Crawford"> >> + DefaultShutdownCallbackRegistry can throw a >> NoClassDefFoundError. >> + </action> >> <action issue="LOG4J2-1644" dev="ggregory" type="update" >> due-to="Tim Gokcen, Pavel Sivolobtchik"> >> Inefficient locking in AbstractLoggerAdapter. >> </action> >> >> >> >> >> -- >> Matt Sicker <boa...@gmail.com> >> >> >> > > > -- > Matt Sicker <boa...@gmail.com> > -- Matt Sicker <boa...@gmail.com>