Pass by reference only kicks in when the two EJBs (or
servlet and
ejb) are in the same "deployment unit".
So if you deploy two separate ejb-jars they will not normally pass-by-reference. If you put your ejbs in one jar or assemble the two ejb jars into an enterprise app (ear) then you will get pass-by-reference.
What's going on is:
Each thing you deploy is turned into an enterprise app if it is not already (look in config.xml and you'll see an Application element wrapping each one).
Each application has its own ClassLoader. So if you have two classes (like the Remote interface or some serializable parameter object) there will actually be two versions of these classes loaded - one by each ClassLoader.
Now when WLS goes to make a "local" (same VM) call on a Remote interface, it checks if both ends know about the same classes. If not, it has to Serialize no matter the setting of pass-by-reference.
If it did not, you would get ClassCastExceptions because even though the classes have the identical name, the instance of the class object loaded by different ClassLoaders is different, thus they are actually different classes to the VM.
So the two ways to fix this are:
Deploy everything you want to pass-by-reference in the same
unit - assemble into ear or into one ejb-jar.
Or put all your classes in the system CLASSPATH. This defeats hot-deploy, and goes against the spirit of J2EE and deployable components - so I don't recommend it. But since all classes will be loaded by the system ClassLoader, WLS will see that serialization is not necessary.
The exact same conditions apply to EJB Local interfaces - they can only be used within the same application.