Friday, November 28, 2014

Calling Stateless Application EJB JARs From Plain Java Code

The stateless application jar is compiled with ejb api. But the invoker should not need the ejb api jars if it can avoid triggering ejb related code, or can it? We have a application for intensive computing farm for intra-red-EM-wave photoresonator calculation of quartz business Precidio Inc. ,


The precidio-jndi-calc.jar has this,
import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless
@Remote(RemoteCalculator.class)
public class ResonatorCalculatorBean implements RemoteResonatorCalculator {

    @Override
    public int add(int a, int b) {
        return a + b + 111;
    }

    @Override
    public int subtract(int a, int b) {
        return Math.abs(a - b) - 11;
    }
}
, and we should be able to -cp precidio-calc.jar , instantiate ResonatorCalculatorBean, and run the add command. This is the essence of EJB.

What is the problem, then, when -cp precidio-calc.jar ? 

[root@android01 ~]# cat UseEjb.java 

import CalculatorBean;

public class UseEjb {

public static void main (String [] args) {

System.out.println("ok");

CalculatorBean cb = new CalculatorBean();

System.out.println(cb.add ( 1, 2));

}

[root@android01 ~]# javac -cp precidio-jndi-calc/build/precidio-calc.jar UseEjb.java
UseEjb.java:1: error: '.' expected
import CalculatorBean;
                     ^
UseEjb.java:1: error: ';' expected
import CalculatorBean;
                      ^
2 errors
[root@android01 ~]#
Why? Non-packaged classes can not be imported. Instead, use it without importing it,
[root@android01 ~]# cat UseEjb.java 
public class UseEjb {
public static void main (String [] args) {
System.out.println("ok");
CalculatorBean cb = new CalculatorBean();
System.out.println(cb.add ( 1, 2));
}
[root@android01 ~]# javac -cp precidio-jndi-calc/build/precidio-calc.jar UseEjb.java
jndi.new/build/john-calc.jar(CalculatorBean.class): warning: Cannot find annotation method 'value()' in type 'Remote': class file for javax.ejb.Remote not found
1 warning
[root@android01 ~]# java -cp precidio-jndi-calc/build/precidio-calc.jar:. UseEjb
ok
3
[root@android01 ~]#java -cp precidio-jndi-calc/build/precidio-calc.jar UseEjb
Error: Could not find or load main class UseEjb
[root@android01 ~]# 

As predicted, as long as the invoker don't touch EJB specific workings, the regular java interpreter can invoke ejb jar without incident. It has a warning at compile time.

This exercise actually exposes the defect of java cp. The cp actually disturbs the java interpreter's original work path. Original java interpreter looks at current working directory in search for a class file, UseEjb in this case. So, simple java UseEjb does not have error of "Cloud not find" UseEjb. When -cp argument is in, it erases the default looking at current working directory.

No comments:

Post a Comment