What logging solutions exist for j2me?
I'm specifically interested in easily excluding logging for "release" version, to have a smaller package & memory footprint.
What logging solutions exist for j2me?
I'm specifically interested in easily excluding logging for "release" version, to have a smaller package & memory footprint.
If you are using preprocessing and obfuscation with Proguard, then you can have a simple logging class.
public class Log {
public static void debug(final String message) {
//#if !release.build
System.out.println(message);
//#endif
}
}
Or do logging where ever you need to. Now, if release.build property is set to true, this code will be commented out, that will result in an empty method. Proguard will remove all usages of empty method - In effect release build will have all debug messages removed.
Edit:
Thinking about it on library level (I'm working on mapping J2ME library) I have, probably, found a better solution.
public class Log {
private static boolean showDebug;
public static void debug(final String message) {
if (showDebug) {
System.out.println(message);
}
}
public static void setShowDebug(final boolean show) {
showDebug = show;
}
}
This way end developer can enable log levels inside library that he/she is interested in. If nothing will be enabled, all logging code will be removed in end product obfuscation. Sweet :)
/JaanusSiim
MicroLog is sure bet. It is a small logging library for Java ME (J2ME) like Log4j. It has support for logging to console, file, RecordStore, Canvas, Form, Bluetooth, a serial port (Bluetooth, IR, USB), Socket(incl SSL), UDP, Syslog, MMS, SMS, e-mail or to Amazon S3.
If you are using preprocessing and obfuscation with Proguard, then you can have a simple logging class.
public class Log {
public static void debug(final String message) {
//#if !release.build
System.out.println(message);
//#endif
}
}
Or do logging where ever you need to. Now, if release.build property is set to true, this code will be commented out, that will result in an empty method. Proguard will remove all usages of empty method - In effect release build will have all debug messages removed.
Edit:
Thinking about it on library level (I'm working on mapping J2ME library) I have, probably, found a better solution.
public class Log {
private static boolean showDebug;
public static void debug(final String message) {
if (showDebug) {
System.out.println(message);
}
}
public static void setShowDebug(final boolean show) {
showDebug = show;
}
}
This way end developer can enable log levels inside library that he/she is interested in. If nothing will be enabled, all logging code will be removed in end product obfuscation. Sweet :)
/JaanusSiim
You can use the -assumenosideaffects in proguard to completley remove your logging class:
-assumenosideeffects public class logger.Logger {*;}
Rather than having to preprocess.
The Series60 and UIQ phone that have a Sun virtual machine modified by Symbian itself have Standard Output redirection.
Not only can you capture System.out but Throwable.printStackTrace() also works.
On early handsets, You would need to write a C++ application that hooks into the standard library server process. Symbian produced the Redirector application that could capture the VM standard output to a console or a file.
On newer handsets, a "redirect://" GCF protocol was introduced that could read the VM standard output into a Java byte[] or String object (you would want to do that in a separate MIDlet) and the Redirector application was rewritten in Java.
On the newest J9 VM used in Series60 3rd Edition Feature Pack 2 handsets (and later), you may need to try "redirect://test" instead.
I've used MIDPLogger to some acceptable level in a production application, although I have found it has more use after integrating into the application rather than as another Midlet in suite or so forth. I also found MicroLog but haven't used it to any great detail.
I wrote a bytecode optimizer, and because of the format of class files you can point to the UTF encoding of classname & function which allows you to output logs with MyClass.someFunc() (you can process the signature if you want to get the types) which allows you to do something like the C style debug using LINE & FILE macros.
Using conditional compilation of the logger class does not solve the problem of completely removing logging statements because you will quite often log more than a simple string. You will look up variable values and then assemble them into strings, e.g.: WhateverLog.log( "Loaded " + someclass.size() + " foos" ).
Now if you only leave out the body of WhateverLog.log (as shown in the accepted solution), you will still leave a lot of unnecessary code in, including String concatenation (and thus a StringBuffer creation). That's why you'd better use a byte code post processing tool like proguard (already mentioned). Proguard's -assumenosideeffects will allow its optimizer to remove not only the logging statements but also all code whose results would only be used by the logging call.
WhateverLog.log("Loaded %d foos", someclass.size());
. The formatting is only done if logging is enabled. Ideally, you would also avoid doing an extra size
call if possible. –
Quatrefoil LWUIT framework of the J2ME provide the Logging form which can have a log the statement inside it. You can add the log at each and every place you think may generate the exception.
Example : Log.getInstance().showLog(); By adding the above line you can able to track the logging in the J2ME devices.
© 2022 - 2024 — McMap. All rights reserved.