Showing posts with label log4j. Show all posts
Showing posts with label log4j. Show all posts

Tuesday, November 29, 2011

Why Android does not support fully java.beans package

Some, or at least one, classes of java.beans package rely on the java.awt package e.g. PropertyEditor. As stated in an issue, Android can not support the java.awt package.

The uncomplete support of java.beans package causes that various libraries relying on this package can not be used as is e.g. Springframework or Log4j. Also see why Log4j does not work in Android and why Spring does not work in Android.

Add support for more JDK classes to Android

The idea is to repackage JDK classes into another package namspace. The repackaging is not enough, since the relying libraries on the original JDK packages must also be changed/repackaged. So the follwoing steps are needed in theory.

  1. repackage JDK libraries
  2. refactor and repackage libraries relying on (repackaged) JDK classes

Unfortunately in case of java.beans package would not be enough, since the repackaged JDK classes would still depend on java.awt package.

Wednesday, November 23, 2011

Why logging with Log4j does not work in Android

If you put log4j.jar and a log4j.properties file in your Android's application classpath, you will investigate the following stack trace in LogCat.

11-23 09:44:56.947: D/dalvikvm(1585): GC_FOR_MALLOC freed 3278 objects / 311568 bytes in 31ms
rejecting opcode 0x21 at 0x000a
rejected Lorg/apache/log4j/config/PropertySetter;.getPropertyDescriptor
(Ljava/lang/String;)Ljava/beans/PropertyDescriptor;
Verifier rejected class Lorg/apache/log4j/config/PropertySetter;
Exception Ljava/lang/VerifyError; thrown during Lorg/apache/log4j/LogManager;.
Shutting down VM
threadid=1: thread exiting with uncaught exception (group=0x400259f8)
FATAL EXCEPTION: main
java.lang.ExceptionInInitializerError
at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:64)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:253)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:265)
...
Caused by: java.lang.VerifyError: org.apache.log4j.config.PropertySetter
at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:772)
at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:735)
at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:615)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:502)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:547)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:483)
at org.apache.log4j.LogManager.(LogManager.java:127)
... 20 more

The problem is, that log4j uses classes of java.beans package e.g. PropertyDescriptor. Not all classes of this package are supported in Android. See javadoc of Android's java.beans package.

There is a project called android-logging-log4j, which provides a convenient way to configure the log4j system properly. It also provides an appender for LogCat.

I filed a feature request to support more classes from java.beans package in the Android issue tracker.

You should follow me
on twitter