In IAS, when you say
prompt% vbj com.inprise.ejb.Container ejbcontainer beans.jar -jns -jts –jss -jdb
it is a simplified view of the above where what you launch is a Container that itself starts up in-process the generic services.
You can logically think of this as a Server with 4 generic services (in same address space) with a 5th "special" service - EJB Container - that hosts your beans in beans.jar.
In contrast when you do
% vbj com.inprise.ejb.Container NS -jns
% vbj com.inprise.ejb.Container TS -jts
% vbj com.inprise.ejb.Container DB -jdb
% vbj com.inprise.ejb.Container ejbcontainer beans.jar
% vbj com.inprise.ejb.Container ejbcontainer beans.jar
You now have exactly same application with a vastly distributed execution structure. Now your "EJB Server" is a logical collection of generic services and a replicated Container (for fault tolerance and load balancing)
There is no easy way to satisfy all these camps. So we designed our Container and services to be flexible. You can start an EJB Container like you start any Java program or you can trigger it from a Console where the backend Server kicks the Container up. You can trivially turn on a few flags like -jns -jts to make the Container VM also host the services required by your EJBs or you can have the services run under the auspices of IAS Server with greater control on their lifecycle and properties. Basically we allow users to do what suits their needs at various points in application deveopment.
-jts starts a Container resident lightweight one-phase capable JTS service. Turning on the Transaction Service in the AppServer daemon starts a full two-phase transaction manager.
-jns starts a CosNaming service in the Container process that does not persist its data and uses all default configuration parameters of the VBJ4 Naming Service. Using the AppServer counterpart you can configure it more flexibly but functionally it is equivalent in the sense that they are both exactly the same service.
-jss is the Container’s state repository for stateful session beans. There is no conterpart of this under AppServer.
-jdb starts an inprocess RDBMS. The jdatastore service in the AppServer daemon is functionally equivalent.
Bottomline: The Container builtin services are developer friendly incarnations of services that are functionally complete and equivalent. The difference is in configuration and lifecycle control.
Running the naming service in or out of process will have a negligible performance hit on applications which make little use of naming. Thus, a typical bean which only has its home registered in JNDI at startup will see little difference. However, if that same bean needs to lookup a JNDI name as part of its business logic, then the performance hit will be substantial. (Of course, you should be running only a single naming service per deployment, otherwise each instance of the naming service will contain only a portion of the named objects. Thus, if you run multiple containers, only one will be able to have the naming service in process.)
In general, it is best to always run the JTS in process, as this is heavily used. JNS can generally be run out of process with little impact. JDB should run in process, assuming you make much use of entities (and you are storing then in JDataStore, otherwise there is no need for the -jdb flag in the first place). Finally, JSS could be run out of process, if EJBPassivationTimeout is fairly large, so the container is not continuously doing RPCs to passivate/activate stateful session beans. However, it is likely that you would best run it in process.
So, the EJB server allows multiple containers (each in a separate VM), and each container allows multiple EJBeans (all in a single or separate Jar files).
Probably, you want to run only one or two containers per box. If the box is a multi-processor, you might run as many containers as you have CPUs and that should give good performance.
Absolutely, you will want cooperating beans collocated in the same container. Typically, these would even be in the same Jar. You also would want to collocate the beans which access the same database, to minimize the number of DB connections, which are a scarce resource.
In summary, look to have about a 1:1 ratio between CPUs and containers. At most, a 2:1 ratio. This will probably mean collocating many Jars into the same containers.
package myPackage;
public class EJBContainerDebugger {
public static void main(String[] args) {
try {
String[] newArgs = {"ejbcontainer", "beans.jar", "-jts", "-jns"};
System.getProperties().put(“EJBNoClassLoader”);
// apparently JB doesn’t work well with breakpoints
// if custom classloading is used
com.inprise.ejb.Container.main(newArgs);
} catch (Exception x) {
x.printStackTrace();
}
}
}
Set any breakpoints in any beans that you have, and run this project in Debug mode. Be sure to set up any -
D parameters in the Project Parameters section. You can also place any command line arguments there as
well, in lieu of the way hardcoded above. The server should be running in debug mode.
Now run the client from another project. When the client invokes a call to a
bean where you have set a breakpoint, execution will stop and you can debug
like normal.
public class Shell {
public static void main(String[] args) throws Exception {
// do your startup stuff here...
com.inprise.ejb.Container.main(args);
}
}
This will allow you to startup services within the shell.
You can insert code before the EJBs are initialized, and you can insert code after afterward, but you cannot guarantee that the insertion happens before a client request comes in.
In summary, here are the points where you can insert your code:
main() {
// insert code here
"start the container and any services, but no beans"
// insert code here
"add a Jar file of EJBs"
// insert code here
"add another Jar file of EJBs"
// etc.
}
orb = (org.omg.CORBA.ORB) context.lookup("java:comp/ORB");