We were using Pax Logging 1.6.1 for a long time (yes, I know it's old). We are now upgrading all of our infrastructure. We tried using Pax Logging 1.10.2. After much debugging, I finally figured out why our logging isn't working the same way as before.
Someone added generics to Pax Logging in December 2015 in this commit: https://github.com/ops4j/org.ops4j.pax.logging/commit/57e0580e0ad290e96f9c4ff64d3d3682d8dedf6c#diff-abdd339630db78965e0e1db82369e4ef In the original code, the m_loggers static variable for all LogFactory types (Commons Logging, SLF4J, Log4J, etc.) was initialized without generics as: m_loggers = new WeakHashMap(); In the new code, this became: m_loggers = new WeakHashMap<String, JclLogger>(); // Or <String, Slf4jLogger>, or <String, Logger>, etc., depending on type. However, the original code was using m_loggers with the logger as the key and the name as the value, which means *the generics should have been*: m_loggers = new WeakHashMap<JclLogger, String>(); // Or <Slf4jLogger, String>, or <Logger, String>, etc., depending on type. The original code from pax-logging-api/src/main/java/org/apache/commons/logging/LogFactory.java is: <https://github.com/ops4j/org.ops4j.pax.logging/commit/57e0580e0ad290e96f9c4ff64d3d3682d8dedf6c?diff=split#diff-abdd339630db78965e0e1db82369e4ef> public Log getInstance(String name) throws LogConfigurationException { PaxLogger logger; if (m_paxLogging == null) { logger = FallbackLogFactory.createFallbackLog(null, name); } else { logger = m_paxLogging.getLogger(name, JclLogger.JCL_FQCN); } JclLogger jclLogger = new JclLogger(logger); synchronized (m_loggers) { m_loggers.put(jclLogger, name); // THIS LINE GOT CHANGED WHEN YOU ADDED GENERICS. KEY/VALUE GOT SWAPPED. } return jclLogger; } After generics were added, the indicated line became: m_loggers.put(name, jclLogger); // THIS LINE GOT CHANGED WHEN YOU ADDED GENERICS. Even in the old code, even if the same name was passed to getInstance twice, each one resulted in an independent JclLogger. But, *both* JclLogger instances were stored in m_loggers (because the *key* was the logger itself, and the name was the value), and *both* (or *all*, if the same name was used more than twice) got the proper Pax Logging configuration once the Pax Logging API and Service got started (the DefaultServiceLog, or whatever came out of the FallbackLogFactory, got replaced with a TrackingLogger, and then the logging properties from org.ops4j.pax.logging.cfg were respected). With the new code, if you pass the same name to getInstance twice, each one still gets an independent JclLogger. But, when the call to m_loggers.put is made with a name that already has a JclLogger, the old JclLogger is removed from m_loggers, and m_loggers.get(name) only returns the new JclLogger. *When Pax Logging API and Service get started, only the most recent JclLogger for the name gets its DefaultServiceLog replaced by a TrackingLogger, and the other JclLogger instances for that name still use a DefaultServiceLog, because those JclLogger instances aren't stored in m_loggers anymore.* Then, when an attempt is made to log to the JclLogger that still uses DefaultServiceLog, the logging properties from Pax Logging in org.ops4j.pax.logging.cfg are ignored. This happens for all loggers (Log4J, SLF4J, etc.), not just JclLogger. We have Pax Logging API and Pax Logging Log4J2 1.10.2 jars in /var/payara5/glassfish/modules/autostart (which correlates to where we always had the old Pax Logging 1.6.1 jars in Glassfish 3.1.2.2-- /var/glassfish/glassfish/modules/autostart). When I use the "autodeploy" directory in my Glassfish domain to deploy a new war after the Glassfish domain is already up and running with Pax Logging started, all of the logging works correctly, because it never sees a DefaultServiceLog at all (it gets TrackingLogger immediately). If I stop the domain and restart it with a war already deployed, the war starts up with DefaultServiceLog instances (the war starts up before Pax Logging starts [war starts creating logger instances before the Activator for Pax Logging API is called])), and not all instances get changed to TrackingLogger, as described above. Thus, the logging is all messed up. If I "touch" the war (to force Glassfish to redeploy while Glassfish is running), then it gets the proper logging configuration, because Pax is started by now. ====================== *Based on the observed behavior, I regard this as a bug in Pax Logging. I should not have to redeploy my wars every time I restart my domain, just so that logging is picked up correctly.* There is no Jira ticket associated with the commit to "add generics". Thus, it is not clear that this was an intentional change to the behavior of Pax Logging. I'm surprised no one complained about it before. Can you look at this and tell me if this is intentional, or if there is any other way to deal with it besides redeploy my wars every time we restart the Glassfish domain? Thank you, Monica -- -- ------------------ OPS4J - http://www.ops4j.org - [email protected] --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/ops4j/952b7207-cd2b-4229-af4a-f60c934d2c1f%40googlegroups.com.
