Crazy/Useful - on device debugging idea

I thought I would share a piece of code I used recently in debugging an application on a specific device. It did help solve the problem, but it wasn’t pretty. I’m sure it could be more robust, but it worked for me. Just a note, I’m big on arrays and not using vectors for anything when I code j2me. The device I was debugging on was already close to memory limits so this code uses arrays. The screen was very small as well and 5 lines was all I could fit.


  Font msgFont;
  String errorLines[];

  public yourConstructor()
    {  
    msgFont = Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_PLAIN,Font.SIZE_SMALL);
    errorLines = new String[5];
    }

  public void addLine(String st)
    {
    int i;
    for (i=1;i<errorLines.length;i++)
      {
      errorLines[i-1] = errorLines[i];
      }
    errorLines[errorLines.length-1] = st;

    System.out.println("added line = "+st);
    this.repaint();
    }

  public void paint(Graphics g)
    {  
    /* Your normal paint code here */


    /* print out and put the error lines to the screen */
    System.out.println("ErrorLines.len="+errorLines.length);
    int top = getHeight()-(errorLines.length*msgFont.getHeight());
    int i;
    for (i=0;i<errorLines.length;i++)
      {
      if (errorLines[i]!=null)
        {
        g.drawString(errorLines[i],2,top,Graphics.LEFT | Graphics.TOP);
        }
      top+=msgFont.getHeight();
      }

    }

  public void codeToTest()
    {
     addLine("This is a test");
    }

I spent some time originally trying to catch System.out so I could just see the messages I was already puting out in the emulator, but security restrictions caused that idea to fail.

Hope this helps someone out there.

Wood

I have a similar setup with some addition.
On top of displaying the errors on screen, I can also save them in the RMS (and use a second MIDlet in the Suite to read those logs), or send them to a server with will save the data in a database. A few final static booleans control which of the logging methods will be activated from a general purpose raiseError() method:


private static final boolean LOG_UI = true;
private static final boolean LOG_CONSOLE = true;
private static final boolean LOG_RMS = false;
private static final boolean LOG_NET = false;

public static void raiseError(String error) {
  if (LOG_CONSOLE ) {
    System.out.println(error);
  }
  if (LOG_UI) {
    // something similar to what you did
  }
  if (LOG_RMS) {
    // save the error in the an RMS record
  }
  if (LOG_NET) {
    // send the error to a remote logging server
  }
}

Since the conditions are final variables, the compiler/obfuscator will remove any unused methods from the final application.

shmoove

I have a similar system linked to my static Util.log function using an additonal debug midlet in my suite - very very handy. You’ve given me some ideas as to the remote logging which could be very useful.

Could it be feasible to send any logs via bluetooth (not having implemented any bluetooth applications so far)?

I haven’t dabbled into bluetooth either, but I see no reason why it shouldn’t work.

shmoove