Professional Documents
Culture Documents
0
document edited by marco tedone
jemos group (www.jemos.co.uk)
for comments and suggestions please email: mtedone@jemos.co.uk
-------------------------------------------------
/******************************************************************
* i n t e r f a c e s *
******************************************************************/
1) ejbhome interface
a) ejbmetadata getejbmetadata();
b) homehandle gethomehandle();
c) void remove(handle h);
d) void remove(object key);
2) ejblocalhome interface
3) ejbobject interface
a) object getprimarykey();
b) ejbhome getejbhome();
c) handle gethandle();
d) void remove();
e) boolean isidentical();
4) ejblocalobject interface
a) object getprimarykey();
b) ejblocalhome getejblocalhome();
c) void remove();
d) boolean isidentical();
5) sessioncontext interface
6) entitycontext interface
7) messagedrivencontext interface
8) sessionbean interface
a) void ejbactivate();
b) void ejbpassivate();
c) void ejbremove();
d) void setsessioncontext(sessioncontext ctx);
9) entitybean interface
a) void ejbactivate();
b) void ejbpassivate();
c) void ejbremove();
d) void setentitycontext(entitycontext ctx);
e) void unsetentitycontext();
f) void ejbload();
g) void ejbstore();
a) void ejbremove();
b) void setmessagedrivecontext(messagedrivencontext ctx);
a) onmessage(message m);
a) void begin()
b) void commit()
c) int getstatus()
d) void rollback()
e) setrollbackonly()
f) settransactiontimeout()
a) void afterbegin()
b) void beforecompletion()
c) aftercompletion(boolean committed)
/******************************************************************
* b e a n t h i n g s i n l i f e c y c l e *
******************************************************************/
9) bean things that can be done in the various lifecycle moments for:
a1) setsessioncontext()
b1) setsessioncontext()
c) entity beans
c1) setentitycontext()
c2) ejbcreate()
/******************************************************************
* t r a n s a c t i o n a t t r i b u t e s *
* *
* d e m a r c a t i o n f o r c m t b e a n s *
******************************************************************/
s e s s i o n b e a n s :
----------------------------
e n t i t y b e a n s :
----------------------------
3) all the home business methods written by the bean's developer in the bean's
home interface
/******************************************************************
* u n s p e c i f i e d t r a n s a c t i o n *
* *
* c o n t e x t f o r c m t b e a n s *
******************************************************************/
the container decides what to do, and we have simply to deal with it.
1) all methods which have been marked with one of the following transaction
attributes:
a) notsupported
b) never
c) supports
a) ejbcreate()
b) ejbremove()
c) ejbactivate()
d) ejbpassivate()
a) ejbcreate
b) ejbremove
/******************************************************************
* e x c e p t i o n s *
******************************************************************/
1) what happens when a bean (or the container) throws an application exception?
2) what happens when a bean (or the container) throws a system exception?
1a) the container throws to the client an ejbexception (if the client is local)
or a remoteexception (if the client is remote)
a) createexception
b) removeexception
c) finderexception
d) objectnotfoundexception
e) duplicatekeyexception
+---------------------------------------+
+ +
+ e x c e p t i o n p a c k a g e s +
+ +
+ a n d m o s t c o m m o n +
+ +
+ u s e s +
+---------------------------------------+
/*********************************************************************************
********
* e x c e p t i o n s r e s p o n s i b i l i t i e s
*
**********************************************************************************
********/
+-------------------------------------+
+ +
+ b e a n d e v e l o p e r +
+ +
+-------------------------------------+
remember: the way the bean developer has to let the application propagating
to the container is by declaring it in the method signature
3) if a bean's method (or a method in a class the bean interacts with), checks
an application exception that the client didn't expect (i.e. the bean couldn't
get a jdbc connection to the database), the bean developer should wrap the
application exception in an ejbexception (unchecked), passing the checked
exception as argument. the reason is that the client most probably doesn't
want to know the problems related to the internal bean state, and if it does,
can always invoke the getcause() method on the received exception.
try {
int a = 5 / 0
catch(exception e) {}
bottom line: catching 'exception' means that runtimeexception (s) will not be
propagated to the container. as a client, would you be happy if
your business logic would have continued in the above situation?
i wouldn't! catching 'exception' is usually a shortcut for lazy
programmers. there is nothing wrong in a programmer being lazy,
but
the business logic should be preserved, otherwise there will be
only lazy unemployed!
+-------------------------------------+
+ +
+ c o n t a i n e r +
+ +
+-------------------------------------+
**************************************************
* cmt entity/session beans business methods *
**************************************************
business methods for entity and session beans are all the methods defined in the
bean's component and home interfaces (and all superinterfaces), plus the
following
methods: ejbcreate<method>, ejbpostcreate<method>, ejbremove(), ejbhome(),
ejbfind()
*********************************************************************************
**********
* 1st scenario (cmt): invoked method runs in the same transaction context as the
invoker; *
*********************************************************************************
**********
this may happen if the cmt bean has got one of the following <trans-attribute>
values:
a) required
b) mandatory
c) supports
+-------------------+
+--------------+
+ container + + client
+
+-------------------+
+--------------+
+-------------------+
+--------------+
+ container + + client
+
+-------------------+
+--------------+
please note the package difference between the remote and local exception:
remote: javax.transaction.transactionrolledbackexception
-----------
local: javax.ejb.transactionrolledbacklocalexception
--- -----
**********************************************************************************
*********
* 2nd scenario (cmt): invoked method runs in a transaction context started by the
*
* container immediately before invoking the method
*
**********************************************************************************
*********
this may happen if the cmt bean has got one of the following <trans-attribute>
values:
a) required
b) requiresnew
+-------------------+
+--------------+
+ container + + client
+
+-------------------+
+--------------+
+-------------------+
+--------------+
+ container + + client
+
+-------------------+
+--------------+
+-------------------+
+--------------+
+ container + + client
+
+-------------------+
+--------------+
bottom line:
------------
if the container didn't start the transaction, it can only mark the transaction
for
rollback, and throw a javax.transaction.transactionrolledbackexception to
remote
clients of a javax.ejb.transactionrolledbacklocalexception to local clients.
if the container did start the transaction, it can rollback it and will throw
remoteexception to remote clients, ejbexception to local clients.
a) required
b) mandatory
c) supports
may leed to a bean's method running in the same transaction context of its
caller. in this
scenario, because the container didn't start a transaction, in case of a non-
application
exception, the container will only be capable of 'indicating' to the client
a rolling back situation.
a) required
b) requiresnew
may leed to the container starting (and therefore being the owner) the
transaction, therefore
in the eventuality of a non-application exception, the container will be
entitled to roll-back
the transaction, and to throw the equivalent of a runtime exception to the
bean's client. this
will be a remoteexception for remote clients, and an ejbexception for local
clients.
**********************************************************************************
*********
* 3rd scenario (cmt): bean's method run in an unspecified transaction context
*
**********************************************************************************
*********
this may happen if the cmt bean has got one of the following <trans-attribute>
values:
a) notsupported
b) never
c) supports
+-------------------+
+--------------+
+ container + + client
+
+-------------------+
+--------------+
**************************************************
**********************************************************************************
*********
* 1st scenario (bmt): session beans
*
**********************************************************************************
*********
+-------------------+
+--------------+
+ container + + client
+
+-------------------+
+--------------+
+-------------------+
+--------------+
+ container + + client
+
+-------------------+
+--------------+
1) logs the exception 1) receives
remoteexception if remote
2) discards the bean instance 2) receives
ejbexception if local
3) marks the transaction for rollback
4) throws a remoteexception to remote clients
5) throws an ejbexception to local clients
why the container here marks 'only' the transaction for rollback? because with
bmt, is the bean
instance which is supposed to start and end the transaction (with
usertransaction.begin() and
usertransaction.commit() or rollback() ).
the container can't substitute itself to the bean's developer (thus, it can't
rollback the
transaction), but it can mark it for rollback so to be a good 'transaction
citizen'. additionally,
it will throw the equivalent of a runtime exception to the bean clients, which
therefore will
know that something 'unexpected' happened on the server.
*********************************
* cmt message-driven beans *
*********************************
**********************************************************************************
*********
* 1st scenario (mdb): the bean's method runs in a transaction context started by
the *
* container
*
**********************************************************************************
*********
+-------------------+
+ container +
+-------------------+
this may happen if the onmessage() bean method runs with the notsupported
transaction attribute
and for ejbcreate() and ejbremove()
+-------------------+
+ container +
+-------------------+
*********************************
* bmt message-driven beans *
*********************************
+-------------------+
+ container +
+-------------------+
*********************************
* container callbacks methods *
*********************************
these are:
the container must handle all the exceptions (application and non-
application) as follows:
******************************************
* javax.ejb.nosuchentityexception
*
* javax.ejb.ejbexception
*
* java.rmi.nosuchobjectexception
*
*
javax.ejb.nosuchobjectlocalexception *
******************************************
in this case, the container should apply the same rules as ejbexception, because
nosuchentityexception
is a subclass of ejbexception. however...the container should throw:
therefore we could assume that, any time a client (which could be also another
bean), tries to 'use'
an object which is not there (most probably because it was removed), the following
exceptions will
be thrown:
************************************
* container and cmt transactions *
************************************
if the container (we are talking about internal container behaviours here), fails
to start or
commit (or rollback) a transaction, for session and entity beans it should throw a
remoteexception
to remote clients, and an ejbexception to local clients.
in case of message-driven beans, and in the above situation, the container should
throw a
javax.ejb.ejbexception
/*********************************************************************************
********
* r o l e s r e s p o n s i b i l i t i e s
*
**********************************************************************************
********/
each bean is given a special jndi environment, which it can access during its
lifecycle.
the special jndi environment is guaranteed as key features for each ejb 2.0
compliant
container and is identified by the 'java:comp/env' jndi subcontext, root from
which
every enterprise bean will start looking for resources.
1) environment entries
the bean developer, additionally, may want to use programmatic security from
within the
bean; for this purpose, she will tipically use the
ejbcontext.iscallerinrole(string s) method
to change bean's behaviour depending on a specific role. this approach can be
necessary when
ejb security must be granted as an 'instance' level, rather than at a 'class'
level. the problem
here is that with declarative security (security roles, method permissions,
responsibilities of
the application assembler) all the instances of a certain bean will face the same
security policy.
if the business logic needs to customize the bean's behaviour depending on a
certain role or the
matching of a principal name against some bean instance variables, the bean
developer needs to
'hard code' some names into the bean class. the same happens for all the four
above mentioned
activities: the bean provider needs to hard code n a m e s into the bean class.
if you're
thinking as a bean developer, and you're hard coding names within your bean class,
you will come
first or later to face a problem: because the bean developer doesn't know
(following the specs,
and not the real case, where most of the time will be the opposite) the target
environment where
the bean will run, and on the other side he has to make its application working,
to ensure the
component model offered by ejbs, the bean developer needs a way to communicate to
the people
who will take responsibility of the ejb application at assembly and deployment
time which names
she used from within the bean class in order to:
1) query the container about a principal's identity
2) query the container about a principal's permission
3) lookup for environment entries
4) lookup for resource manager connection factories
5) lookup for other enterprise javabeans
6) lookup for resource environment entries
because the engineers at sun are cleverer than one would've thought, they thought
of the
deployment descriptor as a means of communication between:
1) the bean developer thinks: 'ok, i had to use some fake names from within my
bean, otherwise
i could never deliver to you my bean. i will tell you which names i've used in
the deployment
descriptor.
2) the application assembler and the bean deployer think: 'all right. i see you've
used some
fake names: i will simply map those names to something that really exists in
the application
so that the bean will be ready for the operational environment
therefore:
b e a n d e p l o y e r
here follows a brief explanation of the dd elements related to the six points
mentioned above
and the responsibilities for bean developer, application assembler, bean deployer.
+---------------------------------------------------------------------------+
+ p r o g r a m m a t i c s e c u r i t y +
+---------------------------------------------------------------------------+
roles involved: bd and aa
--------------------------
or
while for case a), the bd could compare the principal name to some instance
variable containing some hard coded value, for case b the bd could write
something as follows:
if (ctx.iscallerinrole("agenericadmin")) {
//raise all wages by 10%
}
<security-role-ref>
the aa, would look at the <security-role-ref> element of the dd and would think:
'ok, the bean developer used 'agenericadmin' as a security role, but for the
business
domain in which the application will run, i chose to use only a 'superadmin' role
for
activities of this kind. no worries: i'll link 'agenericadmin' to 'superadmin',
which
i've defined in the <assembly-descriptor> section of the dd, in the <security-
role>
element.
<ejb-jar>
<enterprise-beans>
<session>
..
..
<security-role-ref>
<assembly-descriptor>
<security-role>
<description>the superadmin role is the only role who can make changes
to monetary values.
</description>
<role-name>superadmin</role-name>
</security-role>
</assembly-descriptor>
</ejb-jar>
+---------------------------------------------------------------------------+
+ u s i n g e n v i r o n m e n t e n t r i e s +
+---------------------------------------------------------------------------+
<ejb-jar>
<enterprise-beans>
<session>
..
..
<env-entry>
</env-entry>
</session>
</enterprise-beans>
</ejb-jar>
aa (or dpy) will think: 'ah, look at bd! he used a parameter called 'bonusrate' to
inform the bean about our bonus percentage to the agents. let me change the
<env-entry-value> to at least...let me see....5 percent. should our agents see the
dd now, i would risk big troubles.' (they change the environment entry value)
+---------------------------------------------------------------------------+
+ u s i n g r e s o u r c e m a n a g e r c o n n e c t i o n +
+ +
+ f a c t o r i e s r e f e r e n c e s +
+---------------------------------------------------------------------------+
1) javax.jms.queueconnectionfactory
2) javax.jms.topicconnectionfactory
3) javax.sql.datasource
4) javax.mail.session
5) java.net.url
the bd performs a lookup of the required resource on the jndi special environment
assigned to each bean.
as usual, the bd doesn't know anything about the target (operational) environment,
but still has to
guarantee the functionality from within the bean. so she uses a made-up name in
the lookup and informs
the dpy about the name she used.
from within the bean class, the bd writes something similar to the following:
try {
connection conn =
(datasource)ctx.lookup("java:comp/env/jdbc/myconnectionds").getconnection();
} catch (...) //this is a checked exception. btw...do you remember what the bd
responsibility is
//if such exception is caught? (hint...the client doesn't need to
know that some
//internal operational details went wrong, although this is a
checked exception...
//you will quite almost certainly find a question related to the
above situation
//in your exam.
<ejb-jar>
<enterprise-beans>
<session>
..
..
<resource-ref>
<description>optional</description>
<res-ref-name>jdbc/myconnectionds</res-ref-name>
<res-type>javax.sql.datasource</res-type>
<!-- <res-type>javax.jms.queueconnectionfactory</res-type> -->
<!-- <res-type>javax.jms.topicconnectionfactory</res-type> -->
<!-- <res-type>javax.mail.session</res-type> -->
<!-- <res-type>java.net.url</res-type> -->
<res-auth>container</res-auth>
<!-- <res-auth>bean</res-auth> -->
<res-sharing-scope>shareable</res-sharing-scope> //this is optional
<res-sharing-scope>unshareable</res-sharing-scope> //this is optional
</resource-ref>
</session>
</enterprise-beans>
</ejb-jar>
the dpy, reads the above dd declaration, and using vendor specific tools, ensures
that the
connection factory is bound to an existing (and working) connection factory on the
operational
environment (for instance she ensures that'jdbc/myconnectionds' is deployed
as a javax.sql.datasource in the application server.
+---------------------------------------------------------------------------+
+ r e f e r e n c i n g o t h e r b e a n s +
+---------------------------------------------------------------------------+
very often in your design, especially if you will use entirely an ejb based
approach,
will occur that the ejb you're designing will need to get a reference to another
bean.
a bean can lookup for another bean from the jndi special environment assigned to
each bean.
here as well, the bd uses a made-up name because he doesn't know how the aa and/or
the dpy
have called the bean in the operation environment. so he will inform the aa about
the
name he used from within the bean class through the dd and the aa will bind the
made-up
name used by the bd to an <ejb-name> element in the <enterprise-beans> section of
the dd.
from within the bean class the bd will use something like the following:
try {
<ejb-jar>
<enterprise-beans>
<session>
..
..
<ejb-ref>
<ejb-ref-name>ejb/orderhome</ejb-ref-name>
<ejb-ref-type>session</ejb-ref-type>
<!-- <ejb-ref-type>entity</ejb-ref-type> -->
<home>foo.bar.orderhome</home>
<remote>foo.bar.orderhome</remote>
</ejb-ref>
<ejb-ref-name>ejb/orderhome</ejb-ref-name>
<ejb-ref-type>session</ejb-ref-type>
<!-- <ejb-ref-type>entity</ejb-ref-type> -->
<local-home>foo.bar.orderlocalhome</local-home>
<local>foo.bar.orderlocalhome</local>
</ejb-local-ref>
</session>
</enterprise-beans>
</ejb-jar>
the aa will read the dd and think: "well, the bd informed me he used
'ejb/orderhome' to
refer to the order bean defined in the <enterprise-beans> section with the
<ejb-name> 'purchaseorders'. i just need to link the name used by the bd to the
label
(<ejb-name>) identifying this bean.
<ejb-ref>
<ejb-ref-name>ejb/orderhome</ejb-ref-name>
<ejb-ref-type>session</ejb-ref-type>
<!-- <ejb-ref-type>entity</ejb-ref-type> -->
<home>foo.bar.orderhome</home>
<remote>foo.bar.orderhome</remote>
<ejb-link>purchaseorders</ejb-link> //this is responsibility of the aa
</ejb-ref>
if, in the .ear file there is more than one ejb-jar file and the <ejb-name>
element
with the content 'purchaseorders' has been defined in more than one ejb-jar file,
there is a name conflict. the aa can use the alternate form of <ejb-link> to give
the absolute path to the jar file containing the bean to link to <ejb-ref>,
followed
by the '#' and the value of <ejb-name>.
the dpy has got the responsibility of ensuring that the bean reference used by the
bd is
of the right type for the bean home deployed in the operational environment.
+---------------------------------------------------------------------------+
+ r e f e r e n c i n g a r e s o u r c e e n v i r o n m e n t +
+ +
+ v a r i a b l e s
+---------------------------------------------------------------------------+
from within the bean class the bd will use something like the following:
try {
javax.jms.queue queue =
(javax.jms.queue)ctx.lookup("java:comp/env/jms/queuea");
//use the queue
<ejb-jar>
<enterprise-beans>
<session>
..
..
<resource-env-ref>
<res-env-ref-name>jms/queuea</res-env-ref-name>
<res-env-ref-type>javax.jms.queue</res-env-ref-type>
<!-- <res-env-ref-type>javax.jms.topic</res-env-ref-type> -->
</resource-env-ref>
</session>
</enterprise-beans>
</ejb-jar>
the dpy will need to ensure that a queue or topic with the jndi name 'jms/queuea'
is up
and running in the operational environment. the dpy will ensure this using vendor
specific
tools.