...
The
...
Time
...
Bean
...
Example
...
UNDER
...
CONSTRUCTION
...
This
...
is
...
an
...
example
...
of
...
a
...
JSP-page
...
calling
...
a
...
Session
...
Bean.
...
The
...
result
...
looks
...
like this:
First of all, I know I can't spell. I hope you can understand it anyway.
First of all, I know I can't spell. I hope you can understand it anyway.
In this example, I have not used any of the things making EJB development easier, like Eclipse, Ant or Xdoclet. I have tried to strip of everything just to make this example as easy as possible to understand. (On the other hand, some of the things in all the deployment descriptors I don't understand myself, so perhaps it would have been possible to strip of even more.) This is an example using geronimo 1.1, java 1.4 and EJB 2.1.
OK, what I want is an EJB that can tell the time, this is what the code for the bean looks like:
Code Block | ||||
---|---|---|---|---|
| ||||
this: !http://www.freefarm.se/j2ee/ejb/ex1/result.GIF! First of all, I know I can't spell. I hope you can understand it anyway. In this example, I have not used any of the things making EJB development easier, like Eclipse, Ant or Xdoclet. I have tried to strip of everything just to make this example as easy as possible to understand. (On the other hand, some of the things in all the deployment descriptors I don't understand myself, so perhaps it would have been possible to strip of even more.) This is an example using geronimo 1.1, java 1.4 and EJB 2.1. OK, what I want is an EJB that can tell the time, this is what the code for the bean looks like: package mytimepak; public class MyTimeBean implements javax.ejb.SessionBean { public void ejbCreate() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(javax.ejb.SessionContext ctx) {} public void unsetSessionContext() {} public void ejbRemove() {} public String getTime() { String s = new java.util.Date().toString(); return s; } } |
I
...
have
...
put
...
my
...
EJB
...
in
...
a
...
package
...
that
...
I
...
call
...
mytimepak.
...
The
...
first
...
6
...
methods
...
are
...
implementations
...
of
...
the
...
javax.ejb.SessionBean
...
interface.
...
I
...
don't
...
realy
...
know
...
what
...
good
...
they
...
are,
...
but
...
the
...
ejbCreate
...
method
...
is
...
like
...
a
...
constructor,
...
in
...
this
...
case
...
an
...
empty
...
constructor.
...
To
...
enable
...
clients
...
to
...
call
...
the
...
EJB
...
one
...
must
...
provide
...
so
...
called
...
home
...
and
...
remote
...
interfaces.
...
The
...
first
...
one,
...
home
...
interface,
...
is
...
used
...
to
...
locate
...
the
...
EJB,
...
the
...
other,
...
the
...
remote
...
interface
...
is
...
used
...
to
...
invoke
...
methods
...
on
...
the
...
EJB.
...
The
...
remote
...
interface
...
is
...
just
...
like
...
a
...
normal
...
interface
...
used
...
for
...
RMI.
...
As
...
this
...
EJB
...
will
...
only
...
be
...
used
...
from
...
a
...
JSP-page
...
that
...
is
...
run
...
in
...
the
...
same
...
server
...
(same
...
JVM)
...
I
...
use
...
another
...
type
...
of
...
interfaces
...
that
...
don't
...
make
...
use
...
of
...
the
...
network.
...
Thay
...
are
...
called
...
LocalHome
...
and
...
Local
...
interface
...
instead,
...
but
...
they
...
are
...
just
...
the
...
same.
...
This
...
is
...
the
...
code
...
for
...
the
...
local
...
home
...
interface
...
(coresponding
...
to
...
the
...
home
...
interface):
Code Block | ||||
---|---|---|---|---|
| ||||
package mytimepak; public interface MyTimeLocalHome extends javax.ejb.EJBLocalHome { public MyTimeLocal create() throws javax.ejb.CreateException; } |
As
...
you
...
can
...
see,
...
the
...
LocalHome
...
interface
...
is
...
like
...
a
...
constructor
...
returning
...
MyTimeLocal.
...
This
...
is
...
the
...
code
...
for
...
the
...
Local
...
interface
...
(coresponding
...
to
...
the
...
remote
...
interface)
Code Block |
---|
package mytimepak; public interface MyTimeLocal extends javax.ejb.EJBLocalObject { public java.lang.String getTime() ; } |
This
...
is
...
just
...
a
...
plain
...
interface
...
for
...
the
...
methods
...
(I
...
refuse
...
to
...
call
...
them
...
business
...
methods)
...
of
...
the
...
EJB,
...
in
...
this
...
case
...
the
...
getTime()
...
method.
...
This
...
code
...
is
...
not
...
hard
...
to
...
understand,
...
the
...
tricky
...
part
...
is
...
the
...
deployment
...
descriptors.
...
You
...
need
...
2
...
of
...
them,
...
ejb-jar.xml
...
and
...
openejb-jar.xml.
...
This
...
is
...
what
...
they
...
look
...
like:
...
ejb-jar.xml:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8"?> <ejb-jar id="ejb-jar_1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1"> <description>Example of a session bean</description> <display-name>MyTimeBeanEJBName</display-name> <enterprise-beans> <session id="Session_MyTime"> <description>An EJB named MyTimeBean</description> <display-name>MyTimeBeanName</display-name> <ejb-name>MyTimeBean</ejb-name> <local-home>mytimepak.MyTimeLocalHome</local-home> <local>mytimepak.MyTimeLocal</local> <ejb-class>mytimepak.MyTimeBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> </ejb-jar>First you have some stuff that I jar> |
First you have some stuff that I don't
...
know
...
what
...
good
...
they
...
are,
...
for
...
example
...
the
...
display-name
...
tag.
...
You
...
can
...
write
...
what
...
ever
...
there
...
I
...
guess.
...
It
...
seams
...
totaly
...
unnessesary
...
to
...
me,
...
but
...
I
...
have
...
not
...
tested
...
what
...
happens
...
if
...
I
...
take
...
it
...
away.
...
What
...
does
...
matter
...
is
...
the
...
tags
...
ejb-name,
...
local-home,
...
local,
...
ejb-class,
...
session-type.
...
I
...
think
...
that
...
the
...
ejb-name
...
is
...
part
...
of
...
what
...
clients
...
use
...
to
...
locate
...
the
...
bean
...
(see
...
the
...
next
...
xml-file).
...
The
...
local-home,
...
local
...
and
...
ejb-class
...
tags
...
points
...
out
...
the
...
classes.
...
Session
...
type
...
tells
...
if
...
it
...
is
...
a
...
statefull
...
or
...
stateless
...
session
...
bean.
...
Transaction
...
type
...
doen't
...
make
...
sence
...
I
...
think,
...
there
...
is
...
no
...
transactions
...
in
...
a
...
session
...
bean,
...
is
...
there?
...
I
...
have
...
tryed
...
to
...
read
...
more
...
about
...
this
...
deployment
...
descriptors
...
here:
...
http://cwiki.apache.org/GMOxDOC11/deployment-plans.html
...
...
I
...
have
...
not
...
bean
...
able
...
to
...
figure
...
it
...
out.
...
On
...
the
...
other
...
hand,
...
I
...
don't
...
think
...
ejb-jar.xml
...
files
...
are
...
needed
...
in
...
the
...
next
...
generation
...
EJB
...
3.0
...
so
...
perhaps
...
one
...
should
...
not
...
spend
...
to
...
much
...
time
...
trying
...
to
...
understand
...
it.
...
Here
...
comes
...
the
...
openejb-jar.xml
...
file:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8"?> <openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.1" xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.1" xmlns:pkgen="http://www.openejb.org/xml/ns/pkgen-2.0" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.1" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1"> <sys:environment> <sys:moduleId> <sys:groupId>default</sys:groupId> <sys:artifactId>TimeBean_artifact_in_openejb</sys:artifactId> <sys:version>1.0</sys:version> <sys:type>car</sys:type> </sys:moduleId> </sys:environment> <enterprise-beans> <session> <ejb-name>MyTimeBean</ejb-name> <ejb-ref> <ref-name>ejb/MyTimeBean</ref-name> <ejb-link>MyTimeBean</ejb-link> </ejb-ref> </session> </enterprise-beans> </openejb-jar>Againjar> |
Again,
...
I
...
don't
...
understand
...
much
...
of
...
the
...
first
...
part,
...
but
...
the
...
ejb-ref
...
part
...
is
...
important.
...
ref-name=ejb/MyTimeBean
...
is
...
what
...
clients
...
use
...
to
...
lookup
...
the
...
EJB.
...
ejb-link=MyTimeBean
...
is
...
the
...
same
...
as
...
ejb-name=MyTimeBean
...
in
...
ejb-jar.xml.
...
The
...
ejb-link
...
and
...
the
...
ejb-name
...
must
...
be
...
the
...
same.
...
(Why
...
this
...
information
...
has
...
bean
...
split
...
up
...
in
...
2
...
files
...
is
...
a
...
mystery
...
to
...
me.
...
I
...
guess
...
that
...
it
...
has
...
something
...
to
...
do
...
with
...
what
...
is
...
generic
...
for
...
the
...
application
...
(ejb-jar.xml)
...
and
...
other
...
stuff
...
that
...
is
...
spesific
...
to
...
the
...
application
...
server.
...
If
...
you
...
were
...
to
...
deploy
...
this
...
application
...
on
...
another
...
application
...
server
...
than
...
geronimo
...
you
...
would
...
only
...
have
...
to
...
change
...
the
...
openejb-jar
...
file.
...
That
...
sounds
...
good.
...
On
...
the
...
other
...
hand,
...
now
...
you
...
have
...
the
...
extra
...
complexity
...
of
...
knowing
...
what
...
goes
...
where
...
and
...
that
...
sure
...
aint
...
easier
...
than
...
having
...
to
...
rewrite
...
one
...
sigle
...
deployment
...
descriptor
...
if
...
you
...
would
...
face
...
the
...
rare
...
situation
...
of
...
deploying
...
your
...
code
...
on
...
another
...
type
...
of
...
server.
...
But
...
this
...
is
...
ofcourse
...
my
...
personal
...
oppinion
...
based
...
on
...
limited
...
understanding
...
of
...
EJB.)
...
Allright,
...
now
...
for
...
the
...
JSP
...
client
...
of
...
this
...
EJB.
...
This
...
is
...
my
...
JSP-page,
...
I
...
comment
...
the
...
code
...
directly
...
in
...
the
...
code:
Code Block | ||||
---|---|---|---|---|
| ||||
<%@ page contentType="text/html" import="mytimepak.*, javax.naming.* " %> <html<head><title>Time</title></head><body> <% String s="-"; // Just declare a string try { // This creates a context, it can be used to lookup EJBs. Using normal RMI you would // have to know port number and stuff. The InitialContext holds info like // server names, ports and stuff I guess. Context context = new InitialContext(); // MyTimeLocalHome is a rference to the EJB MyTimeLocalHome myTimeHomeLocal = (MyTimeLocalHome)context.lookup("java:comp/env/ejb/MyTimeBean"); // java:comp:env is like a reference to the local server. ejb is where you find the EJBs and // MyTimeBean is the name of the EJB that is written in the deployment descriptors. // This is like a constructor returning a MyTimeLocal, an interface for the EJB on which you // can call methods (but not access variables as with any interface) MyTimeLocal myTimeLocal = myTimeHomeLocal.create(); // So, just go ahead and call a method (in this case the only method). s = myTimeLocal.getTime(); } catch (Exception e) { s=e.toString(); } %> |
This
...
is
...
the
...
time
...
returned
...
from
...
the
...
EJB:
...
<%=
...
s%>
Note that
...
this
...
JSP-page
...
also
...
have
...
to
...
include
...
mytimepak.MyTimeLocalHome
...
and
...
mytimepak.MyTimeLocal.
...
I
...
have
...
done
...
that
...
in
...
the
...
first
...
line
...
import="mytimepak.*.
...
This
...
to
...
class
...
files
...
must
...
be
...
in
...
the
...
WEB-INF/classes
...
directory,
...
and
...
not
...
only
...
that,
...
in
...
the
...
WEB-INF/classes/mytimepak
...
directory.
...
I'll
...
get
...
back
...
to
...
that
...
later.
...
If
...
the
...
JSP
...
is
...
simple,
...
again
...
the
...
deployment
...
descriptors
...
are
...
hard
...
(or
...
at
...
least
...
that
...
is
...
what
...
I
...
think).
...
This
...
is
...
what
...
they
...
look
...
like:
...
geronimo-web.xml:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1" xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.1" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1"> <sys:environment> <sys:moduleId> <sys:groupId>default</sys:groupId> <sys:artifactId>MyTimeWeb</sys:artifactId> <sys:version>1.0</sys:version> <sys:type>car</sys:type> </sys:moduleId> </sys:environment> <context-root>/mytime</context-root> </web-app>Only inportant here app> |
Only inportant here (as
...
far
...
as
...
I
...
understand)
...
is
...
the
...
context-root
...
that
...
becomes
...
the
...
URI.
...
web.xml
Code Block | ||||
---|---|---|---|---|
| ||||
xml <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name> MyTImeWeb</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- To refer local EJB's --> <ejb-local-ref> <ejb-ref-name>ejb/MyTimeBean</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local-home>mytimepak.MyTimeLocalHome</local-home> <local>mytimepak.MyTimeLocal</local> <ejb-link>MyTimeBean</ejb-link> </ejb-local-ref> </web-app>welcomeapp> |
welcome-file
...
is
...
what
...
file
...
the
...
server
...
will
...
show
...
if
...
no
...
file
...
name
...
is
...
in
...
the
...
URI.
...
ejb-local-ref
...
is
...
important.
...
Here
...
you
...
must
...
get
...
the
...
data
...
right
...
in
...
all
...
the
...
tags
...
(or
...
so
...
I
...
think).
...
Note
...
how
...
ejb/MyTimeBean
...
corresponds
...
to
...
ref-name
...
int
...
openejb-jar.
...
ejb-link
...
seams
...
to
...
be
...
unessesary,
...
but
...
we
...
can't
...
deply
...
it
...
without
...
the
...
local-home
...
and
...
local
...
tags
...
pointing
...
out
...
the
...
classes
...
for
...
the
...
interfaces.
...
There
...
are
...
2
...
more
...
deployment
...
descriptors,
...
the
...
ones
...
for
...
the
...
application
...
as
...
a
...
whole.
...
This
...
is
...
what
...
they
...
look
...
like:
...
application.xml
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8"?> <application id="Application_ID" version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"> <display-name>MyTimeEJBApp</display-name> <module> <ejb>mytime-ejb.jar</ejb> </module> <module id="WebModule_1158667626422"> <web> <web-uri>mytime-web.war</web-uri> <context-root>/mytime</context-root> </web> </module> </application>This file tell which two modules, the ejb and the web, that the ear file consists of. application> |
This file tell which two modules, the ejb and the web, that the ear file consists of.
geronimo-application.xml:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8"?> <application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.1" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1" application-name="t6"> <sys:environment> <sys:moduleId> <sys:groupId>default</sys:groupId> <sys:artifactId>MyTime_ArtifactId</sys:artifactId> <sys:version>1.0</sys:version> <sys:type>car</sys:type> </sys:moduleId> </sys:environment> </application>This file is pretty application> |
This file is pretty empty.
...
The
...
only
...
thing
...
of
...
importance
...
is
...
the
...
artifactId,
...
it
...
shows
...
if
...
you
...
look
...
a
...
the
...
lists
...
of
...
modules
...
at
...
http://localhost:8080/console/portal/apps/apps_ear
...
...
this:
...
default/MyPhonebook_ArtifactId/1.0/car
...
(Anybody
...
knows
...
what
...
"car"
...
stands
...
for?)
...
Allright,
...
this
...
is
...
how
...
I
...
have
...
organised
...
my
...
files :
Code Block | ||||
---|---|---|---|---|
| ||||
: app-home (in my case c:\java\j2ee\mytime) ¦ ¦ +---ejb ¦ +---META-INF ¦ ¦ ejb-jar.xml ¦ ¦ openejb-jar.xml ¦ ¦ ¦ +---mytimepak ¦ MyTimeBean.java ¦ MyTimeLocal.java ¦ MyTimeLocalHome.java ¦ +---META-INF ¦ application.xml ¦ geronimo-application.xml ¦ +---web ¦ index.jsp ¦ +---WEB-INF ¦ geronimo-web.xml ¦ web.xml ¦ +---classes +---mytimepak MyTimeLocal.class this file must be copyed here MyTimeLocalHome.class this file must be copyed here |
First
...
we
...
must
...
compile
...
the
...
EJB.
...
Then
...
copy
...
the
...
interface
...
classes
...
to
...
the
...
WEB-INF\classes\mytimepak
...
directory
...
Last
...
task
...
is
...
to
...
pack
...
the
...
EJB-jar
...
file
...
the
...
WEB-war
...
file
...
and
...
finaly
...
the
...
EAR-file.
...
To
...
compile
...
the
...
EJB
...
we
...
must
...
have
...
geronimo-ejb_2.1_spec-1.0.1.jar
...
in
...
the
...
classpath.
...
I
...
have
...
installed
...
geronimo
...
in
...
C:\geronimo\geronimo-1.1
...
and
...
This
...
is
...
a
...
bat-script
...
that
...
does
...
this.
...
Modern
...
programmers
...
use
...
ant
...
ofcourse,
...
but
...
for
...
clarity,
...
this
...
is
...
exactly
...
what
...
is
...
needed
...
to
...
get
...
the
...
ear.
...
So
...
beginning
...
in
...
the
...
app-home
...
directory
...
(in
...
my
...
case
...
cd
...
c:\java\j2ee\mytime)
Code Block | ||||
---|---|---|---|---|
| ||||
set CLPATH=C:\geronimo\geronimo-1.1\repository\org\apache\geronimo\specs\geronimo-ejb_2.1_spec\1.0.1\geronimo-ejb_2.1_spec-1.0.1.jar cd ejb javac -classpath %CLPATH% mytimepak\*.java copy mytimepak\MyTimeLocal.class ..\web\WEB-INF\classes\mytimepak\ copy mytimepak\MyTimeLocalHome.class ..\web\WEB-INF\classes\mytimepak\ jar -cf ../mytime-ejb.jar mytimepak META-INF cd ..\web jar -cf ../mytime-web.war index.jsp WEB-INF cd .. jar -cf mytime-ear.ear mytime-ejb.jar mytime-web.war META-INF |
As
...
you
...
can
...
see
...
here
...
I
...
start
...
with
...
declaring
...
a
...
variable
...
CLPATH
...
just
...
not
...
to
...
get
...
to
...
long
...
lines.
...
Then
...
cd
...
to
...
the
...
ejb-directory
...
and
...
compile
...
the
...
EJB.
...
Then
...
copy
...
the
...
interface
...
flasses
...
to
...
the
...
web
...
application.
...
Then
...
I
...
use
...
jar
...
to
...
first
...
create
...
an
...
jar
...
file
...
for
...
the
...
EJB,
...
then
...
a
...
war-file
...
for
...
the
...
web,
...
and
...
finaly
...
put
...
this
...
to
...
jars
...
(or
...
mor
...
corectly
...
the
...
jar
...
and
...
the
...
war)
...
in
...
an
...
ear
...
file.
...
Note
...
how
...
the
...
META-INF/WEB-INF
...
is
...
directly
...
in
...
the
...
jar-file
...
root
...
directory
...
for
...
all
...
the
...
jars.
...
Finaly
...
the
...
ear
...
must
...
be
...
deployed.
...
I
...
use
...
the
...
geronimo
...
deploy
...
tool
...
like
...
this:
...
c:\geronimo\geronimo-1.1\bin\deploy.bat
...
--user
...
system
...
--password
...
manager
...
deploy
...
mytime-ear.ear
...
(If
...
you
...
change
...
anything,
...
remake
...
the
...
jar,
...
war
...
and
...
ear,
...
and
...
change
...
to
...
redeploy
...
mytime-ear.ear.
...
Also,
...
you
...
need
...
to
...
change
...
the
...
path
...
to
...
deploy.bat
...
if
...
you
...
have
...
not
...
installed
...
geronimo
...
1.1
...
in
...
the
...
directory
...
c:\geronimo\geronimo-1.1)
...
Now
...
we
...
can
...
look
...
at
...
the
...
application
...
at
...
...
The
...
whole
...
source
...
code
...
can
...
be
...
downloaded
...
in
...
this
...
zip-file:
...
mytime.zip
...
Next:
...
the
...
CMP
...
EJB
...
phonebook
...
example.
--------------------------------------------------------------------------------
...
By
...
Mattias
...
Malmgren
...
mattias@freefarm.se
...
2006-09-28
...