It is possible to deploy EJB components without setting security constraints. The default security for a method is "unchecked" which means that no checks are made by the container and this will allow all clients to invoke it.
Is it possible for a bean to use a service or a library?
Yes, it is possible. You must specify a reference from the application to that component in order to have a reference between the class loaders. This could be done in the application-j2ee-engine.xml or after deploying the application by the changeref command of the deploy service. If you want to use an object from JNDI (e.g. bound by a service) you must specify a reference to it in the ejb-j2ee-engine.xml
Can I start a thread from a bean?
No, according to the Enterprise JavaBeans 2.0 Specification (Appendix C EJB 1.1 Runtime Environment) thread management is performed by the EJB Container and Enterprise Beans must not attempt to manage threads, which includes starting, stopping, suspending, or resuming a thread; or changing a thread's priority or name. Enterprise Beans must not attempt to manage thread groups either. These requirements ensure that the Container properly manages the runtime environment.
What happens if the same bean is accessed concurrently from several clients?
For session beans the usual client behavior must be to create its own session object (by any of the Home interface's create methods), use it and then remove it. Sharing the session object between clients and transactions may cause problems. Here are some details :
- Stateless session beans: Each client accessing a session object gets a pooled bean instance for each request. Concurrent access makes no problem.
- Stateful session beans: If a second client tries to use the same EJBObject (that is uses the same session) he/she will get an exception. If the stateful bean has container managed transactions, the instance is "associated" with a transaction. That means that if a transaction T1 calls a business method, no other transaction is allowed to invoke this instance till the end of T1.
- Entity beans: The entity container is common for BMP and CMP and uses Commit option C (EJB2.0 Chapter 10.5.9). That means that for every transaction that uses a bean instance (representing a certain persistent entity) there is a copy of the instance. Concurrent access to the persistent data is managed by locking mechanisms. For BMP entity beans the bean provider is responsible for locking, whereas for CMP entity beans the EJB Container manages the concurrent access. It uses either the Enque server or the database locking mechanisms.
start_app: First, the files that are needed by the container during start (i.e. jar files and other configuration stuff) are downloaded from the DB. Then the descriptors for the application are built and they are used to create the naming contexts for each bean. After that the specific EJB class loader for the application is created and registered, the containers for each EJB are initialized and their EJBHomes and/or EJBLocalHomes are bound to JNDI. Persistence Managers for the CMP entity beans are created and initialized. Finally, the pools for stateless, entity, and message-driven beans are initialized. The default initial pool size is 0 - this means that no instances will be created (and respectively no setSessionContext/setEntityContext/setMessageDrivenContext wil be invoked) at start time. If you wish, you can specify the initial pool size in your ejb-j2ee-engine.xml, like this:
MyStatelessBean InitialSize 10
stop_app: First, the EJBHomes and/or EJBLocalHomes are unbound from JNDI and all EJB naming contexts are destroyed. Then the containers and pools for each EJB are destroyed too. Finally, the EJB class loader for the application is unregistered.
May I deploy the Web components as EAR1 and the corresponding EJB components as EAR2?
Although this scenario is not described in the specification, it is really commonly used and has to be supported. In this case, the dynamically generated P4 stubs are used. If you have the interfaces of the bean in the servlet's ear then there must be also all other helper classes - return types, parameters, exceptions (a common issue is that the EJBObject class can not be loaded and the most probable reason is this). The other possibility is not to have the bean's interfaces in the servlet's ear. Then you should have a reference between the applications. But don't use reference if you already have the interfaces :) This may cause a ClassCastException.
How are the bean instances/EJBObject/EJBHome objects distributed in the cluster environment? Does the client still access the same cluster node?
Every bean component deployed on the J2EE Engine is loaded on every server node of the cluster.
Bean instances (i.e. instances of the bean class) live in every server node.
The distribution of the remote EJBHome and EJBObjects is managed by the remote protocol (the default one for the J2EE Engine is P4). When a remote object is created on a server node the P4 protocol manages a connection from the client to that object. That means that the client is always connected to a certain server node.
What happens if the server node to which the client is connected crashes? Is there a failover mechanism?
If the server node to which the client is connected crashes, the remote protocol redirects the call to another server node where a new remote object will process the subsequent client calls. The failover mechanism is different for the diffenrent types of beans:
- Stateless session beans have no state and their failover is implemented only by redirecting the call to another server node.
- Stateful failover serializes stateful bean instances in a persistent storage (the file system or the system database). Thus the last state of the session is replicated.
- Entity beans are persisted in the database and that's why they are synchronized with the consistent data in the database. The entities are locked in the Enque server and then loaded from the database. If a server crashes during an entity bean update, the transaction will be considered as invalid. The next request to the same entity will be dispatched to a working server and the last committed state will be loaded from the database.
Should I clear/reinitialize bean's fields inside ejbPassivate/ejbActivate?
Stateful session- and entity beans: For minimizing the jndi lookups, my bean looks up some references (jndi context root, ejbHome of related beans, a datasource object, UserTransaction object) inside setSessionContext/setEntityContext (or ejbCreate) and it stores it locally into private fields.
Should they make the lookups again inside ejbActivate() and should they set the references to null inside ejbPassivate()?
Stateful sessions can keep references to some not serializable object after ejbPassivate() (EJB2.0 Chapter 7.4.1). These objects are jndi contexts - the root or any of its subcontexts; UserTransaction object, SessionContext object; EJBHome, EJBObject, EJBLocalHome, EJBLocalObject references. These references may not be set to null in ejbPassivate and that means not to be initialized again in ejbActivate. The opposite applies accordingly for any kind of resources and resource factories - data sources, connections, sockets, etc.
For entity beans it is quite different. After ejbPassivate() is called to a bean it applies a 'passive' state. The passive instances are kept in a pool and are used for finder methods execution. That means that they may have any kind of references - data sources, connections, etc. We recommend not to keep open connections in a passive instance because this may cause problems (like never releasing the connections).
Do references to plain Java classes survive the passivation/activation - ( e.g. I use dao class instances)
Yes, but the classes must implement java.io.Serializable (again EJB2.0 Chapter 7.4.1)
Should EJB instances set their references to null inside ejbRemove (for clean up)?
After ejbRemove() entity beans go in a 'passive' state, and just like in ejbPassivate, there is no reason to set their references to null, but it's a good idea if they close all open connections. Session beans stop their existence after ejbRemove(), so they MUST close all open resources. The ejb instances will be garbage collected so there is no need to set their references to null, but if an open resource remains it may never be released.
Should I call remove() to a session bean in order to clean up the associated EJBObjects (stub/skeleton)?
For stateless session beans it makes no sense to invoke the remove() method as this does not trigger the invoking of the ejbRemove() method on any bean instance.
For stateful session beans cleaning up EJBObjects is important as they are remote objects and cleaning them means removing all proxy objects that are used by the remote protocols. The stateful session beans' remove() method triggers invoking the ejbRemove() method on the corresponding bean instance. That is why invoking it is important if there is a specific business logic implemented in the bean's ejbRemove() method. Otherwise (if the session bean's client hasn't explicit reason to invoke remove) it may omit it. For these cases the session container has a timeout for the active sessions (active means EJBObjects/EJBLocalObject that are obtained by a home's create method and are not removed). If such sessions are not used for a specified period they are removed and the container cleans up all related objects. To avoid keeping objects that are not used on the server for a long time, it is a good design for the applications to invoke remove() always when they are able to do it.
Is the stateful bean the better choice than stateless because of the possibility of utilizing the SessionSynchronization interface?
The answer is no, it is not possible to claim that the one kind is better than the other. They are just different and it depends on the application design which of them is more suitable. SessionSynchronization interface is useless for stateless sessions because the instances are not associated with the session - they are stateless. That means that different methods in the same session (through the same EJBObject) could be (and most probable are) invoked on different instances so they must not keep any information between method calls.
6.30 stateful session beans: How does the passivation/activation work?
The EJB Container uses the LRU (least recently used) algorithm for choosing which stateful session bean instances to be passivated. The instances are serialized and written into a persistent storage (the file system or the system database).
Is there a performance difference between stateful and stateless session beans?
Until SP4 the differences in the implementation were not big. Therefore, we do not expect a significant difference in the performance.
Since SP5 the remote communication for stateless session beans is changed in a way that only one remote object is used for all EJBObjects. This makes the create methods very fast as they are executed only on the client side without executing a remote call.
What is the performance of CMP- versus BMP entity beans with 6.30?
When CMP entity beans can be used, they have proved to be faster than BMP beans. However, the results may vary and depend on the application and its behavior with the persistent data. According to our measurements with the SPECjAppServer 2003 benchmark:
CMP beans are more scalable than BMP beans. On the same configuration, the CMP version of the benchmark application processes the requests of 50% more clients than the BMP version.
The response times for the different transactions with CMP are between 20% and 100% better the response times with BMP.
The life-cycle management of the entity beans is the same for BMP and CMP. The better performance is due to optimizations in the persistence management.
Entity beans: At which point of time will ejbLoad/ejbStore be called?
ejbLoad: before a first method call inside a new transaction.
ejbStore: prior to transaction's commit - beforeCompletion() method of javax.transaction.Synchronization interface (JTA) is used. In addition, for CMP, ejbStore is called before finder methods: the updated data is flushed into the database (for performance reasons this is optional - there is a tag "switch-off-storing" in persistent.xml). The special thought here is that storing before finder methods is not specified for BMP, but if a transaction has accessed both BMP and CMP beans and after that it calls a CMP finder method, then ejbStore will be called for all BMP and CMP beans.
What is the "n+1 finder problem" ?
Entity beans by default force you to first load a collection of keys for the dataset you want to access and then go through this set and get the data records key by key. This results in n+1 round trips to the database, where "n" is the number of records needed.
Does the 6.30 container cache the whole entities after a finder method call? How can the "n+1 finder problem" be avoided?
a. For CMP?
With the default configuration only primary keys are loaded. When a single entity is accessed, it is loaded and locked regarding the transaction's isolation level. The "n+1 finder problem" can be avoided be specifying the load-selected-objects property for the corresponding finder method. Then the whole entities will be loaded in the finder method and will be cached until the end of the transaction.
b. For BMP?
Finder methods are implemented by the bean provider. The EJB Container extracts only the primary keys of the selected entities. Each entity is loaded on demand ? the first time it is accessed. The architecture does not allow the EJB Container to implement any caching and thus to solve the "n+1 finder problem".
May I avoid the "n+1 finder problem" using ejbHome methods instead of ejbFind methods?
Yes. ejbHome methods can be used for operations like increaseAllSallaries(). This is done instead of invoking a finder method and then using business methods on every single instance of the resulting data. With BMP this whole operation can be made with a single query and is the only way to avoid the "n+1 finder problem".
CMP Entity beans: Which kind of data source has to be used: Open SQL/Native SQL/Vendor SQL?
All stated possibilities are allowed.
What is the difference between Open SQL/Native SQL/Vendor SQL?
The three modi are adjusted from the administrator for the engine for every datasource. It defines whether this datasource is using SAP persistence level Open SQL or something in between.
1. Open SQL: You will have full support of the SAP persistence level. This means that SQL requests have to be written in Open SQL grammar, thus ensuring they will run with all DB's supported by SAP. You can use statement cache, SQL trace and the table buffer. Buffering tables has to be configured in.
2. Native SQL: You don't use Open SQL, but parts of the persistence level, that allows you to use the statement cache and SQL trace.
3. Vendor SQL: You are on plain JDBC using the vendor specific driver. No special support for persistence features. You still benefit from serverside connection pooling and transaction management service.
Should I lock the table/entity explicitly when implementing persistence using EJB components?
If using: - session beans - entity bean with BMP - entity beans with CMP?
Answer: When you use session beans or BMP you have to make explicit locking - the bean provider is responsible for the synchronization.
For CMP the synchronization is managed by the Persistence Manager, so the application must not do any kind of locking
If I have to lock do I use the Enque Server interfaces?
All applications that use common persistent data must use the same locking mechanism in order to synchronize their access to the data. Therefore, it depends on whether your persistent data can be accessed by other applications and what locking mechanism they use. If they use the database locking mechanisms you must also use them. If they use the Enque server locking, you must also use it. The EJB Container provides both options for CMP entity beans.
If you use the Enque server locking you must do it by the TableLocking API from the applocking service.
CMP: How does the EJB Container (Persistence Manager) manage the locking?
Persistence Manager uses only pessimistic concurrency control based on different isolation levels and locking in Enque server or in the database. If you have a read-only CMP bean it is better to specify this when describing its O/R mapping in persistent.xml descriptor. Thus you will escape any locking for that bean and will increase the performance.
Which kind of transaction should my EJB bean use: local(JDBC) or global(JTA)?
At best, EJB beans should not start end-to-end transactions explicitly at all. They rather should use the container-managed transaction demarcation and rely on the transaction management done by the EJB Container. Entity beans must use the container-managed transaction demarcation. If you need the explicite (bean-managed) transaction demarcation for a session bean, only JTA transactions must be used.
What is the default transaction attribute for container-managed transaction demarcation?
It is possible to deploy EJB components with container-managed transaction management without having set the transaction attributes for metods.
The default transaction attribute is :
"Supports" for session which means,
a. if a client is part of a transaction: the call is executed in the same transaction;
b. if a client has no transaction: the call is executed without a transaction context.
"Required" for entity beans which means,
a. if a client is part of a transaction: the call is executed in the same transaction;
b. if a client has no transaction: a new transaction is started for executing the call.
"Not Supported" for message-driven beans which means the call will be executed without a transaction context
(BMP) Entity beans: During JTA transaction commit the method ejbPassivate() is called. Why ?
Our EJB Container uses the 'Commit option C', i.e. it associates an active bean instance with a JTA transaction. At the end of the transaction ejbStore() method is invoked and the instance is passivated (returned to the pool). Before passivating an instance, the EJB Container has to call the method ejbPassivate().
When should I use a plain Java RMI client? Which libraries does a Java RMI client need?
A plain Java RMI client is very convenient for small EJB components testing purposes. However, there is no specification for such an RMI client and it may not work correctly in certain situations, e.g. it cannot manage transactions. With regard to J2EE the only possible clients of an EJB bean are appclients, Web components, and other EJBs.
In order to access the EJB components an RMI client needs the libraries:
The ejb-client jar of your deployed EJB application. You can retrieve it either through the runtime view of deploy service in Visual Admin, or through the command shell on the server (using the command CLIENTJARS from DEPLOY group).
The SAPJ2EEEngineClient.jar library as provided inside the Engine's build procedure.
No comments:
Post a Comment