EJB3 - Session Bean calling method of another bean

2019-07-19 10:08发布

问题:

I have a little question... I search the difference in local access between accessing a method that is only declared in the remote interface of a bean and not in the local interface...

does the interface declaration (remote or local) determine the access protocol of the method? or does the ejb container understand that both beans are running the same JVM? is there a big performance difference? Do you have any source about this?

BR's

Laurent

回答1:

I would suggest testing it on your EJB container to be sure.

That said, according to spec (here, section 3.2.3) @Remote interface must use by-value parameter passing, while @Local assumes by-reference parameter passing.

That means that even if both client and @Remote bean are on the same JVM there is an overhead of parameter copying.

It also means that all @Remote parameters must be Serializable.



回答2:

Yes, you are right that @Remote will always be slower than @Local because it always has more work to do.

The problem with exposing a bean's interface as both @Local and @Remote (and the reason the spec says it is rare) is that parameter and return value semantics are unclear. For example, if you have a method:

List filter(List arg);

...and if the bean implements this method by modifying the argument, then the client must be very careful to ensure to either copy the object before calling the method (@Local) or avoid wastefully copying the object if it will be done automatically (@Remote). Additionally, the bean must be careful not to hand out mutable state to its callers from the @Local interface. While the situation might be clear for List, it is might be less clear for questionable Serializables like java.util.Date or if the bean wants to return a "constant" array.



回答3:

So if i create a bean without local interface, any bean inside the same ejb container will be slowered by that overhead? therefore it is better to always declare a local interface if there will be local access even if this local interface is "just" a copy of the remote one.

Am I right?

that's strange because in the source you mention (JSR 220: Enterprise JavaBeansTM,Version 3.0 EJB Core Contracts and Requirements) "While it is possible to provide both a remote client view and a local client view for an enterprise bean, more typically only one or the other will be provided."



回答4:

I tried on my own pc, two interfaces (one local the other remote) with the same methods declared.

package calc; import javax.ejb.Remote;

@Remote public interface CalculatorRemote {

public int add(int a, int b);
public int sub(int a, int b);

}

In another bean I inject both interfaces and uses them:

@EJB
public CalculatorRemote myRemoteCalc;

@EJB
public CalculatorLocal myLocalCalc;
public String fastest(int iter){
    myRemoteCalc.add(5,6);
    myLocalCalc.add(5,6);

    long inittimeLocal=System.currentTimeMillis();
    for(int j = 0; j<iter; j++){
        myLocalCalc.sub(28, 26);
        myLocalCalc.add(134778, 1234);
    }
    long LocalTime=System.currentTimeMillis()-inittimeLocal;

    long inittimeRemote=System.currentTimeMillis();
    for(int i = 0; i<iter; i++){
        myRemoteCalc.sub(28, 26);
        myRemoteCalc.add(134778, 1234);
    }
    long RemoteTime=System.currentTimeMillis()-inittimeRemote;

    if(LocalTime>RemoteTime){
        return "Local slower than Remote " + (LocalTime-RemoteTime) + " ms difference with remote processing in "+ RemoteTime + "ms and local processing in"+ LocalTime + " ms. ";
    }
    return "Remote slower than Local " + (RemoteTime-LocalTime) + " ms difference with remote processing in "+ RemoteTime + "ms and local processing in"+ LocalTime + " ms. " ;
}

When I call the method fastest (used to determine which of the remote or local call is the fastest) the result gives at each time a time factor of 5 between the two access methods.

here are the outputs:

it gave the following output for 200000 iterations:

Remote slower than Local 46 015 ms difference with remote processing in 58 609 ms and local processing in 12 594 ms.

and the following output for 100000 iterations: Remote slower than Local 23 406 ms difference with remote processing in 29 609ms and local processing in 6 203 ms.

and the following output for 1000

Remote slower than Local 219 ms difference with remote processing in 297ms and local processing in78 ms.

that's quite strange that SUN nearly advises us to use only one type of interface in the source of Gregory at the end of the section he refers to: While it is possible to provide both a remote client view and a local client view for an enterprise bean, more typically only one or the other will be provided.

in this case, with only remote access, the calls will be slow and noone would get the advantages of local fast-access.

I think that any bean should have a local interface which includes the methods of the remote interface. The remote interface methods would be a subset of the local interface methods. with this we are sure that remote clients are served on a normal way while local ones are served on a fast way.

Do they tell that only to encourage us to provide different beans for internal and external stuff? or is it because in more complex methods local and remote access will differ greatly?