I have a Java application (= launcher) which loads classes via a custom ClassLoader. In my launched application as well as in the launcher I'm using log4j2 with a custom XML configuration.
In the launcher:
private static final Logger LOGGER;
static
{
loadLog4jConfiguration(ApplicationLauncherClient.class);
LOGGER = getLogger();
}
loadLog4jConfiguration() is implemented as follows:
public static void loadLog4jConfiguration(final Class<?> clazz)
{
try
{
String resourceName = "launcher-log4j2.xml";
try (InputStream inputStream = clazz.getResourceAsStream(resourceName))
{
if (inputStream == null)
{
System.err.println("Cannot find resource: " + resourceName);
} else
{
ConfigurationSource configurationSource = new ConfigurationSource(inputStream);
Configurator.initialize(null, configurationSource);
}
}
} catch (final Exception exception)
{
exception.printStackTrace();
}
}
In the launched application I do the same setup for log4j2 but I load a *different* log4j2.xml file from the classpath (e.g. to provide JTextArea appending of log messages).
Unfortunately, the JTextArea logs do not work when custom classloading. They work however when I launch the application normally (e.g. via IDE). I assume there is some sort of clash between log4j2 instances. The launcher and the launched application hold the log4j2 maven dependency. How would I resolve this cleanly? I do not want to remove log4j2 from the launcher entirely. I thought about maybe always passing a class instance into the getLogger() constructor on the launched application but that didn't help either. I printed out the ClassLoader of the LOGGER instance on the launched application and it said sun.misc.Launcher$AppClassLoader in both cases (when custom classloading and when launching it normally via the IDE) so now I'm not sure what else to try.