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.