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.

Thursday, November 24, 2011

Why spring beans can not be used in Android

java.beans package again

The Springframework does not work in Android because of its heavy use of classes from java.beans package e.g. PropertyEditorSupport. Android currently only supports a few classes from java.beans package. I already filed feature request to support more classes from java.beans package in the Android bugtracker. Of course one can use classes from libraries of the Springframework in general e.g. org.springframework.core.io.DefaultResourceLoader.

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.

Saturday, April 9, 2011

Spring OSGi - Building extensible and customizable bundles

(work in progess)

Abstract

This artcile shows how to build a domain specific Spring OSGi bundle (dynamic module), which can be customized in projects using fragment bundles. Of course one can use the RCP extension points conecpt etc. to provide customization and extensibility, but in my opinion the Spring way is much more convenient, powerful and dynamic.

The following ideas could be used to inspire a product like application based on a lightweight RCP application framework, wich can be customized and extended in projects to customer needs.

Example case

A bundle provides a view showing data columns of a database table. A project has the requirement to change the columns to be displayed and to change behavior of the view components itself. The view itself is a Spring bean. Lets have a look to the MANIFEST.MF of the host bundle providing the standard view and behavior.

Architecture fundamentals

The following sub chapters describe briefly the fundamental parts of the architecture for dynamic extensible Spring OSGi bundles.

The MANIFEST.MF - Spring application context loading

Manifest-Version: 1.0
Unversioned-Imports: *
Bundle-Name: acme.bundle
Bundle-Vendor: acme
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: acme.CommonFrameWorkBundleActivator
Spring-Context: META-INF/spring/*-init.xml,
META-INF/spring/*.xml,
META-INF/spring-ext/*-init.xml,
META-INF/spring-ext/*.xml

Important is the value of Spring-Context. It defines the order in which the Spring OSGi framework loads the configuration files.

  1. META-INF/spring/*-init.xml - this file is loaded first. Put any bootstrap beans here
  2. META-INF/spring/*.xml - all remaining xml files in META-INF/spring/ are loaded
  3. now META-INF/spring-ext/*-init.xml is loaded. This file is not provided by the host bundle, but later by the fragment bundle, which extends the host bundle
  4. META-INF/spring-ext/*.xml - all other xml files of the fragment are loaded

Bundle Activator

Spring BeanPostProcessors

Spring xml schema extensions

Eclipse RCP - Hide minimize / maximize buttons for editors and views

Abstract

Sometimes a user should not be allowed to maximize/minimize a view or editor. This article is about how achieve this.

Defining custom PresentationFactory

The main entry point to change the presentation of RCP editors and views is to define a custom PresentationFactory, which extends the the default presenetation factory. This presenetation factory then needs to be registered in the plugin.xml.

Registering custom presentation factory in plugin.xml


<extension point="org.eclipse.ui.presentationFactories">
  <factory class="org.acme.ExampleWorkbenchPresentationFactory"/>
</extension>

Changing editor presentation

In order to chage the editor presentation - here to hide the minmize / maximize buttons - we need to override the createEditorPresentation method in the presentation factory


@Override
public StackPresentation createEditorPresentation(final Composite parent,
        final IStackPresentationSite site) {
    final TabbedStackPresentation presentation = (TabbedStackPresentation)super.createViewPresentation(parent, site);
        
    presentation.showMinMax(false);
       
    return presentation;
}

The interesting code here is presentation.showMinMax(false).

Changing view presentation

It is the same code as for the editors - we need to override the method createViewPresentation in the presentation factory.

Using fixed layout

The above steps show, how to hide the minimize and maximize buttons of editors and views, but a double click on an editor/view will still cause the editor/view to be maximized. In order to avoid that, an implemenation of the interface IPerspectiveFactory should be provided as follows


public class MyPerspectiveFactory implements IPerspectiveFactory {
    @Override
    public void createInitialLayout(final IPageLayout layout) {
        layout.setFixed(isLayoutFixed());
    }
}

You should follow me
on twitter