вторник, 25 януари 2011 г.

Failed to load the JNI shared library jvm.dll Eclipse error

If your OS is Windows 7 and you try to run Eclipse you might see this error.
If you do a google search you will see some advices suggesting incompatibility between the jdk,jvm,eclipse versions. In some cases instaling proper versions of them all(x32 or x86) might fix your issue but in my case it didn't.
All the software on my pc i 32 bit. My Windows is 32bit,jdk and eclipse helios too.
What I did to fix the issue was to change in the properties of the eclipse exe and set to run it as administrator.

петък, 14 януари 2011 г.

Blackberry debugging notes

If you are a java developer who has written code in J2SE/J2EE and you are coming to the J2ME world here are some useful tips on debugging for Blackberry applications.
Note: All the notes are are based and tested on the BB Eclipse IDE. Its way better than the other IDE available.
However everything could easily done with the other IDE I suppose.

Here are some facts which are really useful for you to know to avoid frustration:
  • System.out.println() will output something to the console screen only if you debug(Debug As...) your application in a simulator or with attached device.
  • You can't get the strack trace for exception i.e. there is no getStackTrace() method
  • You can't redirect the output i.e. you can't do something like System.setOut
  • Calling e.printStackTrace() on java.lang.Exception won't print stacktrace
  • For optimization purposes for mobile devices stack traces are generated only if there is uncaught exception and in this case the trace will go to the device log. In this way your program crashes and you get dialog with information about the error. The device log is usually accessed by holding ALT button and pressing the keys LGLG.
  • Another way to view exception trace is to catch java.lang.Throwable and then call printStackTrace, note that despite Exception is a subclass of Throwable only catching a Throwable and then calling printStackTrace will actually output the stacktrace to the console.
So if you need to debug your app  you can use println on various places in your code. This could get pretty annoying because when you give your app to clients you will need to remove those prints. Also you don't want everybody to view debug info for your app - everyone could attach the device to a pc and run in debug mode.

A possible solutions is to make some method and maintain a flag which you can change manually in the code.Based on the value of this flag  you will determine whether to print or not. But still you will have more compiled code than you need and the jvm will have to check the value of this flag every time. This approach isn't that bad - it gets the job done.

Personally I prefer to use the preprocess directives which are available. This concept is taken from languages like C/C++. I define a directive and just remove it when I will package the final version. Here is the code:


//#preprocess
package mypackage;

public class Debug {

    public static void log( String msg ){
        //#ifdef DEBUG
        System.err.println( msg );
        //#endif
    }
    
    public static void log( Throwable t ){
        //#ifdef DEBUG
        System.err.println( t.getMessage() );
        t.printStackTrace();
        //#endif
    }
}


You can use this log methods to print information on the console screen and when you create your final version there is no need to remove the calls to these methods from your code. Then the lines where you actually print something won't be compiled. Just remove the directive DEBUG from the Application Descriptor file. The downside of this approach is that you will still have empty method call but method invocation is really fast in the jvm so this isn't a big issue.

четвъртък, 13 януари 2011 г.

Determine if device has touch screen support in J2ME

I had to write some code to determine whether a Blackberry device supports touch screen events. There are APIs from RIM to do this but they are availble for devices with os v4.7 or later and I needed to support os 4.6 also.
So I used the pure j2me approach:
Using javax.microedition.lcdui.Canvas you can determine whether a device has touch screen support by calling the hasPointerEvents() method. Because Canvas is abstract class you should provide a dummy implementation similar to the one I offer. The following code is tested and works on actual Blackberry devices and it should also work on other devices but I haven't tested it.

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

public class TouchSupportInfo extends Canvas {

    private static TouchSupportInfo instance;
    
    private TouchSupportInfo(){
        
    }
    
    public static TouchSupportInfo getInstance(){
        if( instance == null ){
            instance = new TouchSupportInfo();
        }
        return instance;
    }
    
    protected void paint(Graphics g) {
        //leave empty
    }
    
    public boolean isTouchScreenDevice(){
        return hasPointerEvents();
    }

}