ews-android-api icon indicating copy to clipboard operation
ews-android-api copied to clipboard

missing class : org.apache.log4j.Priority (API Level 17)

Open tmakin opened this issue 9 years ago • 15 comments

Hi Alex,

I've been trying to get this working on an API Level 17 emulator, but the library was throwing a missing class exception related to log4j

E/dalvikvm: Could not find class 'org.apache.log4j.Priority', referenced from method android.org.apache.commons.logging.impl.Log4JLogger.<clinit>

I haven't found the origin of the error, but I managed to get round it by pasting in 2 extra shim classes into the path ews-android-api/src/main/java/org/apache/log4j. I then recompiled with your gradlew script.

The classes I added were Priority.java and Level.java stolen from the project below without modification: https://code.google.com/p/log4j-android/

I can't be sure if these extra classes have any unwanted side effects, but they worked for me. Note that the package name used was org.apache, without the android.prefix

I've now done successful EWS tests on API levels 17, 21 and 23. I'm running a Nexus 7 x86 emulator on a mac book pro.

I'd be interested to know your thoughts on this.


EDIT: Just checked the logs for my patched version of the library and it is still searching for log4j stuff but it seems these errors are non fatal. For example:

I/dalvikvm: Could not find method org.apache.log4j.Logger.getName, referenced from method android.org.apache.commons.logging.impl.Log4JLogger.<init>

tmakin avatar Oct 11 '15 20:10 tmakin

Hi Tom,

Thanks for your report.

I haven't added log4j library because it's an optional dependency in commons-logging.

The expected behaviour will probably be:

  • write logs to Android's log system by default
  • anyone desired to use log4j will have to add that dependency explicitly

How that sounds to you?

alipov avatar Oct 12 '15 14:10 alipov

That's fine with me, I have no preference on which logging system is used, I'm just trying to get it to run. Is there anything I should be doing to disable log4j?

Out of interest do you see this same behavior on API 17?

tmakin avatar Oct 12 '15 14:10 tmakin

It's configured somewhere, I'll look into it.

I've tested on both KitKat and Lollipop, saw the dalvikm warnings but never crashed. Can you post the crash stack trace?

alipov avatar Oct 12 '15 14:10 alipov

Here is the stack trace when EWS fails:

10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground()
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.os.AsyncTask$3.done(AsyncTask.java:299)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:856)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:  Caused by: java.lang.ExceptionInInitializerError
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTest.connectToExchange(EWSTest.java:76)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTest.test(EWSTest.java:60)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTestTask.doInBackground(EWSTest.java:37)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTestTask.doInBackground(EWSTest.java:31)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:856) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:  Caused by: android.org.apache.commons.logging.LogConfigurationException: java.lang.NullPointerException (Caused by java.lang.NullPointerException)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:571)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:292)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:269)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at microsoft.exchange.webservices.data.core.ExchangeServiceBase.<clinit>(ExchangeServiceBase.java:80)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTest.connectToExchange(EWSTest.java:76) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTest.test(EWSTest.java:60) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTestTask.doInBackground(EWSTest.java:37) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTestTask.doInBackground(EWSTest.java:31) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.os.AsyncTask$2.call(AsyncTask.java:287) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:856) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:  Caused by: java.lang.NullPointerException
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(LogFactoryImpl.java:1067)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:844)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:541)
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:292) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:269) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at microsoft.exchange.webservices.data.core.ExchangeServiceBase.<clinit>(ExchangeServiceBase.java:80) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTest.connectToExchange(EWSTest.java:76) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTest.test(EWSTest.java:60) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTestTask.doInBackground(EWSTest.java:37) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at com.tmakin.ewsdemo.EWSTestTask.doInBackground(EWSTest.java:31) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.os.AsyncTask$2.call(AsyncTask.java:287) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
10-12 15:45:53.519 18705-18737/com.tmakin.ewsdemo E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:856) 

tmakin avatar Oct 12 '15 15:10 tmakin

The log4j errors disappear if I stick this at the top of my MainActivity:

public class MainActivity extends AppCompatActivity {

    static {
        System.setProperty("android.org.apache.commons.logging.Log",
                "android.org.apache.commons.logging.impl.SimpleLog");
    }
...

I've also tried adding it to gradle.properties in my app but that didn't work. I'll try adding it your grade.properties file and see what that does.

tmakin avatar Oct 12 '15 16:10 tmakin

putting the property in gradle.properties didn't work for me. Do you think it could be slotted into build.gradle somewhere?

tmakin avatar Oct 12 '15 16:10 tmakin

Try to put it into a commons-logging.properties configuration file, for example as shown here.

alipov avatar Oct 12 '15 16:10 alipov

Yeah, I found that. But I have no idea how to make the compiler pay attention to it. That's why I went with gradle.properties.

tmakin avatar Oct 12 '15 16:10 tmakin

Check out this (from here):

Use the JDK 1.3 JAR Services Discovery mechanism (see http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html  for more information) to look for a resource named META-INF/services/org.apache.commons.logging.LogFactory whose first line is assumed to contain the desired class name.

I believe the ews-java-api pre-set it with log4j.

alipov avatar Oct 12 '15 16:10 alipov

I can't find any references to log4j in ews-java-api. The only place it shows up is the pom.xml for commons-logging inside repackaged-dependencies.jar

tmakin avatar Oct 12 '15 17:10 tmakin

OK, I'm finally at home and was able to look into this issue.

I was able to workaround it by creating alternative LogFactory implementation that always returns SimpleLog instance (I just copied all the rest functionality from LogFactoryImpl.java).

Then I unzipped the apk, and created a org.apache.commons.logging.LogFactory file under META-INF/services folder. It contains a single line which is a name of your LogFactory implementation. And finally, I've zipped the contents into apk file, signed and zipaligned it.

I will, of course, add a holistic solution for this later on.

alipov avatar Oct 12 '15 19:10 alipov

Nice work. Thanks for checking it out.

tmakin avatar Oct 12 '15 20:10 tmakin

Can add that I am also experiencing this issue. @tmakin Which method did you find to be the best, modification using System.properties?

wwahmed avatar Apr 09 '16 04:04 wwahmed

Can anyone give me an answer????????

freeloopmko687 avatar Jun 15 '16 03:06 freeloopmko687

@freeloopmko687 On which question?

alipov avatar Jun 15 '16 05:06 alipov