Fix: Warn when log4j version is too old
[lttng-ust.git] / liblttng-ust-java-agent / java / org / lttng / ust / agent / LTTngAgent.java
index 342ccfae15c0c0bb45c29291c2f236bc2e60d9fc..f7e1e386be9bd5a56e0016ef235081490782c299 100644 (file)
@@ -29,7 +29,6 @@ import java.util.Enumeration;
 import java.lang.reflect.InvocationTargetException;
 
 import java.util.logging.Logger;
-import java.util.logging.FileHandler;;
 import java.util.logging.SimpleFormatter;
 
 public class LTTngAgent {
@@ -92,23 +91,66 @@ public class LTTngAgent {
        }
 
        private Boolean loadLog4jClasses() {
-               Boolean loaded = false;
+               Class<?> logging;
+
                try {
-                       ClassLoader loader = ClassLoader.getSystemClassLoader();
-                       loader.loadClass("org.apache.log4j.Logger");
-                       loaded = true;
+                       logging = loadClass("org.apache.log4j.spi.LoggingEvent");
                } catch (ClassNotFoundException e) {
                        /* Log4j classes not found, no need to create the relevant objects */
-                       loaded = false;
+                       return false;
+               }
+
+               /*
+                * Detect capabilities of the log4j library. We only
+                * support log4j >= 1.2.15.  The getTimeStamp() method
+                * was introduced in log4j 1.2.15, so verify that it
+                * is available.
+                *
+                * We can't rely on the getPackage().getImplementationVersion()
+                * call that would retrieves information from the manifest file
+                * found in the JAR since the manifest file shipped
+                * from upstream is known to be broken in several
+                * versions of the library.
+                *
+                * More info:
+                * https://issues.apache.org/bugzilla/show_bug.cgi?id=44370
+                */
+
+               try {
+                       logging.getDeclaredMethod("getTimeStamp");
+               } catch (NoSuchMethodException e) {
+                       System.err.println("Warning: The loaded log4j library is too old. Log4j tracing with LTTng will be disabled.");
+                       return false;
+               } catch (NullPointerException e) {
+                       /* Should never happen */
+                       return false;
+               } catch (SecurityException e) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       private Class<?> loadClass(String className) throws ClassNotFoundException {
+               ClassLoader loader;
+               Class<?> loadedClass;
+
+               try {
+                       /* Try to load class using the current thread's context class loader */
+                       loader = Thread.currentThread().getContextClassLoader();
+                       loadedClass = loader.loadClass(className);
+               } catch (ClassNotFoundException e) {
+                       /* Loading failed, try using the system class loader */
+                       loader = ClassLoader.getSystemClassLoader();
+                       loadedClass = loader.loadClass(className);
                }
 
-               return loaded;
+               return loadedClass;
        }
 
        private void initAgentJULClasses() {
                try {
-                       ClassLoader loader = ClassLoader.getSystemClassLoader();
-                       Class<?> lttngJUL = loader.loadClass("org.lttng.ust.agent.jul.LTTngJUL");
+                       Class<?> lttngJUL = loadClass("org.lttng.ust.agent.jul.LTTngJUL");
                        this.julUser = (LogFramework)lttngJUL.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(false);
                        this.julRoot = (LogFramework)lttngJUL.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(true);
                        this.useJUL = true;
@@ -128,8 +170,7 @@ public class LTTngAgent {
 
        private void initAgentLog4jClasses() {
                try {
-                       ClassLoader loader = ClassLoader.getSystemClassLoader();
-                       Class<?> lttngLog4j = loader.loadClass("org.lttng.ust.agent.log4j.LTTngLog4j");
+                       Class<?> lttngLog4j = loadClass("org.lttng.ust.agent.log4j.LTTngLog4j");
                        this.log4jUser = (LogFramework)lttngLog4j.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(false);
                        this.log4jRoot = (LogFramework)lttngLog4j.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(true);
                        this.useLog4j = true;
This page took 0.026142 seconds and 4 git commands to generate.