Sunday, August 1, 2010

JBoss 5.1 doesn't work well with WebService

I was struggling to adopt WebService in JBoss 5.1. It kept blowing up with Exception saying:

java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage

Thanks to master Google, I figured out the problems and came up with a solution. There is a compatible issue between JBoss 5.1 and webService. From the JBoss 5.1 release note: JBoss 5.1 Compatibility Issues, you would realise that the problem was back to JBoss 5.0. It’s supposed to be fixed after that. But somehow, it wasn’t. Basically, there are two issues:

1. It doesn’t really pick up the $JBOSS_HOME/lib/endorsed directory. So I had to end up specifying endorsed folder in JBoss server configuration. That means if you run your JBoss from Eclipse, you need to add the following parameter into the VM arguments of the JBoss server:

-Djava.endorsed.dirs=$JBOSS_HOME /lib/endorsed

2. Copy the following jar files from $JBOSS_HOME /lib to $JBOSS_HOME /lib/endorsed:

jbossws-native-saaj.jar

jbossws-native-jaxrpc.jar

jbossws-native-jaxws.jar

jbossws-native-jaxws-ext.jar

Then Everything should start working!

Monday, June 14, 2010

Two things in Java regex

1. Java Regex "eats" characters: a regex runs from left to right, and once a character has been matched and used, it can't be reused any more. For example, the following codes demonstrate that:

Pattern pattern = Pattern.compile("aba");
Matcher matcher = pattern.matcher("abababababa");
while(matcher.find()) {
System.out.print(matcher.start() + " ");
}

output: 0 4 8

2. Greedy and Reluctant Quantifiers: Greedy quantifier tries to search for a possibly maximum match against a string, for example in "abababababa", the pattern "[\\w]*aba" will find "abababababa". It does in fact read the entire source string and then works backwards until it finds the rightmost match.

On the other hand, reluctant quantifier will find as many match-ups as possible. For the same source string, the pattern "[\\w]*?aba" will get "aba" "baba" "baba". Here is the demonstration:

Pattern pattern2 = Pattern.compile("[\\w]*aba");
Matcher matcher2 = pattern2.matcher("abababababa");
while(matcher2.find()) {
System.out.println(matcher2.group());
}

output: abababababa

Pattern pattern3 = Pattern.compile("[\\w]*?aba");
Matcher matcher3 = pattern3.matcher("abababababa");
while(matcher3.find()) {
System.out.println(matcher3.group());
}

output: aba baba baba

will post a separate page about Possessive quantifier later.

Monday, June 7, 2010

When Java create an actual file

It has been a long time that I thought "File file = new File("readme.txt")" will create an actual file called "readme.txt". Obviously, I was wrong and the consequent codes always blew up with a NullPointerException or IOException saying file or directory not found.

After a bit googling, I figured out the whole thing and wanted to share the thing I know.

There are two ways to create actual files in Java:
  • create a file explicitly with method createNewFile() from a File object:
file.createNewFile();
Even though the method called "createNew...", but it doesn't have to be a file non-existed. I mean it will just ignore the creation if the file is existing.

  • initialising a Writer or Stream, for example, PrintWriter with the file as passed-in parameter will create an actual file:
PrintWriter writer = new PrintWriter(file);

That looks easy. But how about directory creation. Do you think the following codes will work out assuming that the "javaCoffee" directory isn't there?

File dir = new File("javaCoffee");
File file = new File(dir, "bean.txt");
file.createNewFile();

Looks good but unfortunately, the last line will throw an IOException saying "No such file or directory". When creating a directory, you have to explicitly invoke "mkDir()" before creating any files inside the folder, even though you specified the absolute path like: "File file2 = new File("C:/javaCoffee/bean.txt")". It will throw an FileNotFoundException.


This is easy as well once you know it.

Friday, June 4, 2010

@XmlTransient and @Transient

@Transient is a JPA annotation which specified that the field is not going to be persistent. But @XmlTransient one of JAXB annotations is to exclude the field when marshalling the Java objects to a xml file.

I ever made a stupid mistake and replaced @Transient with an @XmlTransient, and thought @XmlTransient would do both things. How could I come up with such "thought"?

Obviously, that would throw up tons of unit test failures with the following exceptions:
Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of uk.co.ondemand.cmm.service.persistence.Product.providerAssetId
......
Caused by: java.lang.IllegalArgumentException
......
The reason of those exceptions is that the unit tests started persisting the field but couldn't find any corresponding values in the test data, say DBUnit. That meant it couldn't insert a value into a field hasn't been defined in the test data.

Wednesday, June 2, 2010

How Java substring works

If you think you are a Java String guru, what do you expect the output of this:

String x = "0123456789";
System.out.println(x.substring(4, 9));
System.out.println(x.substring(4, 3));
System.out.println(x.substring(4, 4));

The fact is:
// start at index 4 and return the characters up to and including the

// 9th position (index 8). So the output is "45678".
System.out.println(x.substring(4, 9));

// java.lang.StringIndexOutOfBoundsException: String index out of range: -1

System.out.println(x.substring(4, 3));

// I thought it would be out-of-bounds. But it's a empty string, WEIRD! isn't it.

System.out.println(x.substring(4, 4));