Sunday, December 21, 2008

Ensuring UTF-8 encoded files compile in Staticmatic

Pages with Russian characters are stored (AFAIK) encoded using UTF-8. Unfortunately, this encoding is not compilable by Staticmatic.

A simple workaround is to insert a blank line at the start of the page like so:



Problem solved :)

Tuesday, December 2, 2008

JBoss web service blocked

If you have a web service in JBoss of which you can access the WSDL but keep getting "connection refused" error when accessing the service, then the culprit is normally this:


C:\jboss-4.2.2.GA\bin\run.bat -b 0.0.0.0


or


C:\jboss-4.2.2.GA\bin\run.bat


A solution - at least what worked for me - was to use the actual IP of the machine like so:


C:\jboss-4.2.2.GA\bin\run.bat -b 192.168.1.11


Its funny how modifying JBoss startup scripts did not affect the "-b" option above. However specifying it on the command line works fine.

Monday, July 28, 2008

Using BETWEEN in an EJB3 query


Say if you have an EJB3 entity bean named Landmark which is mapped to a table called landmarks which has 2 columns longitude & latitude (amongst others). To query a given latitude & longitude, its a good idea to relax the query a bit by using BETWEEN.



An example is shown below where we allow a tolerance of 0.00003 for both latitude & longitude. The sample shown is an excerpt from an EJB3 entity bean, right before its class declaration.


@Entity
@Table(name = "landmarks")
@NamedQueries( {
@NamedQuery(
name = "Landmark.findByCoordinates",
query = "SELECT lgr FROM Landmark lgr " +
"WHERE lgr.latitude BETWEEN (?1 - 0.00003) AND (?1 + 0.00003) " +
"AND lgr.longitude BETWEEN (?2 - 0.00003) AND (?2 + 0.00003) ")
})
public class Landmark implements Serializable {

Convert NMEA latitude & longitude to decimal

Here's how you convert latitude & longitude obtained from NMEA's GPGGA to decimal:











 NMEADecimal
latitude0302.7846903 + (02.78469/60) = 3.046412
longitude10141.82531101 + 41.82531/60) = 101.6971


Notice that for latitude of 0302.78469,


03 ==> degress. counted as is


02.78469 ==> minutes. divide by 60 before adding to degrees above


Hence, the decimal equivalent is:


03 + (02.78469/60) = 3.046412

Friday, May 30, 2008

Comparing byte and int in Java

Yet another blog title of mine with "in Java" at the end :)

Anyway, one of the most confusing aspects of dealing with byte in Java was its actual value range. Based on some simple JUnit tests I made, I got the following output:

0 byte = 0 int
1 byte = 1 int
126 byte = 126 int
127 byte = 127 int
-128 byte = 128 int
-127 byte = 129 int
-2 byte = 254 int
-1 byte = 255 int

Interesting ....

From here we can deduce:
1) byte goes from 0 to 127 then -128 to -1
2) the range above actually corresponds to integer values of 0 to 127 then 128 to 255

Here is the JUnit test case which produced the above output. Note that Java does not allow byte values:
1) beyond or equal 128 and;
2) less or equal to -129
... which explains the remarked code portions below.


import static org.junit.Assert.*;
import org.junit.Test;

public class BaitTest {

@Test
public void printNegativeByte() {
byte baitValue;
int intValue;

baitValue = 0;
intValue = baitValue & 0xFF;
System.out.println(baitValue + " byte = " + intValue + " int");

baitValue = 1;
intValue = baitValue & 0xFF;
System.out.println(baitValue + " byte = " + intValue + " int");

baitValue = 126;
intValue = baitValue & 0xFF;
System.out.println(baitValue + " byte = " + intValue + " int");

baitValue = 127;
intValue = baitValue & 0xFF;
System.out.println(baitValue + " byte = " + intValue + " int");

// baitValue = 128;
// intValue = baitValue & 0xFF;
// System.out.println(baitValue + " byte = " + intValue + " int");

// baitValue = -129;
// intValue = baitValue & 0xFF;
// System.out.println(baitValue + " byte = " + intValue + " int");

baitValue = -128;
intValue = baitValue & 0xFF;
System.out.println(baitValue + " byte = " + intValue + " int");

baitValue = -127;
intValue = baitValue & 0xFF;
System.out.println(baitValue + " byte = " + intValue + " int");

baitValue = -2;
intValue = baitValue & 0xFF;
System.out.println(baitValue + " byte = " + intValue + " int");

baitValue = -1;
intValue = baitValue & 0xFF;
System.out.println(baitValue + " byte = " + intValue + " int");
}

}

How to properly print a hexadecimal byte array in Java

Here is a JUnit snippet of how to properly print a hexadecimal byte array in Java. The byte array may actually be an array of integers as well.


import static org.junit.Assert.*;
import org.junit.Test;

public class HeksTest {

@Test
public void printHex() {
byte[] bs = {
(byte)0xCA,
(byte)0x00,
(byte)0x00,
(byte)0x16,
(byte)0x04
};

int[] parameterArray = new int[5];
parameterArray[0] = bs[0];
parameterArray[1] = bs[1];
parameterArray[2] = bs[2];
parameterArray[3] = bs[3];
parameterArray[4] = bs[4];


StringBuffer sb = new StringBuffer();
String hexString = "";
for (int i = 0; i < 5; i++) {
hexString = Integer.toHexString(0xFF & parameterArray[i]).toUpperCase();
if (hexString.length() == 1) {
// i.e. if its "4" then print out as "04"
sb.append("0");
}
sb.append(hexString);
sb.append(" ");
}

int length = sb.length();
sb.setLength(length - 1);
hexString = sb.toString();

System.out.println("address (hex) = [" + hexString + "]");

assertTrue("CA 00 00 16 04".equals(hexString));

hexString = null;
}

}


Perhaps the most important line in the above code is the one shown below. Take note of the toHexString method used here. Also, the array element conversion uses 0xFF to ensure that negative values are converted properly.


hexString = Integer.toHexString(0xFF & parameterArray[i]).toUpperCase();

Convert byte array to integer in Java

The following JUnit test shows how to convert a byte array into a single integer in Java.


import static org.junit.Assert.*;
import org.junit.Test;

public class BaitTest {

@Test
public void printInt() {
byte[] bs = {
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x16,
(byte)0x04
};

int address = (bs[0] << 32) | (bs[1] << 24) |
(bs[2] << 16) | (bs[3] << 8) | bs[4];

System.out.println("address (int) = [" + address + "]");
System.out.printf("address (hex) = [%X]\n", address);

assertTrue(5636 == address);
}
}


In the above, the line :

int address = (bs[0] << 32) | (bs[1] << 24) |
(bs[2] << 16) | (bs[3] << 8) | bs[4];

is where we convert the byte array to a single integer using the assumption that the most significant byte (i.e. MSB) is at index 0. Note that the bit shift values are incremented by multiples of 8 i.e. or 8*0, 8*1, 8*2, 8*3 and 8*4.

In Java 5 upwards, to print a decimal number as hexadecimal, use the "%X" modifier in "printf", as shown in this line from the above code :

System.out.printf("address (hex) = [%X]\n", address);


You'll see that the above will print out "1604" (i.e. 00 00 00 16 04) which is what the byte array looks like at the top of the code, i.e. :


byte[] bs = {
(byte)0x00,
(byte)0x00,
(byte)0x00,
(byte)0x16,
(byte)0x04
};

Thursday, January 31, 2008

How to eject CD drive in OS X

Press F12 for a few seconds.

Then (hopefully) your CD (or DVD) drive will eject.

Wait, why is this considered "not in the manual" ?

Well, today I had to insert a DVD into my optical drive but its physical eject button was not working anymore.

Since I was booted into OS X at the time, I decided to look around for any sign of said optical drive.

But no. Nada. Zip.



This simple & intuitive task in Windows & Linux proved to be surprisingly complicated in OS X. Funny (well ... not at the time though).

So, I went to the Terminal and typed :


eject /dev/cdrom


It replied saying "eject" wasn't found. True enough, the following returned zilch :


find / -name 'eject' -print


Finally succumbed and Googled instead. Then stumbled upon the F12 trick.

Of course once the optical drive isn't empty, then only Finder displays it as a mounted drive !



This, from a premium priced boutique OS :/

I have other gripes concerning OS X but I'll save it for later (... the fan boys are everywhere)

Solution to "Invalid thread access" in eRCP

In Embedded Rich Client Platform, i.e. eRCP, an "Invalid thread access" exception is produced when any class that extends ViewPart executes a new thread the conventional way in method
public void createPartControl(Composite parent)


What do I mean by "executes a new thread the conventional way" ? Well here's an example (let's say we have a class or subclass WeatherData which implements Runnable) :


// This will produce an "Invalid thread access" error
Thread thread = new Thread(new WeatherData());


To eliminate the "Invalid thread access" issue, use this instead :


parent.getDisplay().syncExec(new WeatherData());

Monday, January 28, 2008

Interesting PushRegistry behaviour in Nokia N95

Based on my observation, the PushRegistry feature in Nokia N95 acts unpredictably when the device misses one or more SMS meant for a listening port, i.e. most probably because the device was switched off.

Perhaps a little story would be in order :)

OK, say on your Nokia N95 device, there is a MIDlet which listens for incoming SMS at port 8044.

Now lets send a series of SMS targeted at port 8044 above.

SMS A was sent to the device when it was switched on. MIDlet wakes up ok.

Let's switched off the device.

Send SMS B to said device

Send another SMS, C.

And another one, D.

Now switch on the device.

Your MIDlet may or may not be awaken at this point (even if it does wake up, the content you get may come from either SMS B, C or D !).

A new SMS, E, is sent to the device.

Now you'll discover that the MIDlet will wake up but the contents you see may come from SMS B, C, or D.

Let's say when E was sent, your MIDlet displays content from B instead, not the one in E.

Now another new SMS, F, gets pushed to the device. You'll discover that the contents of SMS C will be displayed instead of the one in F ! (Interestingly if SMS E, resulted in D being displayed, then SMS F will display the contents in SMS E.)

As you can see, the order is intact i.e. SMS B followed by C etc. However, you're not getting the actual SMS which wakes up the MIDlet.

Weird. Very very weird.

Is it a firmware bug ? Could it be the carrier ? Honestly I can't be sure :/

Solution ? Uninstall & reinstall the MIDlet (and ... no, rebooting the device doesn't work either)

Of course once your MIDlet misses an SMS targeted for its PushRegistry port, then the issue pops up again. Hence, there is no solution really :(

"Must be Server" error from PushRegistry with sms

Whew ! Took 2 days to figure this out.

Recently attempted to create a MIDlet which wakes up on SMS using the PushRegistry feature in Java ME.

Kept getting "Must be Server" error at the
mc.receive()
line in following code snippet :


if (url.startsWith("sms://")) {
MessageConnection mc = (MessageConnection) Connector.open(url);
Message msg = mc.receive();
String data = "";

if (msg != null) {
if (msg instanceof TextMessage) {
form.append("TextMessage\n");
data = ((TextMessage)msg).getPayloadText();
}
}
}


Turns out the JAD file of said MIDlet has the following incorrectly typed PushRegistry entry :


MIDlet-Push-1: sms://8033, org.whatever.Poink, *


There should be a ":" after the 2 "slashes" like so :


MIDlet-Push-1: sms://:8033, org.whatever.Poink, *


After the above fix, the "Must be Server" disappeared :)

Friday, January 25, 2008

Probability notations made simple

OK, this ain't Java. Nonetheless this article by Eliezer Yudkowsky really helped in me understanding probability notations (those "|" and "&") as used in Bayesian theory by presenting actual problems instead of the usual Math gobbledygook. Here's a quote :


... p(Q|P) is the proportion of things that have property Q and property P
within all things that have P; i.e.,
the proportion of women with breast cancer and a positive mammography within
the group of all women with positive mammographies.

If there are

641 women with breast cancer and positive mammographies,
7915 women with positive mammographies, and
89,031 women,

then p(Q&P) is the probability of getting one of those 641 women
if you're picking at random from the entire group of 89,031,

while p(Q|P) is the probability of getting one of those 641 women
if you're picking at random from the smaller group of 7915.


Here's another quote :


In a sense, p(Q|P)really means p(Q&P|P), but specifying the extra P all the
time would be redundant. You already know it has property P, so the property
you're investigating is Q - even though you're looking at the size of group
Q&P within group P, not the size of group Q within group P (which would be
nonsense).

This is what it means to take the property on the right-hand side as given;
it means you know you're working only within the group of things that have
property P. When you constrict your focus of attention to see only this
smaller group, many other probabilities change. If you're taking P as given,
then p(Q&P) equals just p(Q) - at least, relative to the group P.
The old p(Q), the frequency of

"things that have property Q within the entire sample",

is revised to the new frequency of

"things that have property Q within the subsample of things that have property P".

If P is given, if P is our entire world, then looking for Q&P
is the same as looking for just Q.