@Before public void setUp() throws Exception { loader1 = new TestClassLoader(); loader2 = new TestClassLoader(); loader3 = new TestClassLoader(); assertNotSame(loader1, loader2); assertNotSame(loader1, loader3); assertNotSame(loader2, loader3); }
@Override public Class<?> loadClass(final String name) throws ClassNotFoundException { if (name.startsWith(getClass().getPackage().getName())) { return findClass(name); } return super.loadClass(name); }
@Override protected Class<?> findClass(final String name) throws ClassNotFoundException { final String path = name.replace('.', '/').concat(".class"); final URL resource = super.getResource(path); if (resource == null) { throw new ClassNotFoundException(name); } try { final URLConnection uc = resource.openConnection(); final int len = uc.getContentLength(); final InputStream in = new BufferedInputStream(uc.getInputStream()); final byte[] bytecode = new byte[len]; try { IOUtils.readFully(in, bytecode); } finally { Closer.closeSilently(in); } return defineClass(name, bytecode, 0, bytecode.length); } catch (final IOException e) { Throwables.rethrow(e); return null; // unreachable } } }
@Test public void regionClassLoader() { RegionClassLoader regionClassLoader = mock(RegionClassLoader.class); withContextClassLoader(regionClassLoader, () -> { logger.info(MESSAGE); verify(contextSelector).getContext(LOGGER_NAME, regionClassLoader, true); }); } }
@Test public void testShutdownCallbackRegistry() throws Exception { final LoggerContext context = ctx.getLoggerContext(); assertTrue("LoggerContext should be started", context.isStarted()); assertThat(Registry.CALLBACKS, hasSize(1)); Registry.shutdown(); assertTrue("LoggerContext should be stopped", context.isStopped()); assertThat(Registry.CALLBACKS, hasSize(0)); final ContextSelector selector = ((Log4jContextFactory) LogManager.getFactory()).getSelector(); assertThat(selector.getLoggerContexts(), not(hasItem(context))); }
@Override public synchronized boolean stop(final long timeout, final TimeUnit timeUnit) { if (!this.isStarted() && !this.isStopped()) { throw new IllegalStateException("Cannot stop this Log4jWebInitializer because it has not started."); } // only do this once if (this.isStarted()) { this.setStopping(); if (this.loggerContext != null) { LOGGER.debug("Removing LoggerContext for [{}].", this.name); this.servletContext.removeAttribute(CONTEXT_ATTRIBUTE); if (this.namedContextSelector != null) { this.namedContextSelector.removeContext(this.name); } this.loggerContext.stop(timeout, timeUnit); this.loggerContext.setExternalContext(null); this.loggerContext = null; } this.setStopped(); } return super.stop(timeout, timeUnit); }
private void initializeJndi(final String location) { final URI configLocation = getConfigURI(location); if (this.name == null) { throw new IllegalStateException("A log4jContextName context parameter is required"); } LoggerContext context; final LoggerContextFactory factory = LogManager.getFactory(); if (factory instanceof Log4jContextFactory) { final ContextSelector selector = ((Log4jContextFactory) factory).getSelector(); if (selector instanceof NamedContextSelector) { this.namedContextSelector = (NamedContextSelector) selector; context = this.namedContextSelector.locateContext(this.name, this.servletContext, configLocation); ContextAnchor.THREAD_CONTEXT.set(context); if (context.isInitialized()) { context.start(); } ContextAnchor.THREAD_CONTEXT.remove(); } else { LOGGER.warn("Potential problem: Selector is not an instance of NamedContextSelector."); return; } } else { LOGGER.warn("Potential problem: LoggerContextFactory is not an instance of Log4jContextFactory."); return; } this.loggerContext = context; LOGGER.debug("Created logger context for [{}] using [{}].", this.name, context.getClass().getClassLoader()); }
protected LoggerContext getDefault() { final LoggerContext ctx = DEFAULT_CONTEXT.get(); if (ctx != null) { return ctx; } DEFAULT_CONTEXT.compareAndSet(null, createContext(defaultContextName(), null)); return DEFAULT_CONTEXT.get(); }
/** * Removes knowledge of a LoggerContext. * * @param context The context to remove. */ @Override public void removeContext(final org.apache.logging.log4j.spi.LoggerContext context) { if (context instanceof LoggerContext) { selector.removeContext((LoggerContext) context); } }
@Override public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext) { return getContext(fqcn, loader, currentContext, null); }
@Override public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext) { return getContext(fqcn, loader, currentContext, null); }
private static ContextSelector createContextSelector() { try { final ContextSelector selector = LoaderUtil.newCheckedInstanceOfProperty(Constants.LOG4J_CONTEXT_SELECTOR, ContextSelector.class); if (selector != null) { return selector; } } catch (final Exception e) { LOGGER.error("Unable to create custom ContextSelector. Falling back to default.", e); } return new ClassLoaderContextSelector(); }
@Override public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext, final URI configLocation) { final LoggerContext lc = ContextAnchor.THREAD_CONTEXT.get(); if (lc != null) { return lc; } String loggingContextName = null; try (final JndiManager jndiManager = JndiManager.getDefaultManager()) { loggingContextName = jndiManager.lookup(Constants.JNDI_CONTEXT_NAME); } catch (final NamingException ne) { LOGGER.error("Unable to lookup {}", Constants.JNDI_CONTEXT_NAME, ne); } return loggingContextName == null ? CONTEXT : locateContext(loggingContextName, null, configLocation); }
private Logger getLogger(final ClassLoader resolvedCtxClassLoader) { if (useThisLoggerContextClassLoader(resolvedCtxClassLoader)) { return originalLogger; } Logger logger; // trick - this is probably a logger declared in a static field // the classloader used to create it and the TCCL can be different // ask contextSelector for the correct context if (contextSelector instanceof ArtifactAwareContextSelector) { logger = ((ArtifactAwareContextSelector) contextSelector).getContextWithResolvedContextClassLoader(resolvedCtxClassLoader) .getLogger(getName(), getMessageFactory()); } else { logger = contextSelector.getContext(getName(), resolvedCtxClassLoader, true).getLogger(getName(), getMessageFactory()); } if (logger instanceof DispatchingLogger) { return ((DispatchingLogger) logger).getLogger(resolvedCtxClassLoader); } else { return logger; } }
LoggerContextFactory factory = LogManager.getFactory(); ContextSelector selector = ((Log4jContextFactory) factory).getSelector(); for (LoggerContext ctx : selector.getLoggerContexts()) { ... Map<String, Appender> m = ctx.getConfiguration().getAppenders(); ... }
public void destroy() { final LoggerContext ctx = (LoggerContext) context.getAttribute(Log4jContextListener.LOG4J_CONTEXT_ATTRIBUTE); if (ctx != null && created) { context.log("Removing context for " + name); context.removeAttribute(Log4jContextListener.LOG4J_CONTEXT_ATTRIBUTE); if (selector != null) { selector.removeContext(name); } ctx.stop(); } } }
/** * Loads the LoggerContext using the ContextSelector using the provided Configuration * @param fqcn The fully qualified class name of the caller. * @param loader The ClassLoader to use or null. * @param externalContext An external context (such as a ServletContext) to be associated with the LoggerContext. * @param currentContext If true returns the current Context, if false returns the Context appropriate * for the caller if a more appropriate Context can be determined. * @param configuration The Configuration. * @return The LoggerContext. */ public LoggerContext getContext(final String fqcn, final ClassLoader loader, final Object externalContext, final boolean currentContext, final Configuration configuration) { final LoggerContext ctx = selector.getContext(fqcn, loader, currentContext, null); if (externalContext != null && ctx.getExternalContext() == null) { ctx.setExternalContext(externalContext); } if (ctx.getState() == LifeCycle.State.INITIALIZED) { ContextAnchor.THREAD_CONTEXT.set(ctx); try { ctx.start(configuration); } finally { ContextAnchor.THREAD_CONTEXT.remove(); } } return ctx; }
/** * Loads the LoggerContext using the ContextSelector. * @param fqcn The fully qualified class name of the caller. * @param loader The ClassLoader to use or null. * @param currentContext If true returns the current Context, if false returns the Context appropriate * for the caller if a more appropriate Context can be determined. * @param externalContext An external context (such as a ServletContext) to be associated with the LoggerContext. * @return The LoggerContext. */ @Override public LoggerContext getContext(final String fqcn, final ClassLoader loader, final Object externalContext, final boolean currentContext) { final LoggerContext ctx = selector.getContext(fqcn, loader, currentContext); if (externalContext != null && ctx.getExternalContext() == null) { ctx.setExternalContext(externalContext); } if (ctx.getState() == LifeCycle.State.INITIALIZED) { ctx.start(); } return ctx; }
private Logger getLogger() { final ClassLoader currentClassLoader = resolveLoggerContextClassLoader(Thread.currentThread().getContextClassLoader()); if (useThisLoggerContextClassLoader(currentClassLoader)) { return originalLogger; } // trick - this is probably a logger declared in a static field // the classloader used to create it and the TCCL can be different // ask contextSelector for the correct context return contextSelector.getContext(getName(), currentClassLoader, true).getLogger(getName(), getMessageFactory()); }
private Logger getLogger() { final ClassLoader currentClassLoader = resolveLoggerContextClassLoader(Thread.currentThread().getContextClassLoader()); if (useThisLoggerContextClassLoader(currentClassLoader)) { return originalLogger; } // trick - this is probably a logger declared in a static field // the classloader used to create it and the TCCL can be different // ask contextSelector for the correct context return contextSelector.getContext(getName(), currentClassLoader, true).getLogger(getName(), getMessageFactory()); }