18 January 2010

Calling session beans on JSF Managed bean's start up

One situation may occurs is that you need to call some session bean method on some JSF page's start up.

If you try to put the code that calls the injected EJB session bean's method in your JSF request-scoped Managed bean constructor, you will get a NullPointerException as the Injection occurred after making an instance of the managed bean.

The solution is that to provide a @PostConsruct method and put your EJB calling code in.
@PostConsruct is supported in JSF1.2 and if you running your JSF Application in an Application Server (example JBoss)

So, Here's the sequence the managed bean instance is created in:

Calling manged bean constructor => Injecting Session bean (if any) => calling PostConstruct method(s) (if any)

Here's an example:

public class ShowArticleBean {

@EJB(name="SimpleWiki/ArticleManagementBean/local")
private ArticleManagement articleMgmt;

public ShowArticleBean() {
System.out.println("In Constructor : " + articleMgmt);

}

@PostConstruct
public void construct() {
System.out.println("In PostConsruct : " + articleMgmt);
}


And here's the output :

04:51:29,546 INFO [STDOUT] In Constructor : null
04:51:29,547 INFO [STDOUT] In PostConsruct : ArticleManagementBean

12 January 2010

Avoid throwing RuntimeException from you Session beans

Working with session beans usually requires you to throw some type of exceptions to the calling layer (usually the presentation layer), So beware, don't try to throw RuntimeExceptions or RemoteException because the Container will encapsulate these exceptions in EJBException and then destroys the bean instance from the bean bool.

If you need to throws Runtime/Remote Exceptions, then add @ApplicationException(rollback=true) as a class level annotation to your Exception class, and this applicable only on your own custom exceptions.

In all cases (RuntimeException or Application Exceptions) the container will rollback the transactino.

From EJB in Action :
“In EJB , an application exception is an exception that the client is expected to handle. When thrown, such exceptions are passed directly to the method invoker. By default, all checked exceptions except for
java.rmi.RemoteException are assumed to be application exceptions.
On the other hand, all exceptions that inherit from either java.rmi. RemoteExceptions or java.lang.RuntimeException are assumed to be system exceptions (as you might already know, all exceptions that inherit
from java.lang.RuntimeException are unchecked). In EJB , it is not assumed that system exceptions are expected by the client. When encountered, such exceptions are not passed to the client as is but are wrapped in a javax.ejb.EJBException instead.”

Here's an example session bean that throws IllegalArguemntException ( a well-known runtime exception):

@Stateless
@Remote(AccountManagement.class)
@Local(AccountManagement.class)
public class AccountManagementBean extends DBBaseBean implements AccountManagement {

public void registerUser(User user) throws IllegalArgumentException {

if (user == null || StringUtil.isNullSpacesOrEmpty(user.getUsername()) || user.getPassword() == null)
throw new IllegalArgumentException("Uncomplete user registeration data");

em.persist(user);
logger.info("User created :" + user.getUsername());
}
@PostConstruct
public void init() {
System.out.println("INIT");
}
@PreDestroy
public void destroy() {
System.out.println("DESTROY");
}

}

And here's a test client :

public class Main {
public static void main(String[] args) throws Exception{
AccountManagement test = InitialContext.doLookup("SimpleWiki/AccountManagementBean/remote");

try {
test.registerUser(null);
}catch (Exception ex) {
if (ex.getCause() instanceof IllegalArgumentException) {
System.out.println("IllegalArgumentException : " + ex.getCause().getMessage());
}else {
ex.printStackTrace();
}
}
}
}

And here's the output of the EJB Container :

21:33:12,504 INFO [STDOUT] INIT
21:33:28,595 INFO [STDOUT] DESTROY

As you can see from the output of the session bean, When a RuntimeException thrown, the EJB Container destroys the bean instance from the bean bool !

07 January 2010

XPath normalize-space() doesn't just trim !

Yes, It is true, the normalize-space function do more just trimming your text.
so:

<xsl:value-of select=" ABC DEF G " />

Will return :
"AB DEF G"
So,Its real function is "Removes leading and trailing spaces from the specified string, and replaces all internal sequences of white space with one and returns the result"
So, be-careful when using it.

04 January 2010

Controlling your Java command line applications in much an increased performance way

As I am a GNU/Linux fanatic, and do not plan to switch M$ Windows nor in the near or far future, and unfortunately I haven't an Internet connection at home and because my native language is the Arabic so, I've decided to write an English-Arabic dictionary (I know there's already exists good one, but also for historical reasons :) ).

There is a great community called arabeyes that have a good file-based database of translated words , So I've decided to write a simple program that search in this file-based database and retrieve the matched word(s) for me.

This database is all about a 26 files each file for all words for an English character, as there's a file translating words starts with A, other for B and so on.

Really I didn't want to write a Java application from scratch ( Actually I've written on in the past but needn't to rewrite it again), So I decided to utilize some Perl script that do the search process.

Here's the Perl Script:

perl -n -e 'if (/^msgid\s+"(.*)"/) { print "$1 : "; } if (/^msgstr\s+"(.*)"/) { print "$1\n"; }' \
$WORDLIST/full_wordlist_*.po | grep -iw <word>

I'll not comment on this Perl script because I know about perl like a .NET developer's knowledge about Spring framework :)

So, I decided to put this script in a shell file and call it from Java as a process, here' the code for that:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.JOptionPane;

public class JDictionary {

public static void main(String[] args) throws IOException {

String dictionaryExeName = System.getProperty("dict.cmd");
Runtime r = Runtime.getRuntime();

String dictionaryFullCommand = "";

if (args.length >= 1) {
dictionaryFullCommand = dictionaryExeName + args[0];
}
System.out.println(dictionaryFullCommand);
Process p = r.exec(dictionaryFullCommand);

BufferedReader output = new BufferedReader(new InputStreamReader(p
.getInputStream()));

String line = "";
String result = "";
while ((line = output.readLine()) != null) {
result += line + "\n";
}

JOptionPane.showMessageDialog(null, result, "The Dictionary",
JOptionPane.INFORMATION_MESSAGE);
}
}

And I used to run this simple java class as :

java -Ddict.cmd=/path/to/perl/script <word>

I put the above command in a shell file and put it in my PATH and everything goes ok.
After a while, I became more uncomfortable with the performance of this app. Every time i need to know the meaning of a single word, I have to start the JVM !!, ohh bad idea.

So, I've decided to implement some pattern. It is not a Design pattern, but an implementation pattern.
It is a pattern for controlling you Java command line application that runs in the background ( really I captured the idea from my manager, and he told me that he captured the idea from one of Apache projects)

The idea is that, you will start you application in the background and make it accepts its input from a file and then you will pass it the controlling commands by inserting them in this file, so you application will run in the background, but you still control it.

So, I will write two components (classes), one to read the word that need to be translated from a file and pass it to the second component and then get blocked until the other component do its job, the other component will translate this word and show me the translated word and unblock the first component and block it self (the Producer/Consumer threading model).

Here's the class the will read from the file (note, I made it do regular file reading, not reading from its Standard input):

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class WordListener extends Thread {

private Word word;
private String oldStat;

public WordListener(Word word) {
this.word = word;
}

public void listenToWord() throws FileNotFoundException {
Scanner scanner = new Scanner(new FileInputStream("/home/mohammed/programs/dict/tmp"));
String str = scanner.nextLine();
if (str.equals(oldStat)) // to prevent it from translating the same word again
return;
word.put(str);
oldStat = str;
}

public void run() {
while (true)
try {
listenToWord();
sleep(1000); // for the processor's sake :)
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

And here's the class that do the translation:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.JOptionPane;


public class WordFinder extends Thread{

private Word word;

public WordFinder(Word word) {
this.word = word;
}

public void findWord() throws IOException{
String dictionaryExeName = System.getProperty("dict.cmd");
Runtime r = Runtime.getRuntime();

String dictionaryFullCommand = "";
while (true){
dictionaryFullCommand = dictionaryExeName + " " + word.get();
Process p = r.exec(dictionaryFullCommand);

BufferedReader output = new BufferedReader(new InputStreamReader(p
.getInputStream()));

String line = "";
String result = "";
while ((line = output.readLine()) != null) {
result += line + "\n";
}

JOptionPane.showMessageDialog(null, result, "The Dictionary", JOptionPane.INFORMATION_MESSAGE);
}
}

public void run() {
try {
findWord();
} catch (IOException e) {
e.printStackTrace();
}
}
}

And here's the Word class ( The sync'd buffer) :

public class Word {
private String content;
private boolean available = false;

public synchronized void put(String word) {
if (available == true ) {
try {
wait();
} catch (InterruptedException e) { }
}
this.content = word;
avaiable = true;
notifyAll();
}

public synchronized String get() {
if (available == false) {
try {
wait();
} catch (InterruptedException e) { }
}
available = false;
notifyAll();
return content;
}
}

and here's the main class :

public class JDictionary {

public static void main(String[] args) {
Word word = new Word();
WordListener wl = new WordListener(word);
WordFinder wf = new WordFinder(word);

wl.start();
wf.start();
}
}

Look, I'll not illustrate the producer/consumer model, for more info see Java tutorial at http://java.sun.com/tutorial

So, to start the Dictionary, I'll have to start the JVM just once by this command (I can make it a system daemon):

java -Ddict.cmd=/path/to/perl/script


and to translating words (Control the running Java program), I'll execute this command :

echo "<word>" > /home/mohammed/programs/dict/tmp

of course you could put the last line in a shell file like this:

#!/bin/sh
echo $1 > /home/mohammed/programs/dict/tmp

That's all.
Note that, The code above is a dirty code that need more clean up.

thanks.