Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4j2 on Android

I'm trying to use log4j2 on Android Project (I'm working on Android Studio).

In order to simplify this question, I will explaine what I've done in a simple dummy project (I got the same error in the real project than in this dummy project).

I create a simple dummy project with a main activity.

I add the log4j2 libs...

This is the gradle:

apply plugin: 'com.android.application'

android {
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.test20150130"
        minSdkVersion 19
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.android.support:support-v4:21.0.3'
    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.1'
    compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.1'
}

I've reduced the log4j2.xml to this:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/>
        <PatternLayout pattern="%m%n" />
    </Console>
</Appenders>

<Loggers>
    <root level="INFO">
        <AppenderRef ref="Console"/>
    </root>
    <logger name="Queries" level="ALL" additivity="false">
        <AppenderRef ref="Console"/>
    </logger>
</Loggers>

On the Activity, I import the libraries...

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

But when I try to use them...

Logger logger= LogManager.getLogger ("Queries");
logger.error ("It works...");

I've got an error on the 'Logger logger= LogManager.getLogger ("Queries");'

01-30 00:49:29.413    1685-1685/com.example.test20150130 E/AndroidRuntime? FATAL EXCEPTION: main
Process: com.example.test20150130, PID: 1685
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test20150130/com.example.test20150130.MainScreenActivity}: java.lang.NullPointerException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
        at android.app.ActivityThread.access$800(ActivityThread.java:135)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
        at org.apache.logging.log4j.util.ReflectionUtil$PrivateSecurityManager.getCallerClass(ReflectionUtil.java:301)
        at org.apache.logging.log4j.util.ReflectionUtil.getCallerClass(ReflectionUtil.java:214)
        at org.apache.logging.log4j.util.ReflectionUtil.getCallerClass(ReflectionUtil.java:193)
        at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:72)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:195)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:41)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:160)
        at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:492)
        at com.example.test20150130.MainScreenActivity.delayedHide(MainScreenActivity.java:162)
        at com.example.test20150130.MainScreenActivity.onPostCreate(MainScreenActivity.java:129)
        at android.app.Instrumentation.callActivityOnPostCreate(Instrumentation.java:1150)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2178)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
        at android.app.ActivityThread.access$800(ActivityThread.java:135)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)

I'm not sure where the log4j2.xml file should be, so I trayed to put it on \src, on \src\main\java\com\example\test20150130 (same directory than the main activity), Test20150130\app\build\outputs\apk (same directory than the apk),...

Due to the error information, I tryed the getLogger everywhere: initially on the onCreate, then, I trayed it on an onClick event, but I got the same error.

(When I trayed to debug it, the sources I see are not aligned with the real execution...)

I had log4j already working on the Android project, but I've just migrated a Java EE project to log4j2 and I want to do the same on the Android project...

The log4j2 documentation has very few information about Android. It just says there are several modules not working on Android (JNDI, JMX,...), but nothing else... Maybe it requires internally those modules (JNDI?)...

Looking for information, I've founded this (https://issues.apache.org/jira/browse/LOG4J2-446?jql=project%20%3D%20LOG4J2%20AND%20text%20~%20android) but I did'n find a solution...

Is it possible to use log4j2 on Android?

Thank you very much in advance

like image 913
Alvaro de Lucas Avatar asked Nov 01 '22 10:11

Alvaro de Lucas


1 Answers

I've finally have what I was looking for...

I'm working with Android, and I was unable to recover loggers by name (LogManager.getLogger ("xxx") crashes the App in the worst way possible...)

I think the problem starts when it looks for the log4j2.xml. I put the file everywhere, but it doesn't work... ...so, I wanted to provide the log4j2.xml content into a String...

Here it is what I've done...

    String log4j2xmlFileContent=getLog4j2xmlContent();//Content of my log4j2.xml

    // convert String into InputStream
    InputStream is = new ByteArrayInputStream(log4j2xmlFileContent.getBytes());

    ConfigurationSource source=null;
    try{
        source = new ConfigurationSource(is);
    } catch (IOException ioe){
        ioe.printStackTrace();
    }

    Configuration config = org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory.getInstance().getConfiguration(source);
    loggerContext = (LoggerContext) LogManager.getContext();
    try {
        //loggerContext.stop();
        loggerContext.start(config);
    } catch (Exception e){
        e.printStackTrace();
    }
    return loggerContext;

and now, I can use that loggerContext to get my loggers...

    loggerHitosCarga = context.getLogger("HitosCarga");
    loggerPeticiones = context.getLogger("Peticiones");
    loggerQueries = context.getLogger("Queries");
    loggerDepuracionActual=context.getLogger("DepuracionActual");

    loggerDepuracionActual.warn("FUNCIONAAAAA!!!!..");        
    loggerHitosCarga.info("Loggers inicializados...");

Now I only have to review and improve it a little bit, but it works...

like image 115
Alvaro de Lucas Avatar answered Nov 04 '22 10:11

Alvaro de Lucas