This technical article explains how to add logging to your MIDlets using the Microlog open-source logging library. Contents
IntroductionYou have just developed your new cool MIDlet, the one that is going to rule the world. It runs like a well oiled machine on the emulator. But when you download and install it on your target device, the MIDlet seems to take ages to start up. Finally, you see the splash screen. Oh no! The MIDlet crashes and you get an error pop-up saying "Application Error," and the MIDlet shuts down. What happened? This is not the way you pictured it. Is there something that shows what really happened behind the scenes? Have you been in a situation like this? Have you ever wanted to log from your MIDlet? Read on, and I will teach how to add powerful logging to your MIDlets. Getting Started with MicrologYou may have considered doing your own logging facility. But why not use an existing solution? An easy-to-use solution exists: The Microlog open-source logging library. It is based on the well known Log4j API or logging library, but has been created from the ground up with Java ME limitations in mind. The library is released with Apache Software License V2. Thus you can use it in your own open-source projects, as well as in commercial applications. But let's get down to business and do some programming. To add logging to your MIDlet, follow these steps:
I will not go into detail about the first two items. Please refer to the instructions for the specific IDE that you are using. Starting at step 3, the source code is as follows. (For your convenience, I have attached all example source code files and configuration files.)
package com.jayway.midlet.techtip;
import java.io.IOException;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.*;
import net.sf.microlog.core.Logger;
import net.sf.microlog.core.LoggerFactory;
import net.sf.microlog.core.PropertyConfigurator;
/**
* The SimpleLoggingMidlet shows how simple it is to add logging to a midlet.
*
* It has a simple GUI that let you try out logging.
* N.B. there has to be some kind of GUI, otherwise it wont work in Suns WTK.
*
* @author Johan Karlsson
*/
public class SimpleLoggingMidlet extends MIDlet implements CommandListener {
// A logger instance for this class
private static final Logger log = LoggerFactory.getLogger(SimpleLoggingMidlet.class);
private Display display;
private Form form;
private Command logCommand = new Command("Log", Command.OK, 1);
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
/**
* Constructor.
*/
public SimpleLoggingMidlet() {
// Configure Microlog
PropertyConfigurator.configure();
}
/**
* @see javax.microedition.midlet.MIDlet#startApp()
*/
public void startApp() {
log.info("Starting application");
if (form == null) {
log.debug("Creating a new Form");
form = new Form("Simple Logging");
form.addCommand(logCommand);
form.addCommand(exitCommand);
form.setCommandListener(this);
display = Display.getDisplay(this);
}
display.setCurrent(form);
}
/**
* @see javax.microedition.midlet.MIDlet#pauseApp()
*/
public void pauseApp() {
log.info("Pausing application");
}
/**
* @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
*/
public void destroyApp(boolean unconditional) {
log.info("Destroying application");
// Shutdown Microlog gracefully
LoggerFactory.shutdown();
}
/**
* @see CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable)
*/
public void commandAction(Command command, Displayable displayable) {
if (command == logCommand) {
log.debug("User pressed the log button.");
} else if (command == exitCommand) {
log.debug("Exit button was pressed");
notifyDestroyed();
}
}
}
As you can see, the code is really simple. You create a
The
Notice that this should only be done once in an application, and this is why it is recommended to put it in the constructor of the main class. When developing a MIDlet, that is, it should always be in the constructor of the MIDlet. This ensures that it executes only once in the MIDlet's lifetime. To ensure that Microlog shut down correctly, you should add a call to # This is a simple Microlog configuration file microlog.level=DEBUG microlog.appender=ConsoleAppender microlog.formatter=SimpleFormatter The Another solution is to use the Let me show how simple it is to change the logging. All you have to do is change the configuration file and rebuild the jar. The following example shows how to add logging to the record store and change the layout of the log output. # Another simple Microlog configuration file. We now log to two different # destinations; the console and the record store. microlog.level=DEBUG microlog.appender=ConsoleAppender;RecordStoreAppender microlog.formatter=PatternFormatter microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T We have added the The Now compile and run the MIDlet once more, but with the new configuration file. The MIDlet logs to the record store while executing the MIDlet. Afterwards, when you have exited the MIDlet, you start the prepackaged record store log viewer. This is how it looks in action:
Using the Bluetooth ServerBut that is not all! Many developers use Bluetooth to send their MIDlets to the target, to avoid the tedious need to connect and disconnect USB cables. If you are one of those developers, you might want to use the The following picture shows the Bluetooth server in action. Notice that it is possible to connect several clients at the time. I am using an older Sony Ericsson P910 device (in general, Microlog executes on older devices without problem).
Logging DestinationsBut wait, there is even more. You have a myriad of logging destinations available in Microlog. Some of them are on-device, while others send the log to a remote device. In early stages of development, it is most convenient to use the on-device logging (or Bluetooth). Later in the development cycle, it is often more suitable to use remote device logging. My favorite on-device logging destination is a file. On many devices, it is possible to read the log on the device. Most of the time I transfer the file to my computer and view it in my favorite editor. (If you are a dedicated Unix lover, use
Log Levels and FilteringOne of the most important functions in a logging framework is the ability to filter your logging statements, just like Log4j. In Microlog, this is solved by assigning different levels to your logging statements. It is important to use the right level when logging. Otherwise the logs will be flooded and performance will most likely be affected in a negative way. When you set a level in Microlog, you logs everything at the specified level and above. For example, if you choose to log at level Since version 2.0 of Microlog, it has been possible to assign different levels to different classes. Let us assume that you have a MIDlet that is getting a big, that is, you have many classes. The logs get flooded by logging outputs, but you do not want to remove all important logging statements as most of them are there for a good reason. In such cases, it is possible to choose to only enable those classes that are relevant at the moment. For example, you are hunting down a bug and you know that is in a particular package. Look at this example:
microlog.rootLogger=ERROR, A1, A2
microlog.appender.A1=ConsoleAppender
microlog.appender.A2=RecordStoreAppender
microlog.appender.A1.formatter=PatternFormatter
microlog.appender.A1.formatter.pattern=%c{1} [%P] %m %T
microlog.logger.com.jayway.midlet.techtip=DEBUG
First, you set the root logger: You set the logging level and specify two appenders. We set the level to You give the appenders symbolic names, in this case A1 & A2. The setup of the appenders and the formatter is the same, except that we insert the symbolic name. Notice that we we use the default settings for the The property for setting the level is the string The following table shows the different logging levels available in Microlog. The first level,
SummaryThis article shows how easy it is to add powerful logging to your MIDlet. It is done by simply adding the jar and a configuration file to your project. Once this is done, it is a matter of editing the configuration file to your liking. Logging is an essential tool for embedded developers, and a nice companion to a debugger. It will help you in situations where using an emulator is not a viable solution. In Microlog, it is also possible to use in a headless environment, that is, an embedded device without a GUI. For more tips and tricks, see the official Microlog blog. Happy logging! Resources
|
Get TrainingJohan Karlsson is the co-founder and member of several open source projects for Java ME, including Microlog and Microproperties. He currently works at Jayway as a senior Java embedded developer.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.
|
| ||||||||||||