User: tobias
Date: 01/03/11 17:55:01
Modified: documentation/HTML ch01.html ch01s05.html ch01s06.html
ch01s07.html ch01s08.html ch01s09.html ch01s10.html
ch01s11.html ch01s12.html ch02.html ch03.html
ch03s05.html ch04.html ch04s07.html ch04s09.html
ch04s10.html ch04s11.html ch04s12.html ch05.html
ch05s02.html ch05s03.html ch05s04.html ch05s05.html
ch05s06.html ch06.html ch06s02.html ch06s03.html
ch06s04.html ch07.html ch08.html index.html
pr01.html
Added: documentation/HTML ch07s02.html ch07s03.html ch07s07.html
ch08s04.html ch08s17.html ch08s21.html ch08s31.html
ch08s63.html ch08s68.html ch08s72.html ch09.html
ch09s07.html ch09s08.html ch09s24.html ch09s27.html
ch09s32.html ch09s50.html ch09s53.html ch09s56.html
ch09s81.html ch09s92.html jbossdocs.html
Removed: documentation/HTML ch07s04.html ch07s17.html ch07s21.html
ch07s31.html ch07s63.html ch07s68.html ch08s07.html
ch08s08.html ch08s24.html ch08s27.html ch08s32.html
ch08s39.html ch08s42.html ch08s45.html ch08s70.html
Log:
updated HTML manual version. added "in-one-page" and zip file of manual.
Revision Changes Path
1.2 +7 -7 newsite/documentation/HTML/ch01.html
Index: ch01.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01.html 2001/02/11 16:02:02 1.1
+++ ch01.html 2001/03/12 01:54:45 1.2
@@ -1,8 +1,8 @@
-<html><head><title>1. First steps</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.25" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="index.html"
rel="up" title="JBoss 2.0 documentation"><link href="pr01.html" rel="previous"
title="Preface"><link href="ch01s05.html" rel="next" title="Installing
JBoss"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="pr01.html"><img border="0" height="65"
src="images/prev.gif" width="76"><!
/a><a href="ch01s05.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="Na67"><div
class="titlepage"><h2 class="title"><a name="Na67">1. First steps</a></h2></div><div
class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="ch01.html#Na78">Introduction</a></dt><dt> <a href="ch01s05.html">Installing
JBoss</a></dt><dt> <a href="ch01s06.html">Creating the Bean</a></dt><dt> <a
href="ch01s07.html">EJBs: review</a></dt><dt> <a href="ch01s08.html">Coding the
classes</a></dt><dt> <a href="ch01s09.html">The deployment descriptor</a></dt><dt> <a
href="ch01s10.html">Packaging and deploying the bean</a></dt><dt> <a
href="ch01s11.html">Coding the test client</a></dt><dt> <a
href="ch01s12.html">Compiling and running test client</a></dt></dl></div><p>Author:
+<html><head><title>Chapter 1. First steps</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="index.html" rel="up" title="JBoss 2.0 documentation"><link
href="pr01.html" rel="previous" title="Preface"><link href="ch01s05.html" rel="next"
title="Installing JBoss"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="pr01.html"><img border="0" height="65"
src="images/prev.gif" widt!
h="76"></a><a href="ch01s05.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="Na67"><div
class="titlepage"><div><h2 class="title"><a name="Na67"></a>Chapter 1. First
steps</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="ch01.html#Na78">Introduction</a></dt><dt> <a href="ch01s05.html">Installing
JBoss</a></dt><dt> <a href="ch01s06.html">Creating the Bean</a></dt><dt> <a
href="ch01s07.html">EJBs: review</a></dt><dt> <a href="ch01s08.html">Coding the
classes</a></dt><dt> <a href="ch01s09.html">The deployment descriptor</a></dt><dt> <a
href="ch01s10.html">Packaging and deploying the bean</a></dt><dt> <a
href="ch01s11.html">Coding the test client</a></dt><dt> <a
href="ch01s12.html">Compiling and running test client</a></dt></dl></div><p>Author:
<span class="author">Kevin Boone</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
-</p><div class="section" id="Na78"><div class="titlepage"><h2 class="title"
style="clear: all"><a name="Na78"></a><span
class="title">Introduction</span></h2></div><div class="section" id="Na7c"><div
class="titlepage"><h3 class="title"><a name="Na7c"></a><span class="title">What this
article is about</span></h3></div><p>
-This article presensts a step-by-step tutorial on how to set up `JBoss', the
+</p><div class="section"><a name="Na78"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="Na78"></a><span
class="title">Introduction</span></h2></div></div><div class="section"><a
name="Na7c"></a><div class="titlepage"><div><h3 class="title"><a name="Na7c"></a><span
class="title">What this section is about</span></h3></div></div><p>
+This section presents a step-by-step tutorial on how to set up `JBoss', the
free Enterprise JavaBean (EJB) server, and create your first
Enterprise JavaBean and client. It doesn't explain what Enterprise JavaBeans
are, or how they are used; there are a number of good
@@ -11,7 +11,7 @@
this article will also apply to other platforms. If you are using a Windows
platform you will need to pay attention to the directory names, which
will be different from the one's I've assumed.
-</p></div><div class="section" id="Na85"><div class="titlepage"><h3
class="title"><a name="Na85"></a><span class="title">About JBoss</span></h3></div><p>
+</p></div><div class="section"><a name="Na85"></a><div class="titlepage"><div><h3
class="title"><a name="Na85"></a><span class="title">About
JBoss</span></h3></div></div><p>
JBoss is an implementation of the EJB 1.1 specification, that is, it is a
server and container for Enterprise JavaBeans. In this it is similar to Sun's
`J2SDK Enterprise Edition' (J2EE), but JBoss is much more single-minded than
@@ -19,7 +19,7 @@
support for JSP, SSL, and all the other protocols that the Sun product can
handle. This means that it is smaller in memory and in disk space.
JBoss will run very effectively on a machine with 64 megabytes of RAM, and
-requires only 4 megabytes of disk (including source code!). Sun's
+requires only some megabytes of disk (including source code!). Sun's
J2EE requires a minimum of 128 megabytes of RAM, and 31 megabytes of disk
space. That's not to criticise the Sun product; it is a
heavyweight offering providing a host of services. Because of its small memory
@@ -42,7 +42,7 @@
recourse to it at some point. This article hopes to remedy this deficiency, to
a small degree, by describing step-by-step how a simple EJB can
be created, deployed and tested on the JBoss server.
-</p></div><div class="section" id="Na94"><div class="titlepage"><h3
class="title"><a name="Na94"></a><span
class="title">Pre-requisites</span></h3></div><p>
+</p></div><div class="section"><a name="Na94"></a><div class="titlepage"><div><h3
class="title"><a name="Na94"></a><span
class="title">Pre-requisites</span></h3></div></div><p>
JBoss is written entirely in Java, and requires a Java system compatible with
JDK 1.3. This is essential, not optional. Trust me on this; I've tried
it with JDK 1.2.2 and the `hot' deployment facility simply doesn't work. Since
@@ -52,7 +52,7 @@
traditional gzipped tar, the RPM version does not unpack, so don't waste time
downloading the 34 megabytes it requires. Use the tar version
and un-tar it as normal. </p><p>
-I will assume that you are basically familiar with EJBs (and know, for
+I will assume that you are basically familiar with EJBs (and roughly know, for
example, what a `home interface' is) and know how to compile Java
classes.
</p></div></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="pr01.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch01s05.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.2 +34 -31 newsite/documentation/HTML/ch01s05.html
Index: ch01s05.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01s05.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01s05.html 2001/02/11 16:02:02 1.1
+++ ch01s05.html 2001/03/12 01:54:46 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Installing JBoss</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.25" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch01.html"
rel="up" title="1. First steps"><link href="ch01.html" rel="previous" title="1. First
steps"><link href="ch01s06.html" rel="next" title="Creating the Bean"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01.html"><img border="0" height="65" src="images/prev.gif" width="76"></!
a><a href="ch01s06.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="Naa1"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="Naa1"></a><span
class="title">Installing JBoss</span></h2></div><p>Before installing and running the
server, you should check that your JDK
+<html><head><title>Installing JBoss</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch01.html"
rel="up" title="Chapter 1. First steps"><link href="ch01.html" rel="previous"
title="Chapter 1. First steps"><link href="ch01s06.html" rel="next" title="Creating
the Bean"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01.html"><img border="0" height="65"
src="images/prev.gi!
f" width="76"></a><a href="ch01s06.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="Naa1"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Naa1"></a><span class="title">Installing
JBoss</span></h2></div></div><p>Before installing and running the server, you should
check that your JDK
installation is working. (Step-by-step instructions are available.) You will
need the JDK binaries directory in your PATH (this is essential: see below)
not just for the user account which is doing the installation, but also for
@@ -7,39 +7,42 @@
(root and ordinary users normally have different PATH settings). You won't
need to specify a CLASSPATH environment variable if you don't normally have
to.</p><p>The next step will be to download, install and test the JBoss server. At
-the time of writing the most recent version of JBoss is 2.0. You can get JBoss
-from www.jboss.org</p><p>It doesn't matter very much where you install JBoss; my
preference is to
+the time of writing the most recent version of JBoss is 2.0.</p><p>It doesn't
matter very much where you install JBoss; my preference is to
use /usr/local/jboss. If you don't have root access, or would rather not run
untested software as root, jboss will work perfectly well if installed in a
user directory and run as an ordinary user. I will assume in this tutorial
that you are installing in /usr/local/jboss. If you haven't, change the paths
-as appropriate.</p><p>JBoss is distributed using Install Anywhere which isn't a
natural format
-for Linux users. If you're running the X Window System on your Linux machine
-and you have Netscape installed with Java enabled, this might work for you.
-Otherwise, your best bet right now is to download from CVS or to install from
-the Zip file like this:</p><div class="literallayout"><b>su<br>
-mkdir /usr/local/jboss<br>
-cd /usr/local/jboss<br>
-lynx -source \<br>
- http://jboss.org/JBoss2/InstData/Other/install.zip \<br>
- > install.zip<br>
-mkdir installer<br>
-cd installer<br>
-unzip ../install.zip<br>
-mv c:/jboss2/* ..<br>
-cd ..<br>
-rm -rf installer<br>
-rm -f install.zip<br>
-</b></div><p>You could try running the server now. Change to the bin directory, and
+as appropriate.</p><p>JBoss is distributed as a ZIP file. You can download the
binary
+distribution which contains the latest offical release (which was 2.0
+FINAL at the time of writing) or a source snapshot with the latest
+version from CVS (called PRE2.1). This documentation mainly is written
+for the 2.0
+version. You can get all the mentioned packages from http://www.jboss.org .
+</p><p><b>Installation of binary package for Windows:</b> Download the binary
package from http://www.jboss.org from the
+Download - Binary section. Place it in a temporary directory and use your
+favorite unziper to decompress it to the place where you want JBoss
+installed. Start the "command line" from "Accessories" menu and change to
+the directory to which you just decompressed the binary package. In
+the following descriptions you will need to replace /usr/local/jboss/
+with the path you selected to install JBoss to (e.g. c:\jboss\ ). Also
+note that Windows is not using a colon “:” but a
+semicolon “;” to separate
+multiple entries in paths (e.g. the CLASSPATH).
+</p><p><b>Installation of binary package for Linux:</b> <div
class="literallayout"><b>cd /tmp/<br>
+lynx -source http://www.jboss.org/newsite/bin/jBoss-2.0_FINAL.zip > jBoss-2.0_FINAL.zip<br>
+su<br>
+cd /usr/local/<br>
+unzip /tmp/jBoss-2.0_FINAL.zip<br>
+mv jBoss-2.0_FINAL jboss<br>
+cd jboss<br>
+</b></div>
+</p><p>Now change to the user as which you want to run the
+server. Please make sure, that this user has the JDK binaries in his
+command path and that he has write access to the JBoss directory
+(needed for log files and deployment).
+You are now ready to change to the bin directory, and
run the program like this: </p><div class="literallayout"><b>cd bin<br>
-java -jar run.jar<br>
-</b><br>
+java -jar run.jar</b><br>
</div><p>In a proper installation, the server should start without any error
-messages or exceptions being thrown. It will produce about three pages of
-output on startup.</p><p>The JBoss distribution is supplied with one test Bean,
packaged as
-bank.jar. This is supplied in the `deploy' subdirectory, which is where Beans
-are placed to deploy them. The effect of this is to deploy the `bank' bean
-when the server starts up. This is fine the first time, as it tests that the
-SQL server is working, but you can usefully move bank.jar out of the deploy
-directory when you are sure that everything's OK, and the server will start up
-more quickly.</p></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch01s06.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
+messages or exceptions being thrown. It will produce several pages of
+output on startup.</p></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch01s06.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
1.2 +9 -13 newsite/documentation/HTML/ch01s06.html
Index: ch01s06.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01s06.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01s06.html 2001/02/11 16:02:02 1.1
+++ ch01s06.html 2001/03/12 01:54:46 1.2
@@ -1,15 +1,10 @@
-<html><head><title>Creating the Bean</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="1. First steps"><link
href="ch01s05.html" rel="previous" title="Installing JBoss"><link href="ch01s07.html"
rel="next" title="EJBs: review"></head><body alink="#0000FF" bgcolor="white"
link="#0000FF" text="black" vlink="#840084"><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/jboss.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s05.html"><img border="0" height="65"
src="images/prev.gif" width="76!
"></a><a href="ch01s07.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="Nad0"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="Nad0"></a><span
class="title">Creating the Bean</span></h2></div><p>
+<html><head><title>Creating the Bean</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="Chapter 1. First steps"><link
href="ch01s05.html" rel="previous" title="Installing JBoss"><link href="ch01s07.html"
rel="next" title="EJBs: review"></head><body alink="#0000FF" bgcolor="white"
link="#0000FF" text="black" vlink="#840084"><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/jboss.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s05.html"><img border="0" height="65"
src="images/prev.gif" w!
idth="76"></a><a href="ch01s07.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a name="Nae2"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="Nae2"></a><span
class="title">Creating the Bean</span></h2></div></div><p>
In this step we will write and compile a simple Enterprise JavaBean. You can
-download the source code interestEJB.tar.gz for this example; you will need to
-unpack it into an empty directory.</p><div
class="literallayout"><b>cd /usr/local/jboss<br>
-mkdir examples<br>
-cd examples<br>
-lynx -source http://jboss.org/newsite/documentation/interestEJB.tar.gz > interestEJB.tar.gz<br>
-gunzip interestEJB.tar.gz<br>
-tar xf interestEJB.tar<br>
-rm -rf interestEJB.tar<br>
-<br>
-</b></div><p>The example -- which is called `Interest' -- is about as simple as an
+download the source code for this example; according to which unpacker
+(WinZIP, unzip, tar) you have available either download
+interestEJB.zip or interestEJB.tar.gz from the file section in the
+documentation section on www.jboss.org . You will need to
+unpack the archive into an empty directory.</p><p>The example -- which is called
`Interest' -- is about as simple as an
EJB can get: it is a `stateless session bean'. Its job is to calculate the
amount of compound interest payable on a sum of money borrowed over a
specified term with a specified interest rate. In fact, there is only one
@@ -22,6 +17,7 @@
web_tomorrow<br>
interest<br>
{java source and class files here}<br>
+<br>
</div>
-If you unpack the archive interestEJB.tar.gz it will create this
-structure automatically. </p></div><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/gbar.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s05.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch01s07.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
+If you unpack the interestEJB-archive it will create a subdirectory
+called "interest" and the needed structure automatically below it.</p></div><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s05.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch01s07.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
1.2 +2 -1 newsite/documentation/HTML/ch01s07.html
Index: ch01s07.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01s07.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01s07.html 2001/02/11 16:02:02 1.1
+++ ch01s07.html 2001/03/12 01:54:46 1.2
@@ -1,4 +1,4 @@
-<html><head><title>EJBs: review</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.25" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch01.html"
rel="up" title="1. First steps"><link href="ch01s06.html" rel="previous"
title="Creating the Bean"><link href="ch01s08.html" rel="next" title="Coding the
classes"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s06.html"><img border="0" height="65"
src="images/prev.gif" width="!
76"></a><a href="ch01s08.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="Naf0"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="Naf0"></a><span
class="title">EJBs: review</span></h2></div><p> As a reminder, and Enterprise JavaBean
has a minimum of three
+<html><head><title>EJBs: review</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch01.html"
rel="up" title="Chapter 1. First steps"><link href="ch01s06.html" rel="previous"
title="Creating the Bean"><link href="ch01s08.html" rel="next" title="Coding the
classes"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s06.html"><img border="0" height="65"
src="images/prev.gif"!
width="76"></a><a href="ch01s08.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="Naf8"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Naf8"></a><span class="title">EJBs:
review</span></h2></div></div><p> As a reminder, and Enterprise JavaBean has a minimum
of three
classes.The remote interface. This is the class that exposes the methods of
the Bean to the outside world. In the example, the remote interface is the
class com.web_tomorrow.interest.Interest The Bean class. This implements the
@@ -25,6 +25,7 @@
META-INF<br>
ejb-jar.xml<br>
jboss.xml (optional)<br>
+<br>
</div>
</p><p>If the jar utility is run at the top level of this directory structure,
it will put the files in the right ordering in the archive. We will discuss
1.2 +8 -11 newsite/documentation/HTML/ch01s08.html
Index: ch01s08.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01s08.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01s08.html 2001/02/11 16:02:02 1.1
+++ ch01s08.html 2001/03/12 01:54:46 1.2
@@ -1,8 +1,8 @@
-<html><head><title>Coding the classes</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="1. First steps"><link
href="ch01s07.html" rel="previous" title="EJBs: review"><link href="ch01s09.html"
rel="next" title="The deployment descriptor"></head><body alink="#0000FF"
bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s07.html"><img border="0" height="65" src="images/prev.gif"!
width="76"></a><a href="ch01s09.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="section"
id="Nb11"><div class="titlepage"><h2 class="title" style="clear: all"><a
name="Nb11"></a><span class="title">Coding the classes</span></h2></div><p>We need
three classes: the remote interface, the Bean, and the home
+<html><head><title>Coding the classes</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="Chapter 1. First steps"><link
href="ch01s07.html" rel="previous" title="EJBs: review"><link href="ch01s09.html"
rel="next" title="The deployment descriptor"></head><body alink="#0000FF"
bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s07.html"><img border="0" height="65" src="images/p!
rev.gif" width="76"></a><a href="ch01s09.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="Nb19"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Nb19"></a><span class="title">Coding the
classes</span></h2></div></div><p>We need three classes: the remote interface, the
Bean, and the home
interface. All the .java files will go in the subdirectory
./com/web_tomorrow/interest.
The remote interface in this example is very simple.
-</p><div class="figure"><p><a name="Nb19"></a><b>Figure 1.1. Remote interface for
the `interest' EJB</b></p><pre class="programlisting">
+</p><div class="figure"><p><a name="Nb21"></a><b>Figure 1.1. Remote interface for
the `interest' EJB</b></p><pre class="programlisting">
package com.web_tomorrow.interest;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
@@ -26,7 +26,7 @@
double rate, double periods) throws RemoteException;
}
</pre></div><p> The remote interface specifies only one `business method'
-calculateCompoundInterest. The home interface is even simpler. </p><div
class="figure"><p><a name="Nb28"></a><b>Figure 1.2. Home interface for the `interest'
EJB</b></p><pre class="programlisting">
+calculateCompoundInterest. The home interface is even simpler. </p><div
class="figure"><p><a name="Nb30"></a><b>Figure 1.2. Home interface for the `interest'
EJB</b></p><pre class="programlisting">
package com.web_tomorrow.interest;
import java.io.Serializable;
import java.rmi.RemoteException;
@@ -46,7 +46,7 @@
throws RemoteException, CreateException;
}
</pre></div><p>Finally, here is the Bean class. This is the only one that does any
real
-work in this simple example.</p><div class="figure"><p><a name="Nb37"></a><b>Figure
1.3. Bean class for the `interest' EJB</b></p><pre class="programlisting">
+work in this simple example.</p><div class="figure"><p><a name="Nb3f"></a><b>Figure
1.3. Bean class for the `interest' EJB</b></p><pre class="programlisting">
package com.web_tomorrow.interest;
import java.rmi.RemoteException;
@@ -102,15 +102,12 @@
</pre></div><p>Notice that most of the methods are empty; they have to exist
because
they're specified by the SessionBean interface, but they don't need to do
anything in this case.</p><p>If you haven't already done so, you should create
these .java files in
-the directory ./com/web_tomorrow/interest (or unpack the archive with them
+the directory com/web_tomorrow/interest (or unpack the archive with them
in). Then you can compile them using the command
-<b>javac
--classpath/usr/local/jboss/lib/ext/ejb.jarcom/web_tomorrow/interest/*.java</b>
+<b>javac -classpath /usr/local/jboss/client/ejb.jar
com/web_tomorrow/interest/*.java</b>
</p><p>
-substituting the correct path to the JBoss class EJB library if you haven't
+Substituting the correct path to the JBoss class EJB library if you haven't
installed JBoss in /usr/local/jboss. This should create three class files:
-InterestBean.class, Interest.class, and InterestHome.class. If you have `make'
-on your system, and you have unpacked the archive, you can build all the
-classes just be running make in the same directory as the Makefile.
+InterestBean.class, Interest.class, and InterestHome.class.
With the classes compiled, it's time to create the deployment
descriptor.</p></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s07.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch01s09.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.2 +5 -4 newsite/documentation/HTML/ch01s09.html
Index: ch01s09.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01s09.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01s09.html 2001/02/11 16:02:02 1.1
+++ ch01s09.html 2001/03/12 01:54:46 1.2
@@ -1,4 +1,4 @@
-<html><head><title>The deployment descriptor</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="1. First steps"><link
href="ch01s08.html" rel="previous" title="Coding the classes"><link
href="ch01s10.html" rel="next" title="Packaging and deploying the bean"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s08.html"><img border="0" height="65" s!
rc="images/prev.gif" width="76"></a><a href="ch01s10.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="section"
id="Nb52"><div class="titlepage"><h2 class="title" style="clear: all"><a
name="Nb52"></a><span class="title">The deployment descriptor</span></h2></div><p>Now
it's time to create the deployment descriptor. As a reminder, this
+<html><head><title>The deployment descriptor</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="Chapter 1. First steps"><link
href="ch01s08.html" rel="previous" title="Coding the classes"><link
href="ch01s10.html" rel="next" title="Packaging and deploying the bean"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s08.html"><img border="0" heigh!
t="65" src="images/prev.gif" width="76"></a><a href="ch01s10.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="Nb5a"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Nb5a"></a><span class="title">The deployment
descriptor</span></h2></div></div><p>Now it's time to create the deployment
descriptor. As a reminder, this
file tells the EJB server which classes form the Bean, the home interface and
the remote interface. If there is more than one Bean in the package, it
indicates also how the Beans interact with one another. In this simple
@@ -6,7 +6,7 @@
part.</p><p>Most commercial EJB servers are supplied with graphical tools for
constructing the deployment descriptor. JBoss does have an XML editor, but
it's just as easy to construct the deployment descriptor manually. Here it
-is:</p><div class="figure"><p><a name="Nb5d"></a><b>Figure 1.4. Deployment
descriptor for the Interest Bean</b></p><div class="literallayout"> <br>
+is:</p><div class="figure"><p><a name="Nb65"></a><b>Figure 1.4. Deployment
descriptor for the Interest Bean</b></p><div class="literallayout"> <br>
<?xml version="1.0" encoding="Cp1252"?><br>
<ejb-jar><br>
<description>JBoss test application</description><br>
@@ -25,7 +25,8 @@
<br>
</div></div><p>The deployment descriptor must be called ejb-jar.xml and it must be
in
the directory ./META-INF. A common mistake is to name this directory
-`META_INF' (with an underscore, rather than a dash), which won't work.</p><p> In
principle what we deploy on the server is an application, not a
+`META_INF' (with an underscore, rather than a dash) or write it lower
+case, which won't work.</p><p> In principle what we deploy on the server is an
application, not a
Bean. In this example our application consists of exactly one Bean, so it
comes to the same thing. In the deployment descriptor, the section
<ejb-name>Interest</ejb-name> assigns a name to the Bean. jboss
@@ -62,7 +63,7 @@
beans the container will get the ejb-name as the JNDI name as standard
behaviour. This makes your development life easier.</p><p>If you don't provide a
jboss.xml file you will find your bean under the
name "Interest".</p><p>Overriding ejb-name with a real JNDI name in
jboss.xml</p><p>If in deployment you would rather use the "myApp/myBean" naming
pattern
-you need to provide the following text in jboss.xml. </p><p>jboss.xml: ()</p><div
class="figure"><p><a name="Nb8f"></a><b>Figure 1.5. The JBoss XML descriptor.
(Optional, this file is provided by
+you need to provide the following text in jboss.xml. </p><p>jboss.xml: ()</p><div
class="figure"><p><a name="Nb97"></a><b>Figure 1.5. The JBoss XML descriptor.
(Optional, this file is provided by
the Bean deployer)</b></p><div class="literallayout"> <br>
<jboss><br>
<enterprise-beans><br>
1.2 +6 -4 newsite/documentation/HTML/ch01s10.html
Index: ch01s10.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01s10.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01s10.html 2001/02/11 16:02:02 1.1
+++ ch01s10.html 2001/03/12 01:54:46 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Packaging and deploying the bean</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="1. First steps"><link
href="ch01s09.html" rel="previous" title="The deployment descriptor"><link
href="ch01s11.html" rel="next" title="Coding the test client"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s09.html"><img border="0" height="6!
5" src="images/prev.gif" width="76"></a><a href="ch01s11.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section" id="Nba7"><div class="titlepage"><h2 class="title" style="clear:
all"><a name="Nba7"></a><span class="title">Packaging and deploying the
bean</span></h2></div><p>Creation of the Bean package involves building a JAR archive
containing
+<html><head><title>Packaging and deploying the bean</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="Chapter 1. First steps"><link
href="ch01s09.html" rel="previous" title="The deployment descriptor"><link
href="ch01s11.html" rel="next" title="Coding the test client"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s09.html"><img border="0" h!
eight="65" src="images/prev.gif" width="76"></a><a href="ch01s11.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="Nbaf"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Nbaf"></a><span class="title">Packaging and deploying the
bean</span></h2></div></div><p>Creation of the Bean package involves building a JAR
archive containing
the classes and the XML files. For the example Bean we have been discussing,
this is straightforward; at the top of the directory hierarchy run jar like
this:</p><div class="literallayout"><b><br>
@@ -22,8 +22,9 @@
3597 06-15-00 17:20 META-INF/jboss.xml<br>
</tt><br>
</div><p>Note that the directory structure must be exactly like this, or it won't
-work. Again a common mistake is to do a META_INF (underscore) instead of
-META-INF, be careful with this one</p><p>To deploy the Bean on the server, all
that's necessary is to copy the
+work. Again a common mistake is to do a META_INF (underscore) or meta-inf
+(lower case) instead of
+META-INF, be careful with this one.</p><p>To deploy the Bean on the server, all
that's necessary is to copy the
.jar file to the `deploy' directory on the server, e.g.,
<b>cp interest.jar /usr/local/jboss/deploy </b></p><p>You can do this as often as
you like; the server will detect that the
@@ -40,7 +41,8 @@
[Container factory] Deploying:file:/usr/local/jboss/deploy/interest.jar<br>
[Container factory] Deployed application <br>
file:/usr/local/jboss/deploy/interest.jar <br>
-</tt></div><p>then no Beans have been deployed -- the server always reports the
Beans
+</tt><br>
+</div><p>then no Beans have been deployed -- the server always reports the Beans
that it detects. This usually means that the deployment descriptor ejb-jar.xml
is badly structured, or missing, or in the wrong directory. Note that the
server doesn't need to have the CLASSPATH set with your classes it is done
1.2 +4 -4 newsite/documentation/HTML/ch01s11.html
Index: ch01s11.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01s11.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01s11.html 2001/02/11 16:02:03 1.1
+++ ch01s11.html 2001/03/12 01:54:46 1.2
@@ -1,11 +1,11 @@
-<html><head><title>Coding the test client</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="1. First steps"><link
href="ch01s10.html" rel="previous" title="Packaging and deploying the bean"><link
href="ch01s12.html" rel="next" title="Compiling and running test client"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s10.html"><img border="0" h!
eight="65" src="images/prev.gif" width="76"></a><a href="ch01s12.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section" id="Nbf2"><div class="titlepage"><h2 class="title" style="clear:
all"><a name="Nbf2"></a><span class="title">Coding the test
client</span></h2></div><p>An EJB on its own is no use; we will need at least a simple
client to
+<html><head><title>Coding the test client</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="Chapter 1. First steps"><link
href="ch01s10.html" rel="previous" title="Packaging and deploying the bean"><link
href="ch01s12.html" rel="next" title="Compiling and running test client"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s10.html"><img bord!
er="0" height="65" src="images/prev.gif" width="76"></a><a href="ch01s12.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a name="Nbfb"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="Nbfb"></a><span
class="title">Coding the test client</span></h2></div></div><p>An EJB on its own is no
use; we will need at least a simple client to
use its services. A user of EJBs may be another EJB, and ordinary JavaBean, a
JSP page, an applet, or a stand-alone application. In this example, for
simplicity, we will code a simple application. This application will create an
object of class Interest, and execute its one method.</p><p>Upon "deployment" of
the bean as we have seen in the previous step, the
server has generated all the stubs and skeletons needed for the distributed
calls. What we are going to cover here is the way you lookup a reference in
-JNDI from a client and invoke it. It is pretty straightforward.</p><p>Here is the
test client:</p><div class="figure"><p><a name="Nc00"></a><b>Figure 1.6. Test
client</b></p><pre class="programlisting">
+JNDI from a client and invoke it. It is pretty straightforward.</p><p>Here is the
test client:</p><div class="figure"><p><a name="Nc09"></a><b>Figure 1.6. Test
client</b></p><pre class="programlisting">
import javax.naming.*;
import com.web_tomorrow.interest.*;
import java.util.Hashtable;
@@ -81,7 +81,7 @@
"org.jnp.interfaces.NamingContextFactory");
System.setProperty("java.naming.provider.url",
"localhost:1099"); </pre></p><p>There are several other ways to do this, which
you may see described in
-other articles. In this case, the server is on the same machine as the client
+other sections. In this case, the server is on the same machine as the client
(`localhost') and the default naming port is `1099' for JBoss (other servers
may use different port numbers). If you run the client and the server on
different machines, you will need to change these settings.</p><p>The comments in
the program should describe how it works; one point that
@@ -102,5 +102,5 @@
to the client so that the compiler can do the appropriate type checking. In
the example program I have put the client at the top level of the directory
hierachy, so if the CLASSPATH includes the current directory it will correctly
-find the EJB classes which are in the directories beneath it. </p><p><b>javac
-classpath usr/lib/jboss/lib/ext/ejb.jar:.
+find the EJB classes which are in the directories beneath it. </p><p><b>javac
-classpath /usr/local/jboss/client/ejb.jar:.
InterestClient.java</b></p><p>This generates InterestClient.class in the current
directory. </p></div><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch01.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s10.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch01s12.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.2 +7 -6 newsite/documentation/HTML/ch01s12.html
Index: ch01s12.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch01s12.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch01s12.html 2001/02/11 16:02:03 1.1
+++ ch01s12.html 2001/03/12 01:54:46 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Compiling and running test client</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="1. First steps"><link
href="ch01s11.html" rel="previous" title="Coding the test client"><link
href="ch02.html" rel="next" title="2. Basic configuration"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s11.html"><img border="0" height="65" sr!
c="images/prev.gif" width="76"></a><a href="ch02.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="section"
id="Nc39"><div class="titlepage"><h2 class="title" style="clear: all"><a
name="Nc39"></a><span class="title">Compiling and running test
client</span></h2></div><p>We're now ready to run the test client, but first a word of
+<html><head><title>Compiling and running test client</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch01.html" rel="up" title="Chapter 1. First steps"><link
href="ch01s11.html" rel="previous" title="Coding the test client"><link
href="ch02.html" rel="next" title="Chapter 2. Basic configuration"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch01.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s11.html"><img border="0!
" height="65" src="images/prev.gif" width="76"></a><a href="ch02.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="Nc42"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Nc42"></a><span class="title">Compiling and running test
client</span></h2></div></div><p>We're now ready to run the test client, but first a
word of
explanation.</p><p>In reality the client and the server are likely to be on
different
computers. When you compile the client, the compiler needs to know about the
organization and methods of classes in the Bean so it can do type checking.
@@ -19,13 +19,14 @@
doesn't need to have the classpath set, you just need to put it in the deploy
directory and the server will generate a ClassLoader for it.</p><p>If the client
program is at the top of the directory hierarchy, with the
Bean classes below it, then we can run it like this:</p><div
class="literallayout"><b><br>
-java -classpath $$CLASSPATH:\<br>
-/usr/local/jboss/lib/ext/ejb.jar:/usr/local/jboss/client/jboss-client.jar \ <br>
-InterestClient </b></div><p>Once again, this needs to go in a shell script or
a Makefile; you won't
+java -classpath $CLASSPATH:\<br>
+/usr/local/jboss/client/ejb.jar:/usr/local/jboss/client/jboss-client.jar \ <br>
+InterestClient</b><br>
+<br>
+</div><p>Once again, this needs to go in a shell script or a Makefile; you won't
want to type it more than once.</p><p>Note the long CLASSPATH; it needs to include
the JBoss client classes
and the EJB classes as well as the standard classpath (if any).
-If all is well, the test client produces the following output: </p><div
class="literallayout"><br>
-<tt><br>
+If all is well, the test client produces the following output: </p><div
class="literallayout"><tt><br>
Got context<br>
Got reference<br>
Interest on 1000 units, at 10% per period, compounded over 2 periods is:<br>
1.2 +13 -13 newsite/documentation/HTML/ch02.html
Index: ch02.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch02.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch02.html 2001/02/11 16:02:03 1.1
+++ ch02.html 2001/03/12 01:54:46 1.2
@@ -1,13 +1,13 @@
-<html><head><title>2. Basic configuration</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="index.html" rel="up" title="JBoss 2.0 documentation"><link
href="ch01s12.html" rel="previous" title="Compiling and running test client"><link
href="ch03.html" rel="next" title="3. JDBC/Database configuration"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="index.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch01s12.html"><img border!
="0" height="65" src="images/prev.gif" width="76"></a><a href="ch03.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="Nc86"><div
class="titlepage"><h2 class="title"><a name="Nc86">2. Basic
configuration</a></h2></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>
<a href="ch02.html#Nc96">In a nutshell</a></dt></dl></div><p>Author:
+<html><head><title>Chapter 2. Basic configuration</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="index.html" rel="up" title="JBoss 2.0 documentation"><link
href="ch01s12.html" rel="previous" title="Compiling and running test client"><link
href="ch03.html" rel="next" title="Chapter 3. JDBC/Database
configuration"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s12.h!
tml"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch03.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="Nc8f"><div
class="titlepage"><div><h2 class="title"><a name="Nc8f"></a>Chapter 2. Basic
configuration</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>
<a href="ch02.html#Nc9f">In a nutshell</a></dt></dl></div><p>Author:
<span class="author">Aaron Mulder</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
-</p><div class="section" id="Nc96"><div class="titlepage"><h2 class="title"
style="clear: all"><a name="Nc96"></a><span class="title">In a
nutshell</span></h2></div><p>
+</p><div class="section"><a name="Nc9f"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="Nc9f"></a><span class="title">In a
nutshell</span></h2></div></div><p>
JBoss ships preconfigured, so there's nothing you need to do to get it up and
running with the test beans. However, you
will likely need to make minor configuration changes to support your specific
applications. This section gives an
overview of the configuration files and directories. The Advanced Configuration
section gives detailed instructions for
specific configuration changes you may require. The Appendix contains DTDs for the
configuration files, which gives the
-exact information.</p><div class="section" id="Nc9d"><div class="titlepage"><h3
class="title"><a name="Nc9d"></a><span class="title">Important
Directories</span></h3></div><p>
-The directory names given here are all relative to the directory you installed
JBoss into.</p></div><div class="section" id="Nca5"><div class="titlepage"><h3
class="title"><a name="Nca5"></a><span class="title">Executables</span></h3></div><p>
+exact information.</p><div class="section"><a name="Nca6"></a><div
class="titlepage"><div><h3 class="title"><a name="Nca6"></a><span
class="title">Important Directories</span></h3></div></div><p>
+The directory names given here are all relative to the directory you installed
JBoss into.</p></div><div class="section"><a name="Ncae"></a><div
class="titlepage"><div><h3 class="title"><a name="Ncae"></a><span
class="title">Executables</span></h3></div></div><p>
Executables are located in the bin directory. Using the Batch (Windows) or Shell
(UNIX) scripts here, you can start the
server or run the test bean client. You can also run the EJX deployment descriptor
editor by double-clicking on it (if
your platform supports that) or issuing the command:
@@ -15,34 +15,34 @@
<b>
java -jar ejx.jar
</b>
-</p></div><div class="section" id="Ncb2"><div class="titlepage"><h3
class="title"><a name="Ncb2"></a><span class="title">Configuration</span></h3></div><p>
+</p></div><div class="section"><a name="Ncbb"></a><div class="titlepage"><div><h3
class="title"><a name="Ncbb"></a><span
class="title">Configuration</span></h3></div></div><p>
Configuration files are located in the conf directory. These files configure the
server as a whole, so the settings here will
-be the same for all EJBs.</p></div><div class="section" id="Ncba"><div
class="titlepage"><h3 class="title"><a name="Ncba"></a><span
class="title">Libraries</span></h3></div><p>
+be the same for all EJBs.</p></div><div class="section"><a name="Ncc3"></a><div
class="titlepage"><div><h3 class="title"><a name="Ncc3"></a><span
class="title">Libraries</span></h3></div></div><p>
Java libraries are located in the lib directory. They should use either the ZIP or
JAR format. All libraries in this directory
will automatically be added to the server classpath. Again, this should only be
used for libraries which need to be
available to all EJBs; there are alternatives for libraries that should be
available to individual EJB JARs (see The
-Manifest File in the Deploying EJBs in jBoss section).</p></div><div
class="section" id="Ncc2"><div class="titlepage"><h3 class="title"><a
name="Ncc2"></a><span class="title">EJBs</span></h3></div><p>
+Manifest File in the Deploying EJBs in jBoss section).</p></div><div
class="section"><a name="Nccb"></a><div class="titlepage"><div><h3 class="title"><a
name="Nccb"></a><span class="title">EJBs</span></h3></div></div><p>
EJB JARs you want to deploy go in the deploy directory. If the server is running,
they will be deployed automatically. If
-you delete a JAR it will be undeployed, and if you update it it will be
redeployed.</p></div><div class="section" id="Ncca"><div class="titlepage"><h3
class="title"><a name="Ncca"></a><span class="title">Client
Libraries</span></h3></div><p>
+you delete a JAR it will be undeployed, and if you update it it will be
redeployed.</p></div><div class="section"><a name="Ncd3"></a><div
class="titlepage"><div><h3 class="title"><a name="Ncd3"></a><span class="title">Client
Libraries</span></h3></div></div><p>
Libraries required for clients are in the client directory. A typical client
requires jboss-client.jar,
jnp-client.jar, ejb.jar, and jta-spec1_0_1.jar. If you client is not running JDK
1.3, it will require
-jndi.jar as well.</p></div><div class="section" id="Ncd2"><div
class="titlepage"><h3 class="title"><a name="Ncd2"></a><span
class="title">Configuration Files</span></h3></div><p>
+jndi.jar as well.</p></div><div class="section"><a name="Ncdb"></a><div
class="titlepage"><div><h3 class="title"><a name="Ncdb"></a><span
class="title">Configuration Files</span></h3></div></div><p>
There are a number of configuration files for jBoss. The contents of each are give
here, though you should refer to the
Advanced Configuration section and the DTDs section of the Appendix for details on
the specific settings.</p><p>
You may create more than one set of configuration files as long as the base
filename is the same for all files in the set
and the extensions are not changed. For example, you could copy jboss.conf,
jboss.jcml, ... to
myconfig.conf, myconfig.jcml, ... To start jboss with a different set of
configuration files, add the base name
-of the configuration file set to the command or script you use to start jBoss (for
example, "run.sh myconfig").</p><div class="table"><p><a name="Ncdc"></a><b>Table 2.1.
Configuration files</b></p><table border="1" summary="Configuration
files"><colgroup><col><col></colgroup><thead><tr><th>File</th><th>Description</th></tr></thead><tbody><tr><td>jboss.conf</td><td>Lists
server components that should be loaded. Each must be a JMX
MBean</td></tr><tr><td>jboss.jcml</td><td>Lists configuration parameters for the
server components loaded in
jboss.conf</td></tr><tr><td>jboss.properties</td><td>Provides parameters to the Java
runtime (the entries here become system
properties)</td></tr><tr><td>jboss.dependencies</td><td>Lists dependencies between the
MBeans loaded in jboss.conf, so they can be loaded and
+of the configuration file set to the command or script you use to start jBoss (for
example, "run.sh myconfig").</p><div class="table"><p><a name="Nce5"></a><b>Table 2.1.
Configuration files</b></p><table border="1" summary="Configuration
files"><thead><tr><th>File</th><th>Description</th></tr></thead><tbody><tr><td>jboss.conf</td><td>Lists
server components that should be loaded. Each must be a JMX
MBean</td></tr><tr><td>jboss.jcml</td><td>Lists configuration parameters for the
server components loaded in
jboss.conf</td></tr><tr><td>jboss.properties</td><td>Provides parameters to the Java
runtime (the entries here become system
properties)</td></tr><tr><td>jboss.dependencies</td><td>Lists dependencies between the
MBeans loaded in jboss.conf, so they can be loaded and
stopped in the correct
order</td></tr><tr><td>jnp.properties</td><td>Lists properties for the JNDI server
implementation</td></tr><tr><td>jndi.properties</td><td>Lists properties for the JNDI
client implementation. You can achieve the same thing by
hardcoding the properties, passing them on the command line, or
putting this file on the client
classpath. We recommend putting this on the classpath since it is
easiest to use and easiest to
change. You have to hardcode the properties if you want to look up
beans on more than one
server, though.</td></tr><tr><td>server.policy</td><td>The default
security policy for the jBoss server. Currently, this is set to allow all permissions.
In
- a future release it will be locked down
more.</td></tr></tbody></table></div></div><div class="section" id="Nd35"><div
class="titlepage"><h3 class="title"><a name="Nd35"></a><span class="title">Clients on
Remote Machines</span></h3></div><p>
+ a future release it will be locked down
more.</td></tr></tbody></table></div></div><div class="section"><a
name="Nd3e"></a><div class="titlepage"><div><h3 class="title"><a name="Nd3e"></a><span
class="title">Clients on Remote Machines</span></h3></div></div><p>
The default configuration assumes client will run on the same machine as the jBoss
server. While often appropriate for
-servlet and JSP clients, you need to make minor changes to support remote
clients.</p><div class="orderedlist"><ol type="1"><li><a name="Nd42"></a><p>Change
jboss.properties. The properties java.rmi.server.useLocalHostName and
+servlet and JSP clients, you need to make minor changes to support remote
clients.</p><div class="orderedlist"><ol type="1"><li><p><a name="Nd4b"></a>Change
jboss.properties. The properties java.rmi.server.useLocalHostName and
java.rmi.server.hostname should either both be commented out, or
useLocalHostName should be
set to true and hostname should be set to the host name of your server (the
name you want your clients to
- use, if your server has more than one). </p></li><li><a name="Nd46"></a><p>Set
the JNDI properties for your clients appropriately. If you choose to put
jndi.properties on the client classpath
+ use, if your server has more than one). </p></li><li><p><a name="Nd4f"></a>Set
the JNDI properties for your clients appropriately. If you choose to put
jndi.properties on the client classpath
(which is recommended), you should change the value for
java.naming.provider.url to the host
name of your server (again, the name you want your clients to use).
</p></li></ol></div></div></div></div><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/gbar.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch01s12.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch03.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.2 +6 -6 newsite/documentation/HTML/ch03.html
Index: ch03.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch03.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch03.html 2001/02/11 16:02:03 1.1
+++ ch03.html 2001/03/12 01:54:46 1.2
@@ -1,7 +1,7 @@
-<html><head><title>3. JDBC/Database configuration</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="index.html" rel="up" title="JBoss 2.0 documentation"><link
href="ch02.html" rel="previous" title="2. Basic configuration"><link
href="ch03s05.html" rel="next" title="Creating DB Connection Pools"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="index.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch02.html"><img border="0" hei!
ght="65" src="images/prev.gif" width="76"></a><a href="ch03s05.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="chapter" id="Nd4e"><div class="titlepage"><h2 class="title"><a name="Nd4e">3.
JDBC/Database configuration</a></h2></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="ch03.html#Nd5e">Introduction</a></dt><dt> <a
href="ch03s05.html">Creating DB Connection Pools</a></dt></dl></div><p>Author:
+<html><head><title>Chapter 3. JDBC/Database configuration</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="index.html" rel="up" title="JBoss 2.0
documentation"><link href="ch02.html" rel="previous" title="Chapter 2. Basic
configuration"><link href="ch03s05.html" rel="next" title="Creating DB Connection
Pools"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch02.html"><im!
g border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch03s05.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="Nd57"><div
class="titlepage"><div><h2 class="title"><a name="Nd57"></a>Chapter 3. JDBC/Database
configuration</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>
<a href="ch03.html#Nd67">Introduction</a></dt><dt> <a href="ch03s05.html">Creating DB
Connection Pools</a></dt></dl></div><p>Author:
<span class="author">Aaron Mulder</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
-</p><div class="section" id="Nd5e"><div class="titlepage"><h2 class="title"
style="clear: all"><a name="Nd5e"></a><span
class="title">Introduction</span></h2></div><div class="section" id="Nd62"><div
class="titlepage"><h3 class="title"><a name="Nd62"></a><span class="title">Data
Sources</span></h3></div><p>
+</p><div class="section"><a name="Nd67"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="Nd67"></a><span
class="title">Introduction</span></h2></div></div><div class="section"><a
name="Nd6b"></a><div class="titlepage"><div><h3 class="title"><a name="Nd6b"></a><span
class="title">Data Sources</span></h3></div></div><p>
One of the most common requirements is to create one or more data sources for your
EJBs. You must create a data source for CMP entity beans, and it is
the recommended way to interact with a database for BMP entity beans and session
beans.</p><p>
JBoss data sources provide database connection pooling. This means that when your
application closes a connection, it is not really closed, just returned
@@ -12,13 +12,13 @@
Supported Databases
JBoss supports any database with a JDBC driver. We recommend pure java drivers
(type 3 or type 4), and specifically suggest you do not use the
-JDBC-ODBC bridge (type 1).</p></div><div class="section" id="Nd70"><div
class="titlepage"><h3 class="title"><a name="Nd70"></a><span class="title">Mappings
Available for CMP Entities</span></h3></div><p>
+JDBC-ODBC bridge (type 1).</p></div><div class="section"><a name="Nd79"></a><div
class="titlepage"><div><h3 class="title"><a name="Nd79"></a><span
class="title">Mappings Available for CMP Entities</span></h3></div></div><p>
If we have not worked with a database product before we may need to work with you
to generate a type mapping if you plan to use container managed
persistence. The mappings we have tested extensively include PostgreSQL, InstantDB,
Hypersonic SQL, Oracle 7, Oracle 8, Sybase, DB2, and
InterBase. Additional contributed mappings include PointBase, SOLID, mySQL, MS SQL
Server, and DB2/400. If you would like to support CMP for
another DBMS, or have a working mapping to share, please contact the JBoss Mailing
List.
-</p></div><div class="section" id="Nd78"><div class="titlepage"><h3
class="title"><a name="Nd78"></a><span class="title">Installing JDBC
Drivers</span></h3></div><p>
-To install a JDBC driver, it must be distributed as one or more ZIP or JAR files.
You should copy those files to the lib/ext directory under your JBoss
+</p></div><div class="section"><a name="Nd81"></a><div class="titlepage"><div><h3
class="title"><a name="Nd81"></a><span class="title">Installing JDBC
Drivers</span></h3></div></div><p>
+To install a JDBC driver, it must be distributed as one or more ZIP or JAR files.
You should copy those files to the <tt>lib/ext</tt> directory under your JBoss
installation directory. In addition, you need to change one line in the file
jboss.properties located in the conf directory. Find the property named
jdbc.drivers, and add your product's driver class name to the list of drivers. The
drivers in the list should be separated by commas. Here's an
example line, listing drivers for Oracle and Sybase:
@@ -28,7 +28,7 @@
</p><p>
The next time you start JBoss, you should see output like the following listing
each driver that was loaded. If instead you see an error for the driver (also
-shown below), make sure that you installed the required ZIPs and/or JARs to the
lib/ext directory.
+shown below), make sure that you installed the required ZIPs and/or JARs to the
<tt>lib/ext</tt> directory.
<tt>
[JDBC] Loaded JDBC-driver:oracle.jdbc.driver.OracleDriver
1.2 +195 -174 newsite/documentation/HTML/ch03s05.html
Index: ch03s05.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch03s05.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch03s05.html 2001/02/11 16:02:03 1.1
+++ ch03s05.html 2001/03/12 01:54:46 1.2
@@ -1,8 +1,8 @@
-<html><head><title>Creating DB Connection Pools</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch03.html" rel="up" title="3. JDBC/Database
configuration"><link href="ch03.html" rel="previous" title="3. JDBC/Database
configuration"><link href="ch04.html" rel="next" title="4. Using container-managed
persistence"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch03.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch03.html"><!
img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch04.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="Nd8e"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="Nd8e"></a><span
class="title">Creating DB Connection Pools</span></h2></div><p>
+<html><head><title>Creating DB Connection Pools</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch03.html" rel="up" title="Chapter 3. JDBC/Database
configuration"><link href="ch03.html" rel="previous" title="Chapter 3. JDBC/Database
configuration"><link href="ch04.html" rel="next" title="Chapter 4. Using
container-managed persistence"></head><body alink="#0000FF" bgcolor="white"
link="#0000FF" text="black" vlink="#840084"><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/jboss.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch03.html"><img border="0" height="65"
src="images/toc.gif" width="60"><!
/a><a href="ch03.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch04.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a name="Nda1"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="Nda1"></a><span
class="title">Creating DB Connection Pools</span></h2></div></div><p>
Once your JDBC driver is installed, you can add one or more connection pools that
use it. Any number of EJBs may share one connection pool, but you
may want to create multiple pools for a number of reasons. For example, you may
want a dedicated pool for an application that requires very high reponse
time, while other applications share a pool of limited size.</p><p>
-To add a pool, you need to add sections to jboss.conf and jboss.jcml, both of which
can be found in the conf directory.</p><div class="section" id="Nd98"><div
class="titlepage"><h3 class="title"><a name="Nd98"></a><span class="title">The JDBC
2.0 Optional Package</span></h3></div><p>
+To add a pool, you need to add sections to jboss.conf and jboss.jcml, both of which
can be found in the conf directory.</p><div class="section"><a name="Ndab"></a><div
class="titlepage"><div><h3 class="title"><a name="Ndab"></a><span class="title">The
JDBC 2.0 Optional Package</span></h3></div></div><p>
Before we configure the pool, we need to take a brief detour into specifications.
The JDBC API distributed with JDKs 1.1 through 1.3 defines a transaction
for every connection. It is not possible to have more than one connection in a
transaction, or to use a single connection for more than one transaction at a
time.</p><p>
@@ -16,28 +16,26 @@
You must determine whether your driver supports the JDBC 2.0 Optional Package in
order to configure JBoss appropriately. If it does not, JBoss will
simulate it so that your EJBs will operate appropriately, but there are two
important restrictions:
- <div class="orderedlist"><ol type="1"><li><a name="Ndad"></a><p>If you request
more than one connection from a DataSource in the context of the same transaction,
JBoss will return the same connection every
- time. This is so changes made by one bean will be visible to other beans
operating in the same transaction.</p></li><li><a name="Ndb1"></a><p>The connections
cannot determine ahead of time whether it is possible for them to commit, so they
cannot participate fully in the two-phase
+ <div class="orderedlist"><ol type="1"><li><p><a name="Ndc0"></a>If you request
more than one connection from a DataSource in the context of the same transaction,
JBoss will return the same connection every
+ time. This is so changes made by one bean will be visible to other beans
operating in the same transaction.</p></li><li><p><a name="Ndc4"></a>The connections
cannot determine ahead of time whether it is possible for them to commit, so they
cannot participate fully in the two-phase
commit protocol used to commit multiple data sources. This means that if
there's a problem with one of the data sources, some may commit and
others may rollback. This is why we want all DB vendors to fully support the
JDBC 2.0 Optional Package.</p></li></ol></div>
-</p></div><div class="section" id="Ndb8"><div class="titlepage"><h3
class="title"><a name="Ndb8"></a><span class="title">Configuration File
Changes</span></h3></div><p>
+</p></div><div class="section"><a name="Ndcb"></a><div class="titlepage"><div><h3
class="title"><a name="Ndcb"></a><span class="title">Configuration File
Changes</span></h3></div></div><p>
First, you need to add a section to jboss.conf for each pool. This declares a JMX
service (an MBean) for the the pool. There's a sample below. It
does not matter where in the file you add these lines; the startup order is not
dependent on the order of services in the file. You should make the following
changes to customize your pool:
- <div class="itemizedlist"><ul><li><a name="Ndc0"></a><p>In the first line, you
should replace "vendor.jar" with the name of the ZIPs or JARs you added to the lib/ext
directory when you configured
- the driver</p></li><li><a name="Ndc4"></a><p>
- Enter the name you want to use for this pool instead of "PoolName" for the
first argument.</p></li><li><a name="Ndc8"></a><p>If your driver supports the JDBC 2.0
Optional Package, you should use the class name of the vendor's XADataSource
implementation for the
+ <div class="itemizedlist"><ul><li><p><a name="Ndd3"></a>In the first line, you
should replace "vendor.jar" with the name of the ZIPs or JARs you added to the
<tt>lib/ext</tt> directory when you configured
+ the driver</p></li><li><p><a name="Nddc"></a>
+ Enter the name you want to use for this pool instead of "PoolName" for the
first argument.</p></li><li><p><a name="Nde0"></a>If your driver supports the JDBC 2.0
Optional Package, you should use the class name of the vendor's XADataSource
implementation for the
second argument. Otherwise, use the JBoss class name shown.</p></li></ul></div>
-
<pre class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar,vendor.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="PoolName">
<ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre>
-
</p><p>
Second, you must add a section to jboss.jcml for each pool. This declares all the
parameters for the pool, such as the size, username and password
to use, etc. The parameters will be covered in detail next. The block you need to
add is shown below. You only need to add lines for the parameters you
@@ -52,11 +50,10 @@
<attribute name="Password">tiger</attribute>
</mbean>
</pre>
-
-</p><div class="section" id="Nddb"><div class="titlepage"><h4 class="title"><a
name="Nddb"></a><span class="title">Connection Pool Parameters</span></h4></div><p>
+</p><div class="section"><a name="Ndf3"></a><div class="titlepage"><div><h4
class="title"><a name="Ndf3"></a><span class="title">Connection Pool
Parameters</span></h4></div></div><p>
Here is the list of possible parameters for each pool's entry in jboss.jcml. Again,
after you run
JBoss once with your new pool, it will add entries for all of these to jboss.jcml,
using the default
-values for anything you didn't specify.</p><div class="table"><p><a
name="Nde2"></a><b>Table 3.1. Connection pool parameters</b></p><table border="1"
summary="Connection pool
parameters"><colgroup><col><col><col></colgroup><thead><tr><th>Name</th><th>Connection
pool parameters</th><th>default</th></tr></thead><tbody><tr><td>URL</td><td>The JDBC
URL used to connect to the data
source</td><td> </td></tr><tr><td>JDBCUser</td><td>The user name used to connect
to the data source.</td><td> </td></tr><tr><td>Password</td><td>The password used
to connect to the data source.</td><td> </td></tr><tr><td>Properties</td><td>Any
properties required to connect to the data source. This should
+values for anything you didn't specify.</p><div class="table"><p><a
name="Ndfa"></a><b>Table 3.1. Connection pool parameters</b></p><table border="1"
summary="Connection pool parameters"><thead><tr><th>Name</th><th>Connection pool
parameters</th><th>default</th></tr></thead><tbody><tr><td>URL</td><td>The JDBC URL
used to connect to the data
source</td><td> </td></tr><tr><td>JDBCUser</td><td>The user name used to connect
to the data source.</td><td> </td></tr><tr><td>Password</td><td>The password used
to connect to the data source.</td><td> </td></tr><tr><td>Properties</td><td>Any
properties required to connect to the data source. This should
be expressed in a String of the form
name=value;name=value;name=value....</td><td> </td></tr><tr><td>MinSize</td><td>The
minimum size of the pool. The pool always starts with one
instance, but if shrinking is enabled the pool will never
fall below
@@ -109,192 +106,216 @@
query, navigating on a ResultSet, etc.). If not, the last
used time will
only be updated when the object is given to a client and
returned to
the pool. This time is important if shrinking or garbage
collection are
- enabled (particularly the
latter).</td><td>false</td></tr></tbody></table></div></div></div><div class="section"
id="Neb0"><div class="titlepage"><h3 class="title"><a name="Neb0"></a><span
class="title">Connection Pool Configuration Examples and Driver
Notes</span></h3></div><p>
+ enabled (particularly the
latter).</td><td>false</td></tr></tbody></table></div></div></div><div
class="section"><a name="Nec8"></a><div class="titlepage"><div><h3 class="title"><a
name="Nec8"></a><span class="title">Connection Pool Configuration Examples and Driver
Notes</span></h3></div></div><p>
Here are some sample database pool configuration file exerpts for a variety of
database products. Note that your configuration may differ slightly if you're
-using a different version, different JDBC driver, etc. The parameters you are most
likely to need to change are in bold.</p><div class="itemizedlist"><ul><li><a
name="Neb9"></a><p>Oracle 8i with native JDBC 2 Optional Package XADataSource</p><div
class="itemizedlist"><ul><li><a name="Nebf"></a><div
class="literallayout">Driver Notes <br>
+using a different version, different JDBC driver, etc. The parameters you are most
likely to need to change are in bold.</p><div class="itemizedlist"><ul><li><p><a
name="Ned1"></a>Oracle 8i with native JDBC 2 Optional Package XADataSource</p><div
class="itemizedlist"><ul><li><a name="Ned7"></a><div
class="literallayout">Driver Notes <br>
Extreme Float or Double values will cause SQLExceptions <br>
The Oracle XADataSource requires the Oracle Xid implementation. Other vendor's XADataSource implementation may or may<br>
- not be able to interoperate.</div></li><li><a
name="Nec7"></a><p>lib/ext: classes12.zip</p></li><li><a
name="Necb"></a><p>jboss.properties</p><pre class="programlisting">
- jboss.xa.xidclass=oracle.jdbc.xa.OracleXid
- </pre></li><li><a name="Ned5"></a><p>jboss.conf</p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="OracleDB">
- <ARG TYPE="java.lang.String"
VALUE="oracle.jdbc.xa.client.OracleXADataSource">
- </MLET>
- </pre></li><li><a name="Nedf"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean name="DefaultDomain:service=XADataSource,name=OracleDB">
- <attribute
name="URL">jdbc:oracle:thin:@host.domain.com:1521:instance</attribute>
- <attribute name="JDBCUser">scott</attribute>
- <attribute name="Password">tiger</attribute>
- </mbean>
- </pre></li><li><a name="Nee9"></a><p>CMP Type Mapping Names (for
jaws.xml): Oracle8 </p></li></ul></div></li><li><a name="Neef"></a><p>Oracle
7.x,8.x,8i with JDBC 1/2 Wrapper
- This configuration is reported to be outdated. It is still here for reference
for older versions.</p><div class="itemizedlist"><ul><li><a name="Nef5"></a><div
class="literallayout">Driver Notes <br>
+ not be able to interoperate.</div></li><li><p><a
name="Nedf"></a>lib/ext: classes12.zip</p></li><li><p><a
name="Nee3"></a>jboss.properties</p><pre class="programlisting">
+jboss.xa.xidclass=oracle.jdbc.xa.OracleXid
+ </pre></li><li><p><a name="Need"></a>jboss.conf</p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="OracleDB">
+ <ARG TYPE="java.lang.String"
VALUE="oracle.jdbc.xa.client.OracleXADataSource">
+</MLET>
+ </pre></li><li><p><a name="Nef7"></a>jboss.jcml</p><pre
class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=OracleDB">
+ <attribute
name="URL">jdbc:oracle:thin:@host.domain.com:1521:instance</attribute>
+ <attribute name="JDBCUser">scott</attribute>
+ <attribute name="Password">tiger</attribute>
+</mbean>
+</pre></li><li><p><a name="Nf01"></a>CMP Type Mapping Names (for jaws.xml): Oracle8
</p></li></ul></div></li><li><p><a name="Nf07"></a>Oracle 7.x,8.x,8i with JDBC 1/2
Wrapper
+ This configuration is reported to be outdated. It is still here for reference
for older versions.</p><div class="itemizedlist"><ul><li><a name="Nf0d"></a><div
class="literallayout">Driver Notes <br>
For CMP Entity Beans, Oracle 7 only allows 1 serialized Java Object per bean (column type LONG RAW). Oracle 8 does not have<br>
this limitation (column type BLOB). <br>
- Extreme Float or Double values will cause SQLExceptions </div></li><li><a
name="Nefd"></a><p>lib/ext: classes12.zip</p></li><li><a
name="Nf01"></a><p>jboss.properties</p><pre class="programlisting">
- jdbc.drivers=oracle.jdbc.driver.OracleDriver
- </pre></li><li><a name="Nf0b"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="OracleDB">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
- </pre></li><li><a name="Nf15"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean name="DefaultDomain:service=XADataSource,name=OracleDB">
- <attribute
name="URL">jdbc:oracle:thin:@host.domain.com:1521:instance</attribute>
- <attribute name="JDBCUser">scott</attribute>
- <attribute name="Password">tiger</attribute>
- </mbean>
- </pre></li><li><a name="Nf1f"></a><p>CMP Type Mapping Names (for
jaws.xml): Oracle7 and Oracle8 </p></li></ul></div></li><li><a
name="Nf25"></a><p>Hypersonic</p><div class="itemizedlist"><ul><li><a
name="Nf2b"></a><p>lib/ext: hsql.jar</p></li><li><a
name="Nf2f"></a><p>jboss.properties</p><pre class="programlisting">
- jdbc.drivers=org.hsql.jdbcDriver
- </pre></li><li><a name="Nf39"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="Hypersonic">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
- </pre></li><li><a name="Nf43"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean
name="DefaultDomain:service=XADataSource,name=Hypersonic">
- <attribute
name="URL">jdbc:HypersonicSQL:hsql://localhost</attribute>
- <attribute name="JDBCUser">sa</attribute>
- </mbean>
- </pre></li><li><a name="Nf4d"></a><p>CMP Type Mapping Names (for
jaws.xml): Hypersonic SQL </p></li></ul></div></li><li><a name="Nf53"></a><p>DB2
7.1</p><div class="itemizedlist"><ul><li><a name="Nf59"></a><div
class="literallayout">Driver Notes <br>
+ Extreme Float or Double values will cause SQLExceptions </div></li><li><p><a
name="Nf15"></a>lib/ext: classes12.zip</p></li><li><p><a
name="Nf19"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=oracle.jdbc.driver.OracleDriver
+ </pre></li><li><p><a name="Nf23"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="OracleDB">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+</pre></li><li><p><a name="Nf2d"></a>jboss.jcml</p><pre class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=OracleDB">
+ <attribute
name="URL">jdbc:oracle:thin:@host.domain.com:1521:instance</attribute>
+ <attribute name="JDBCUser">scott</attribute>
+ <attribute name="Password">tiger</attribute>
+</mbean>
+</pre></li><li><p><a name="Nf37"></a>CMP Type Mapping Names (for jaws.xml): Oracle7
and Oracle8 </p></li></ul></div></li><li><p><a name="Nf3d"></a>Hypersonic</p><div
class="itemizedlist"><ul><li><p><a name="Nf43"></a>lib/ext: hsql.jar</p></li><li><p><a
name="Nf47"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=org.hsql.jdbcDriver
+ </pre></li><li><p><a name="Nf51"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="Hypersonic">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+</pre></li><li><p><a name="Nf5b"></a>jboss.jcml</p><pre class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=Hypersonic">
+ <attribute name="URL">jdbc:HypersonicSQL:hsql://localhost</attribute>
+ <attribute name="JDBCUser">sa</attribute>
+</mbean>
+</pre></li><li><p><a name="Nf65"></a>CMP Type Mapping Names (for jaws.xml):
Hypersonic SQL </p></li></ul></div></li><li><p><a name="Nf6b"></a>DB2 7.1</p><div
class="itemizedlist"><ul><li><a name="Nf71"></a><div
class="literallayout">Driver Notes <br>
DB2 does not support variables of type "byte", so with CMP entities they will be serialized. We recommend that you use short or int<br>
variables to avoid this. <br>
For CMP entities, serialized objects are stored as type BLOB(n), where n is 2000 by default. If you plan to serialize objects larger<br>
than 2000 bytes, you will need to alter the mapping or create the table manually. <br>
Extreme Float or Double values will cause SQLExceptions and may corrupt the driver so that further actions fail. <br>
The "net" driver (type 4) is preferred over the "app" driver (type 2), though only the "app" driver has a native XADataSource<br>
- implementation. To use the "net" driver, you must run the "db2jstrt [port]" tool on your DB server. </div></li><li><a
name="Nf61"></a><p>lib/ext: db2java.zip</p></li><li><a
name="Nf65"></a><p>jboss.properties</p><pre class="programlisting">
- jdbc.drivers=COM.ibm.db2.jdbc.net.DB2Driver
- </pre></li><li><a name="Nf6f"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="DB2">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
-
- </pre></li><li><a name="Nf79"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean name="DefaultDomain:service=XADataSource,name=DB2">
- <attribute
name="URL">jdbc:db2://host.domain.com:port/database</attribute>
- <attribute name="JDBCUser">username</attribute>
- <attribute name="Password">password</attribute>
- </mbean>
- </pre></li><li><a name="Nf83"></a><p>CMP Type Mapping Names (for
jaws.xml):DB2 </p></li></ul></div></li><li><a name="Nf89"></a><p>DB2/400</p><div
class="itemizedlist"><ul><li><a name="Nf8f"></a><p>lib/ext: jt400.jar </p></li><li><a
name="Nf93"></a><p>jboss.properties</p><pre class="programlisting">
- jdbc.drivers=com.ibm.as400.access.AS400JDBCDriver
- </pre></li><li><a name="Nf9d"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="AS400">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
-
- </pre></li><li><a name="Nfa7"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean name="DefaultDomain:service=XADataSource,name=AS400">
- <attribute name="URL">jdbc:as400://hostname</attribute>
- <attribute name="JDBCUser">user</attribute>
- <attribute name="Password">pw</attribute>
- </mbean>
- </pre></li><li><a name="Nfb1"></a><p>CMP Type Mapping Names (for
jaws.xml):DB2/400 </p></li></ul></div></li><li><a name="Nfb7"></a><p>Sybase Adaptive
Server Anywhere 6.x, Adaptive Server Enterprise 11.9.x, 12.x </p><div
class="itemizedlist"><ul><li><a name="Nfbd"></a><div
class="literallayout">Driver Notes <br>
+ implementation. To use the "net" driver, you must run the "db2jstrt [port]" tool on your DB server. </div></li><li><p><a
name="Nf79"></a>lib/ext: db2java.zip</p></li><li><p><a
name="Nf7d"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=COM.ibm.db2.jdbc.net.DB2Driver
+ </pre></li><li><p><a name="Nf87"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="DB2">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+</pre></li><li><p><a name="Nf91"></a>jboss.jcml</p><pre class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=DB2">
+ <attribute
name="URL">jdbc:db2://host.domain.com:port/database</attribute>
+ <attribute name="JDBCUser">username</attribute>
+ <attribute name="Password">password</attribute>
+</mbean>
+</pre></li><li><p><a name="Nf9b"></a>CMP Type Mapping Names (for jaws.xml):DB2
</p></li></ul></div></li><li><p><a name="Nfa1"></a>DB2/400</p><div
class="itemizedlist"><ul><li><p><a name="Nfa7"></a>lib/ext: jt400.jar
</p></li><li><p><a name="Nfab"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=com.ibm.as400.access.AS400JDBCDriver
+ </pre></li><li><p><a name="Nfb5"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="AS400">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+</pre></li><li><p><a name="Nfbf"></a>jboss.jcml</p><pre class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=AS400">
+ <attribute name="URL">jdbc:as400://hostname</attribute>
+ <attribute name="JDBCUser">user</attribute>
+ <attribute name="Password">pw</attribute>
+</mbean>
+</pre></li><li><p><a name="Nfc9"></a>CMP Type Mapping Names (for jaws.xml):DB2/400
</p></li></ul></div></li><li><p><a name="Nfcf"></a>Sybase Adaptive Server Anywhere
6.x, Adaptive Server Enterprise 11.9.x, 12.x </p><div class="itemizedlist"><ul><li><a
name="Nfd5"></a><div class="literallayout">Driver Notes <br>
You must install jConnect 5.2, including the stored procedures which are distributed with the jConnect package. There are<br>
directions for this in the Installation Instructions chapter of the jConnect for JDBC Installation Guide. <br>
JAWS cannot create a table automatically for CMP Entity beans (the server rejects DDL within a transaction) <br>
The jConnect 5.2 JDBC driver does not support variables of type byte or short, so they will be serialized (column type must be<br>
- varbinary or image). We recommend you use int variables instead to avoid this. </div></li><li><a
name="Nfc5"></a><p>lib/ext:jconn2.jar</p></li><li><a
name="Nfc9"></a><p>jboss.properties</p><pre class="programlisting">
- jdbc.drivers=com.sybase.jdbc2.jdbc.SybDriver
- </pre></li><li><a name="Nfd3"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="SybaseDB">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
-
- </pre></li><li><a name="Nfdd"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean name="DefaultDomain:service=XADataSource,name=SybaseDB">
- <attribute
name="URL">jdbc:sybase:Tds:host.domain.com:4100/database</attribute>
- <attribute name="Password">password</attribute>
- <attribute name="JDBCUser">username</attribute>
- </mbean>
- </pre></li><li><a name="Nfe7"></a><p>CMP Type Mapping Names (for
jaws.xml):Sybase</p></li></ul></div></li><li><a name="Nfed"></a><p>PostgreSQL 7.x
</p><div class="itemizedlist"><ul><li><a name="Nff3"></a><div
class="literallayout">Driver Notes <br>
- Extreme Java "long" values will cause SQLExceptions and may corrupt the driver so that further actions fail. </div></li><li><a
name="Nffb"></a><p>lib/ext:jdbc7.0-1.2.jar</p></li><li><a
name="Nfff"></a><p>jboss.properties</p><pre class="programlisting">
- jdbc.drivers=org.postgresql.Driver
- </pre></li><li><a name="N1009"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="PostgresDB">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
- </pre></li><li><a name="N1013"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean
name="DefaultDomain:service=XADataSource,name=PostgresDB">
- <attribute
name="URL">jdbc:postgresql://host.domain.com/database</attribute>
- <attribute name="JDBCUser">postgres</attribute>
- <attribute name="Password">foo</attribute>
- </mbean>
- </pre><p>Note: You must include a user name and password. They can be
bogus if your PostgreSQL installation is configured to "trust" the machine
- you're coming from, but you can't leave them out.</p></li><li><a
name="N1020"></a><p>CMP Type Mapping Names (for jaws.xml):PostgreSQL
</p></li></ul></div></li><li><a name="N1026"></a><p>Interbase 6.x </p><div
class="itemizedlist"><ul><li><a name="N102c"></a><div
class="literallayout">Driver Notes <br>
+ varbinary or image). We recommend you use int variables instead to avoid this. </div></li><li><p><a
name="Nfdd"></a>lib/ext:jconn2.jar</p></li><li><p><a
name="Nfe1"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=com.sybase.jdbc2.jdbc.SybDriver
+ </pre></li><li><p><a name="Nfeb"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="SybaseDB">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+</pre></li><li><p><a name="Nff5"></a>jboss.jcml</p><pre class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=SybaseDB">
+ <attribute
name="URL">jdbc:sybase:Tds:host.domain.com:4100/database</attribute>
+ <attribute name="Password">password</attribute>
+ <attribute name="JDBCUser">username</attribute>
+</mbean>
+</pre></li><li><p><a name="Nfff"></a>CMP Type Mapping Names (for
jaws.xml):Sybase</p></li></ul></div></li><li><p><a name="N1005"></a>PostgreSQL 7.x
</p><div class="itemizedlist"><ul><li><a name="N100b"></a><div
class="literallayout">Driver Notes <br>
+ Extreme Java "long" values will cause SQLExceptions and may corrupt the driver so that further actions fail. </div></li><li><p><a
name="N1013"></a>lib/ext:jdbc7.0-1.2.jar</p></li><li><p><a
name="N1017"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=org.postgresql.Driver
+ </pre></li><li><p><a name="N1021"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="PostgresDB">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+</pre></li><li><p><a name="N102b"></a>jboss.jcml</p><pre class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=PostgresDB">
+ <attribute
name="URL">jdbc:postgresql://host.domain.com/database</attribute>
+ <attribute name="JDBCUser">postgres</attribute>
+ <attribute name="Password">foo</attribute>
+</mbean>
+</pre><p>Note: You must include a user name and password. They can be bogus if your
PostgreSQL installation is configured to "trust" the machine
+ you're coming from, but you can't leave them out.</p></li><li><p><a
name="N1038"></a>CMP Type Mapping Names (for jaws.xml):PostgreSQL
</p></li></ul></div></li><li><p><a name="N103e"></a>Interbase 6.x </p><div
class="itemizedlist"><ul><li><a name="N1044"></a><div
class="literallayout">Driver Notes <br>
For CMP entity beans, serialized Java Objects are limited to 2000 bytes by default in automatically generated tables. You may<br>
increase this limit by changing the mapping or creating the table manually. <br>
The interclient JDBC driver seems to have trouble checking whether a table exists, so until that is resolved you can't have JAWS<br>
- create the table anyway. </div></li><li><a
name="N1034"></a><p>lib/ext:interclient-core.jar</p></li><li><a
name="N1038"></a><p>jboss.properties</p><pre class="programlisting">
- jdbc.drivers=interbase.interclient.Driver
- </pre></li><li><a name="N1042"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="InterBaseDB">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
-
- </pre></li><li><a name="N104c"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean
name="DefaultDomain:service=XADataSource,name=InterBaseDB">
- <attribute
name="URL">jdbc:interbase://host.domain.com/path/to/database.gdb</attribute>
- <attribute name="JDBCUser">sysdba</attribute>
- <attribute name="Password">changeme</attribute>
- </mbean>
- </pre></li><li><a name="N1056"></a><p>CMP Type Mapping Names (for
jaws.xml):InterBase</p></li></ul></div></li><li><a name="N105c"></a><p>mySQL
3.23.24-beta </p><div class="itemizedlist"><ul><li><a name="N1062"></a><div
class="literallayout">Notes:<br>
+ create the table anyway. </div></li><li><p><a
name="N104c"></a>lib/ext:interclient-core.jar</p></li><li><p><a
name="N1050"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=interbase.interclient.Driver
+ </pre></li><li><p><a name="N105a"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="InterBaseDB">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+</pre></li><li><p><a name="N1064"></a>jboss.jcml</p><pre class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=InterBaseDB">
+ <attribute
name="URL">jdbc:interbase://host.domain.com/path/to/database.gdb</attribute>
+ <attribute name="JDBCUser">sysdba</attribute>
+ <attribute name="Password">changeme</attribute>
+</mbean>
+</pre></li><li><p><a name="N106e"></a>CMP Type Mapping Names (for
jaws.xml):InterBase</p></li></ul></div></li><li><p><a name="N1074"></a>mySQL
3.23.24-beta </p><div class="itemizedlist"><ul><li><a name="N107a"></a><div
class="literallayout">Notes:<br>
mySQL does not support transactions before version 3.23.15 (experimental support). Check the consequences for your configuration. <br>
get mm.mysql-2.0.2-bin.jar from http://www.worldserver.com/mm.mysql/<br>
- copy the jar to lib/ext/ </div></li><li><a
name="N106a"></a><p>jboss.properties</p><pre class="programlisting">
- jdbc.drivers=org.gjt.mm.mysql.Driver
- </pre></li><li><a name="N1074"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader"
ARCHIVE="jboss.jar" CODEBASE="../../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="mySQL">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
-
- </pre></li><li><a name="N107e"></a><p>jboss.jcml</p><pre
class="programlisting">
- At least adjust URL, JDBCUser and Password in the following:
+ copy the jar to <tt>lib/ext/</tt> </div></li><li><p><a
name="N1087"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=org.gjt.mm.mysql.Driver
+ </pre></li><li><p><a name="N1091"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="mySQL">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+ </pre></li><li><p><a name="N109b"></a>jboss.jcml</p><pre
class="programlisting">
+At least adjust URL, JDBCUser and Password in the following:
- <mbean name="DefaultDomain:service=XADataSource,name=mySQL">
- <attribute name="Properties"></attribute>
- <attribute
name="URL">jdbc:mysql://host/databasename</attribute>
- <attribute name="GCMinIdleTime">1200000</attribute>
- <attribute
name="JDBCUser">EnterDatabaseUserHere</attribute>
- <attribute name="MaxSize">10</attribute>
- <attribute
name="Password">EnterDatabasePasswordHere</attribute>
- <attribute name="GCEnabled">false</attribute>
- <attribute name="InvalidateOnError">false</attribute>
- <attribute name="TimestampUsed">false</attribute>
- <attribute name="Blocking">true</attribute>
- <attribute name="GCInterval">120000</attribute>
- <attribute name="IdleTimeout">1800000</attribute>
- <attribute name="IdleTimeoutEnabled">false</attribute>
- <attribute name="LoggingEnabled">false</attribute>
- <attribute name="MaxIdleTimeoutPercent">1.0</attribute>
- <attribute name="MinSize">0</attribute>
- </mbean>
- </pre></li><li><a name="N1088"></a><p>CMP Type Mapping Names (for
jaws.xml):mySQL</p></li></ul></div></li><li><a name="N108e"></a><p>Microsoft Jet
Engine/Access 97</p><div class="itemizedlist"><ul><li><a name="N1094"></a><div
class="literallayout">Driver Notes <br>
+<mbean name="DefaultDomain:service=XADataSource,name=mySQL">
+ <attribute name="Properties"></attribute>
+ <attribute name="URL">jdbc:mysql://host/databasename</attribute>
+ <attribute name="GCMinIdleTime">1200000</attribute>
+ <attribute name="JDBCUser">EnterDatabaseUserHere</attribute>
+ <attribute name="MaxSize">10</attribute>
+ <attribute name="Password">EnterDatabasePasswordHere</attribute>
+ <attribute name="GCEnabled">false</attribute>
+ <attribute name="InvalidateOnError">false</attribute>
+ <attribute name="TimestampUsed">false</attribute>
+ <attribute name="Blocking">true</attribute>
+ <attribute name="GCInterval">120000</attribute>
+ <attribute name="IdleTimeout">1800000</attribute>
+ <attribute name="IdleTimeoutEnabled">false</attribute>
+ <attribute name="LoggingEnabled">false</attribute>
+ <attribute name="MaxIdleTimeoutPercent">1.0</attribute>
+ <attribute name="MinSize">0</attribute>
+</mbean>
+</pre></li><li><p><a name="N10a5"></a>CMP Type Mapping Names (for
jaws.xml):mySQL</p></li></ul></div></li><li><p><a name="N10ab"></a>Microsoft Jet
Engine/Access 97</p><div class="itemizedlist"><ul><li><a name="N10b1"></a><div
class="literallayout">Driver Notes <br>
This example uses Sun's Jdbc-Odbc bridge. This type 1 JDBC driver is very convenient if you start working with JBoss-Jet<br>
Engine. It can be slow under heavy loads and should be replaced in high-load production environments. Also, the driver supports<br>
only JDBC 1, so JDBC 2.0 types like CLOB cannot be used. <br>
The ODBC data source can be created using Control Panel - ODBC Data Sources. <br>
You can let Access and JBoss use the datasource at the same time. To do this, start JBoss first, then start Access. Access will<br>
open the datasource in Shared Mode. You can now use Access 97 as editor, viewer, bulk importer/exporter and query builder<br>
- while JBoss can be stopped and started concurrently. </div></li><li><a
name="N109c"></a><p>lib/ext:Sun JRE's rt.jar if your not running on a Sun virtual
machine, otherwise none </p></li><li><a name="N10a1"></a><p>jboss.properties</p><pre
class="programlisting">
- jdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriver
- </pre></li><li><a name="N10ab"></a><p> jboss.conf </p><pre
class="programlisting">
- <MLET CODE="org.jboss.jdbc.XADataSourceLoader"
ARCHIVE="jboss.jar" CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="JetEngineDB">
- <ARG TYPE="java.lang.String"
VALUE="org.jboss.minerva.xa.XADataSourceImpl">
- </MLET>
- </pre></li><li><a name="N10b5"></a><p>jboss.jcml</p><pre
class="programlisting">
- <mbean
name="DefaultDomain:service=XADataSource,name=JetEngineDB">
- <attribute name="URL">jdbc:odbc:ODBC datasource
name</attribute>
- <attribute name="JDBCUser"></attribute>
- <attribute name="Password"></attribute>
- </mbean>
- </pre></li><li><a name="N10bf"></a><p> Note: a default Jet Engine
data source has no user and password, therefor the JDBCUser and Password attributes
are empty. If you need
+ while JBoss can be stopped and started concurrently. </div></li><li><p><a
name="N10b9"></a>lib/ext:Sun JRE's rt.jar if your not running on a Sun virtual
machine, otherwise none </p></li><li><p><a name="N10be"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriver
+ </pre></li><li><p><a name="N10c8"></a> jboss.conf </p><pre
class="programlisting">
+<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
+ <ARG TYPE="java.lang.String" VALUE="JetEngineDB">
+ <ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
+</MLET>
+</pre></li><li><p><a name="N10d2"></a>jboss.jcml</p><pre class="programlisting">
+<mbean name="DefaultDomain:service=XADataSource,name=JetEngineDB">
+ <attribute name="URL">jdbc:odbc:ODBC datasource name</attribute>
+ <attribute name="JDBCUser"></attribute>
+ <attribute name="Password"></attribute>
+</mbean>
+ </pre></li><li><p><a name="N10dc"></a> Note: a default Jet Engine
data source has no user and password, therefor the JDBCUser and Password attributes
are empty. If you need
a user or a password, see the other examples. </p><p>You can download
this mapping here (if using JdbcOdbc bridge driver) or here (if using JDBC 2.0
compliant driver). Add the contents to
- your jaws.xml in the type-mappings section. </p></li><li><a
name="N10c6"></a><p>CMP Type Mapping Names (for jaws.xml):MS Jet Engine
</p></li></ul></div></li></ul></div></div></div><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/gbar.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch03.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch03.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch04.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
+ your jaws.xml in the type-mappings section. </p></li><li><p><a
name="N10e3"></a>CMP Type Mapping Names (for jaws.xml):MS Jet Engine
</p></li></ul></div></li></ul></div></div><div class="section"><a
name="N10eb"></a><div class="titlepage"><div><h3 class="title"><a
name="N10eb"></a><span class="title">Changes for newer versions than 2.0
FINAL</span></h3></div></div><p>Author:
+ <span class="author">Tobias Frech</span>
+</p><p>
+If your are using a newer version of JBoss than 2.0 FINAL then
+all you need to configure is the file jboss.jcml in your configuration
+directory (probably this is conf/default/). The following points describe
+where the information provided for the former different files now should be
inserted into <i>jboss.jcml</i>:
+</p><div class="itemizedlist"><ul><li><a
name="N1100"></a><p><b>jboss.properties:</b> In the
+ <tt><mbean code="org.jboss.jdbc.JdbcProvider"...>
+ </tt> add the
+ additional driver entry to the comma separated list inside the
+ <tt><attribute name="Drivers"></tt> tag.</p></li><li><a
name="N1114"></a><p><b>jboss.conf:</b> This information is no longer
needed.</p></li><li><a name="N111e"></a><p><b>jboss.jcml:</b> Find the entry
+ <pre class="programlisting">
+<mbean code="org.jboss.jdbc.XADataSourceLoader"
+name="DefaultDomain:service=XADataSource,name=DefaultDS">
+...
+</mbean>
+</pre>
+ Either you want to change the default Datasource, then change the
+ contents of this entry directly, or you want to add a new
+ datasource. For the second
+ case create a copy of the whole entry after
+ the already existing one.
+ Now change the two occurences of the “DefaultDS”
+ string (in “name=...”
+ and attribute “PoolName”) to the name you want
+ to specify for your new datasource.
+ Also adjust at least the following entries according to your
+ configuration and to the data given in the example:
+ <pre class="programlisting">
+<attribute
name="URL">jdbc:url/with/your/database/name/like/in/example</attribute>
+<attribute name="JDBCUser">DatabaseUserNameHere</attribute>
+<attribute name="Password">DatabasePasswordHere</attribute>
+</pre>
+ </p></li></ul></div><p>
+All other information contained in the examples like which driver jar
+to copy to <tt>lib/ext/</tt> and using which type mapping in your beans
+jaws.xml should still be valid.
+</p></div></div><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch03.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch03.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch04.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
1.2 +6 -6 newsite/documentation/HTML/ch04.html
Index: ch04.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch04.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch04.html 2001/02/11 16:02:03 1.1
+++ ch04.html 2001/03/12 01:54:46 1.2
@@ -1,7 +1,7 @@
-<html><head><title>4. Using container-managed persistence</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.25" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="index.html" rel="up" title="JBoss 2.0
documentation"><link href="ch03s05.html" rel="previous" title="Creating DB Connection
Pools"><link href="ch04s07.html" rel="next" title="Container Managed Persistence -
CMP"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch03s0!
5.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch04s07.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N10d0"><div
class="titlepage"><h2 class="title"><a name="N10d0">4. Using container-managed
persistence</a></h2></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="ch04.html#N10e1">Introduction</a></dt><dt> <a href="ch04s07.html">Container
Managed Persistence - CMP</a></dt><dt> <a href="ch04s09.html">Creating the
Beans</a></dt><dt> <a href="ch04s10.html">Packaging and deploying the
Beans</a></dt><dt> <a href="ch04s11.html">Creating a test client </a></dt><dt> <a
href="ch04s12.html">Discussion: container-managed
persistence</a></dt></dl></div><p>Author:
+<html><head><title>Chapter 4. Using container-managed persistence</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="index.html" rel="up" title="JBoss 2.0
documentation"><link href="ch03s05.html" rel="previous" title="Creating DB Connection
Pools"><link href="ch04s07.html" rel="next" title="Container Managed Persistence -
CMP"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href!
="ch03s05.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch04s07.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N1147"><div
class="titlepage"><div><h2 class="title"><a name="N1147"></a>Chapter 4. Using
container-managed persistence</h2></div></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="ch04.html#N1158">Introduction</a></dt><dt> <a
href="ch04s07.html">Container Managed Persistence - CMP</a></dt><dt> <a
href="ch04s09.html">Creating the Beans</a></dt><dt> <a href="ch04s10.html">Packaging
and deploying the Beans</a></dt><dt> <a href="ch04s11.html">Creating a test client
</a></dt><dt> <a href="ch04s12.html">Discussion: container-managed
persistence</a></dt></dl></div><p>Author:
<span class="author">Kevin Boone</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
- </p><div class="section" id="N10e1"><div class="titlepage"><h2 class="title"
style="clear: all"><a name="N10e1"></a><span
class="title">Introduction</span></h2></div><div class="section" id="N10e5"><div
class="titlepage"><h3 class="title"><a name="N10e5"></a><span class="title">What this
article is about</span></h3></div><p>
+ </p><div class="section"><a name="N1158"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1158"></a><span
class="title">Introduction</span></h2></div></div><div class="section"><a
name="N115c"></a><div class="titlepage"><div><h3 class="title"><a
name="N115c"></a><span class="title">What this article is
about</span></h3></div></div><p>
This article presensts a step-by-step example of creating, deploying and
testing an Entity JavaBean that uses
`container-managed persistence' with the JBoss EJB server. This
@@ -22,7 +22,7 @@
that's what I use for EJB
development; most of the material in this article will work with any Unix
version, and even with Windows NT
-if the directory structure is adjusted accordingly.</p></div><div class="section"
id="N10f3"><div class="titlepage"><h3 class="title"><a name="N10f3"></a><span
class="title">Pre-requisites</span></h3></div><p>
+if the directory structure is adjusted accordingly.</p></div><div
class="section"><a name="N116a"></a><div class="titlepage"><div><h3 class="title"><a
name="N116a"></a><span class="title">Pre-requisites</span></h3></div></div><p>
You will need a fully-functioning JBoss installation to follow this tutorial,
which must have a working
database connection. I will assume that you are basically familiar with EJBs
@@ -33,7 +33,7 @@
assume that you know how to
package and deploy EJBs using JBoss. If you don't know about these things, you
might want to look at my
-introductory article on JBoss first.</p></div><div class="section" id="N10fb"><div
class="titlepage"><h3 class="title"><a name="N10fb"></a><span class="title">JBoss
hints</span></h3></div><p>JBoss is written entirely in Java, as is the `Hypersonic'
database with
+introductory article on JBoss first.</p></div><div class="section"><a
name="N1172"></a><div class="titlepage"><div><h3 class="title"><a
name="N1172"></a><span class="title">JBoss hints</span></h3></div></div><p>JBoss is
written entirely in Java, as is the `Hypersonic' database with
which it is supplied. Searching a database
requires lots of repetitive operations, and an interpreting Java system will
be extremely slow if the database is
@@ -44,7 +44,7 @@
by ensuring that the database size is kept small, but with even a hundred
objects you will find it too slow to use.
Some Linux systems are reluctant to use the `Hotspot' JVM, but they can
-normally be coerced to.</p></div><div class="section" id="N1103"><div
class="titlepage"><h3 class="title"><a name="N1103"></a><span
class="title">Persistence: review</span></h3></div><p>
+normally be coerced to.</p></div><div class="section"><a name="N117a"></a><div
class="titlepage"><div><h3 class="title"><a name="N117a"></a><span
class="title">Persistence: review</span></h3></div></div><p>
There are, in essence, two kinds of Enterprise JavaBean: session and entity.
Entity EJBs contain information
that is persistent across different client-Bean interactions, while session
@@ -77,7 +77,7 @@
by the server (technically by the
`container'). The latter technique is called `Container-managed persistence',
and is the subject of the rest of
-this article.</p></div><div class="section" id="N1114"><div class="titlepage"><h3
class="title"><a name="N1114"></a><span class="title">When to Use CMP or
BMP?</span></h3></div><p>
+this article.</p></div><div class="section"><a name="N118b"></a><div
class="titlepage"><div><h3 class="title"><a name="N118b"></a><span class="title">When
to Use CMP or BMP?</span></h3></div></div><p>
Unlike what many folks believe, the choice of going BMP or CMP is not really
one of "trade-off". If you have
already schemas deployed you may find that the complexity of the schemas
1.2 +5 -5 newsite/documentation/HTML/ch04s07.html
Index: ch04s07.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch04s07.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch04s07.html 2001/02/11 16:02:03 1.1
+++ ch04s07.html 2001/03/12 01:54:46 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Container Managed Persistence - CMP</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.25" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch04.html" rel="up" title="4. Using container-managed
persistence"><link href="ch04.html" rel="previous" title="4. Using container-managed
persistence"><link href="ch04s09.html" rel="next" title="Creating the
Beans"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch04.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch04.h!
tml"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch04s09.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N1120"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N1120"></a><span
class="title">Container Managed Persistence - CMP</span></h2></div><div
class="section" id="N1124"><div class="titlepage"><h3 class="title"><a
name="N1124"></a><span class="title">Determine the persistent
classes</span></h3></div><p>
+<html><head><title>Container Managed Persistence - CMP</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch04.html" rel="up" title="Chapter 4. Using
container-managed persistence"><link href="ch04.html" rel="previous" title="Chapter 4.
Using container-managed persistence"><link href="ch04s09.html" rel="next"
title="Creating the Beans"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch04.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a!
><a href="ch04.html"><img border="0" height="65" src="images/prev.gif"
>width="76"></a><a href="ch04s09.html"><img border="0" height="65"
>src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
>class="section"><a name="N1197"></a><div class="titlepage"><div><h2 class="title"
>style="clear: all"><a name="N1197"></a><span class="title">Container Managed
>Persistence - CMP</span></h2></div></div><div class="section"><a
>name="N119b"></a><div class="titlepage"><div><h3 class="title"><a
>name="N119b"></a><span class="title">Determine the persistent
>classes</span></h3></div></div><p>
In this simple example we will use two Enterprise JavaBeans. The first, called
`CD' models a music CD.
It contains attributes (instance variables) that store the title ID code and
@@ -12,10 +12,10 @@
will have the following methods deleteAll(), addCd(), findInAnyField() and
findAll().
</p><p>
- <div class="itemizedlist"><ul><li><a name="N1130"></a><p>
- addCd() - Adds a single CD specified by values of its
attributes</p></li><li><a name="N1134"></a><p>
- deleteAll() - Delete all CDs </p></li><li><a
name="N1138"></a><p>findInAnyField() - Returns an array of CD instances which have
- the specified text string in any of their attributes</p></li><li><a
name="N113c"></a><p>
+ <div class="itemizedlist"><ul><li><p><a name="N11a7"></a>
+ addCd() - Adds a single CD specified by values of its
attributes</p></li><li><p><a name="N11ab"></a>
+ deleteAll() - Delete all CDs </p></li><li><p><a
name="N11af"></a>findInAnyField() - Returns an array of CD instances which have
+ the specified text string in any of their
attributes</p></li><li><p><a name="N11b3"></a>
findAll() - Returns an array of all CD instances in the system
</p></li></ul></div>
</p><p>
1.2 +6 -5 newsite/documentation/HTML/ch04s09.html
Index: ch04s09.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch04s09.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch04s09.html 2001/02/11 16:02:03 1.1
+++ ch04s09.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Creating the Beans</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch04.html" rel="up" title="4. Using container-managed
persistence"><link href="ch04s07.html" rel="previous" title="Container Managed
Persistence - CMP"><link href="ch04s10.html" rel="next" title="Packaging and deploying
the Beans"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch04.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch04s07.!
html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch04s10.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N1151"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N1151"></a><span
class="title">Creating the Beans</span></h2></div><p>
+<html><head><title>Creating the Beans</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch04.html" rel="up" title="Chapter 4. Using
container-managed persistence"><link href="ch04s07.html" rel="previous"
title="Container Managed Persistence - CMP"><link href="ch04s10.html" rel="next"
title="Packaging and deploying the Beans"></head><body alink="#0000FF" bgcolor="white"
link="#0000FF" text="black" vlink="#840084"><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/jboss.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch04.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="!
ch04s07.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch04s10.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N11c8"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N11c8"></a><span class="title">Creating the Beans</span></h2></div></div><p>
The entity bean representing the CD is very easy to code, as it doesn't have
to do a great deal.
All the issues of persistence will be taken care of by the server. I will
@@ -6,8 +6,9 @@
for this Bean below; the code for the CDCollection Bean will not be discussed
further because it
is not interesting in the context of container-managed persistence. Remember
-that the full source
-code is available to download: click here.
+that the full source code is available to download as an archive named
+“cdEJB.zip”. You can get it from the files area in the
+documentation section on www.jboss.org.
</p><p>
CD.java: remote interface for the `CD' Bean
</p><p>
@@ -234,7 +235,7 @@
don't forget
to include the path to the JBoss EJB class library in your classpath, e.g.,
</p><p>
- <b>
-javac -classpath /usr/lib/jboss/lib/ext/ejb.jar:. ....
+ <b>
+javac -classpath /usr/local/jboss/client/ejb.jar:. ....
</b>
</p></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch04.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch04s07.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch04s10.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.2 +1 -1 newsite/documentation/HTML/ch04s10.html
Index: ch04s10.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch04s10.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch04s10.html 2001/02/11 16:02:04 1.1
+++ ch04s10.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Packaging and deploying the Beans</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch04.html" rel="up" title="4. Using container-managed
persistence"><link href="ch04s09.html" rel="previous" title="Creating the Beans"><link
href="ch04s11.html" rel="next" title="Creating a test client "></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch04.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch04s09.html"><img b!
order="0" height="65" src="images/prev.gif" width="76"></a><a href="ch04s11.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N119d"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N119d"></a><span
class="title">Packaging and deploying the Beans</span></h2></div><p>
+<html><head><title>Packaging and deploying the Beans</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch04.html" rel="up" title="Chapter 4. Using
container-managed persistence"><link href="ch04s09.html" rel="previous"
title="Creating the Beans"><link href="ch04s11.html" rel="next" title="Creating a test
client "></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch04.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch04s09.html!
"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch04s11.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N1217"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1217"></a><span class="title">Packaging and deploying the
Beans</span></h2></div></div><p>
Deploying an entity bean requires providing some extra information, in
addition to that required
for a session bean. This information is provided in the deployment descriptor
1.2 +1 -1 newsite/documentation/HTML/ch04s11.html
Index: ch04s11.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch04s11.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch04s11.html 2001/02/11 16:02:04 1.1
+++ ch04s11.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Creating a test client </title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch04.html" rel="up" title="4. Using container-managed
persistence"><link href="ch04s10.html" rel="previous" title="Packaging and deploying
the Beans"><link href="ch04s12.html" rel="next" title="Discussion: container-managed
persistence"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch04.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a hre!
f="ch04s10.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch04s12.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N11de"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N11de"></a><span
class="title">Creating a test client </span></h2></div><p>
+<html><head><title>Creating a test client </title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch04.html" rel="up" title="Chapter 4. Using
container-managed persistence"><link href="ch04s10.html" rel="previous"
title="Packaging and deploying the Beans"><link href="ch04s12.html" rel="next"
title="Discussion: container-managed persistence"></head><body alink="#0000FF"
bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch04.html"><img border="0" height="65" src="images/toc.gif" width="60"></!
a><a href="ch04s10.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch04s12.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1258"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1258"></a><span class="title">Creating a test client
</span></h2></div></div><p>
Client for EJBs may be any Java program or applet; in this simple example I
will describe
a very simple client program that can be run from the command line. It simply
1.2 +5 -5 newsite/documentation/HTML/ch04s12.html
Index: ch04s12.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch04s12.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch04s12.html 2001/02/11 16:02:04 1.1
+++ ch04s12.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Discussion: container-managed persistence</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.25" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch04.html" rel="up" title="4. Using container-managed
persistence"><link href="ch04s11.html" rel="previous" title="Creating a test client
"><link href="ch05.html" rel="next" title="5. Customizing JAWS"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch04.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch04s11.html">!
<img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch05.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N120f"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N120f"></a><span
class="title">Discussion: container-managed persistence</span></h2></div><p>
+<html><head><title>Discussion: container-managed persistence</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch04.html" rel="up" title="Chapter 4. Using
container-managed persistence"><link href="ch04s11.html" rel="previous"
title="Creating a test client "><link href="ch05.html" rel="next" title="Chapter 5.
Customizing JAWS"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch04.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href!
="ch04s11.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch05.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N1289"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1289"></a><span class="title">Discussion: container-managed
persistence</span></h2></div></div><p>
If you followed the tutorial on container-managed persistence with JBoss,
you will have seen that creating persistent, distributed objects is not
really any more difficult than creating transient ones. The EJB container does
@@ -7,7 +7,7 @@
naive use of CMP can lead to very inefficient programs. To see why,
it's necessary to understand at least in outline how the EJB server deals with
container-managed persistence.
- </p><div class="section" id="N1216"><div class="titlepage"><h3 class="title"><a
name="N1216"></a><span class="title">Technical overview </span></h3></div><p>
+ </p><div class="section"><a name="N1290"></a><div class="titlepage"><div><h3
class="title"><a name="N1290"></a><span class="title">Technical overview
</span></h3></div></div><p>
In the EJB field there is a very strong correspondence between `rows of a
database table', and `instances of an object'. It is clear that the EJB
developers had this notion in mind from the very beginning. While the
@@ -28,7 +28,7 @@
Initialization from the database table takes place later, perhaps
when one of the methods is called. This late initialization reduces
inefficiencies arising from initializing objects that are never read, but has
-its own problems, as we shall see. </p></div><div class="section" id="N1222"><div
class="titlepage"><h3 class="title"><a name="N1222"></a><span
class="title">Limitations of CMP </span></h3></div><div class="section"
id="N1226"><div class="titlepage"><h4 class="title"><a name="N1226"></a><span
class="title">Efficiency limitations </span></h4></div><p>
+its own problems, as we shall see. </p></div><div class="section"><a
name="N129c"></a><div class="titlepage"><div><h3 class="title"><a
name="N129c"></a><span class="title">Limitations of CMP </span></h3></div></div><div
class="section"><a name="N12a0"></a><div class="titlepage"><div><h4 class="title"><a
name="N12a0"></a><span class="title">Efficiency limitations </span></h4></div></div><p>
The main limitation is that the EJB container will probably not be able to
generate database access statements with the efficiency of a human
programmer. Consider this example: suppose I have an database table containing
@@ -89,7 +89,7 @@
values are written, it doesn't matter what the columns are called.
This is the approach that JBoss uses. The problem is that if a class has ten
persistent attributes, and they are altered one after the other, in the
-worst case this results in ten row deletions and ten row insertions. </p></div><div
class="section" id="N1251"><div class="titlepage"><h4 class="title"><a
name="N1251"></a><span class="title">Limitations of late initialization
</span></h4></div><p>
+worst case this results in ten row deletions and ten row insertions. </p></div><div
class="section"><a name="N12cb"></a><div class="titlepage"><div><h4 class="title"><a
name="N12cb"></a><span class="title">Limitations of late initialization
</span></h4></div></div><p>
Suppose we want to find whether a CD with a specific ID exists on the system.
With CMP this corresponds to finding whether there is a row in
the database table with the corresponding value of the `id' column. The code
@@ -134,7 +134,7 @@
</p><p>
If there is no CD whose ID field is `XXX' then this will throw a
java.rmi.NoSuchObjectException. This gets around the problem
-of late initialization, but at the cost of an additional SQL access.</p></div><div
class="section" id="N126a"><div class="titlepage"><h4 class="title"><a
name="N126a"></a><span class="title">Suitability of container-managed persistence
</span></h4></div><p>
+of late initialization, but at the cost of an additional SQL access.</p></div><div
class="section"><a name="N12e4"></a><div class="titlepage"><div><h4 class="title"><a
name="N12e4"></a><span class="title">Suitability of container-managed persistence
</span></h4></div></div><p>
In many applications of object-oriented programming we have had to accept that
some things that are philosophically objects are in reality
implemented as something else. The `something else' may be a row of a database
1.2 +7 -7 newsite/documentation/HTML/ch05.html
Index: ch05.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch05.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch05.html 2001/02/11 16:02:04 1.1
+++ ch05.html 2001/03/12 01:54:47 1.2
@@ -1,18 +1,18 @@
-<html><head><title>5. Customizing JAWS</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="index.html" rel="up" title="JBoss 2.0 documentation"><link
href="ch04s12.html" rel="previous" title="Discussion: container-managed
persistence"><link href="ch05s02.html" rel="next" title="Specifying a
datasource"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch04s12.html"><img borde!
r="0" height="65" src="images/prev.gif" width="76"></a><a href="ch05s02.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N1279"><div
class="titlepage"><h2 class="title"><a name="N1279">5. Customizing
JAWS</a></h2></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="ch05.html#N1289">Introduction</a></dt><dt> <a href="ch05s02.html">Specifying a
datasource</a></dt><dt> <a href="ch05s03.html">JAWS Options</a></dt><dt> <a
href="ch05s04.html">Telling JAWS about your tables</a></dt><dt> <a
href="ch05s05.html">Declaring finders</a></dt><dt> <a href="ch05s06.html">Defining a
type mapping</a></dt></dl></div><p>Author:
+<html><head><title>Chapter 5. Customizing JAWS</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="index.html" rel="up" title="JBoss 2.0 documentation"><link
href="ch04s12.html" rel="previous" title="Discussion: container-managed
persistence"><link href="ch05s02.html" rel="next" title="Specifying a
datasource"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch04s12.html"><i!
mg border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch05s02.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N12f3"><div
class="titlepage"><div><h2 class="title"><a name="N12f3"></a>Chapter 5. Customizing
JAWS</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="ch05.html#N1303">Introduction</a></dt><dt> <a href="ch05s02.html">Specifying a
datasource</a></dt><dt> <a href="ch05s03.html">JAWS Options</a></dt><dt> <a
href="ch05s04.html">Telling JAWS about your tables</a></dt><dt> <a
href="ch05s05.html">Declaring finders</a></dt><dt> <a href="ch05s06.html">Defining a
type mapping</a></dt></dl></div><p>Author:
<span class="author">Sebastien Alborini</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
-</p><div class="section" id="N1289"><div class="titlepage"><h2 class="title"
style="clear: all"><a name="N1289"></a><span
class="title">Introduction</span></h2></div><p>JAWS is the O/R mapper used by JBoss to
manage CMP entity beans. JAWS
+</p><div class="section"><a name="N1303"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1303"></a><span
class="title">Introduction</span></h2></div></div><p>JAWS is the O/R mapper used by
JBoss to manage CMP entity beans. JAWS
can be configured by putting a jaws.xml file in the
META-INF directory of your application. JAWS will read this file while
-deploying your beans. Here is what you can do with jaws.xml:</p><div
class="itemizedlist"><ul><li><a name="N1292"></a><p>
+deploying your beans. Here is what you can do with jaws.xml:</p><div
class="itemizedlist"><ul><li><p><a name="N130c"></a>
Specify a datasource and the type-mappings to use with it
- </p></li><li><a name="N1296"></a><p>
+ </p></li><li><p><a name="N1310"></a>
Set a bunch of options concerning jaws behavior
- </p></li><li><a name="N129a"></a><p>
+ </p></li><li><p><a name="N1314"></a>
Specify how JAWS should build/use your tables
- </p></li><li><a name="N129e"></a><p>
+ </p></li><li><p><a name="N1318"></a>
Define finders to access you entity beans
- </p></li><li><a name="N12a2"></a><p>
+ </p></li><li><p><a name="N131c"></a>
Define a type mapping
</p></li></ul></div><p>
If you want to know everything about jaws.xml, see the Jaws.xml DTD. The
1.2 +10 -10 newsite/documentation/HTML/ch05s02.html
Index: ch05s02.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch05s02.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch05s02.html 2001/02/11 16:02:04 1.1
+++ ch05s02.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Specifying a datasource</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch05.html" rel="up" title="5. Customizing JAWS"><link
href="ch05.html" rel="previous" title="5. Customizing JAWS"><link href="ch05s03.html"
rel="next" title="JAWS Options"></head><body alink="#0000FF" bgcolor="white"
link="#0000FF" text="black" vlink="#840084"><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/jboss.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch05.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch05.html"><img border="0" height="65"
src="images/prev.gif" w!
idth="76"></a><a href="ch05s03.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N12ab"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N12ab"></a><span
class="title">Specifying a datasource</span></h2></div><p>
+<html><head><title>Specifying a datasource</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch05.html" rel="up" title="Chapter 5. Customizing
JAWS"><link href="ch05.html" rel="previous" title="Chapter 5. Customizing JAWS"><link
href="ch05s03.html" rel="next" title="JAWS Options"></head><body alink="#0000FF"
bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch05.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch05.html"><img border="0" height="65" src="im!
ages/prev.gif" width="76"></a><a href="ch05s03.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1325"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1325"></a><span class="title">Specifying a
datasource</span></h2></div></div><p>
A datasource is, mainly, a database plus a driver plus a connection pool. By
default, jboss uses the Hypersonic datasource. To add another
datasource, you have to declare it as a JMX MLet: see the manual.</p><p>
@@ -12,23 +12,23 @@
You just have to add a <type-mapping> tag with the name of the
type mapping in it. Type mappings for the most common databases are already
defined in jboss in a file called standardjaws.xml. Their
-names are listed here:</p><div class="itemizedlist"><ul><li><a name="N12ba"></a><p>
+names are listed here:</p><div class="itemizedlist"><ul><li><p><a name="N1334"></a>
Hypersonic SQL
- </p></li><li><a name="N12be"></a><p>
+ </p></li><li><p><a name="N1338"></a>
InstantDB
- </p></li><li><a name="N12c2"></a><p>
+ </p></li><li><p><a name="N133c"></a>
Oracle
- </p></li><li><a name="N12c6"></a><p>
+ </p></li><li><p><a name="N1340"></a>
PointBase
- </p></li><li><a name="N12ca"></a><p>
+ </p></li><li><p><a name="N1344"></a>
PostgreSQL
- </p></li><li><a name="N12ce"></a><p>
+ </p></li><li><p><a name="N1348"></a>
SOLID
- </p></li><li><a name="N12d2"></a><p>
+ </p></li><li><p><a name="N134c"></a>
mySQL
- </p></li><li><a name="N12d6"></a><p>
+ </p></li><li><p><a name="N1350"></a>
DB2/400
- </p></li><li><a name="N12da"></a><p>
+ </p></li><li><p><a name="N1354"></a>
MS SQLSERVER
</p></li></ul></div><p>
For instance, if you want to use the Postgres Database that you have deployed
1.2 +6 -6 newsite/documentation/HTML/ch05s03.html
Index: ch05s03.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch05s03.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch05s03.html 2001/02/11 16:02:04 1.1
+++ ch05s03.html 2001/03/12 01:54:47 1.2
@@ -1,24 +1,24 @@
-<html><head><title>JAWS Options</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.25" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch05.html"
rel="up" title="5. Customizing JAWS"><link href="ch05s02.html" rel="previous"
title="Specifying a datasource"><link href="ch05s04.html" rel="next" title="Telling
JAWS about your tables"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch05.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch05s02.html"><img border="0" height="65"
src="i!
mages/prev.gif" width="76"></a><a href="ch05s04.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="section"
id="N12eb"><div class="titlepage"><h2 class="title" style="clear: all"><a
name="N12eb"></a><span class="title">JAWS Options</span></h2></div><p>
-Here are the options you can set in JAWS:</p><div class="itemizedlist"><ul><li><a
name="N12f4"></a><p>
+<html><head><title>JAWS Options</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch05.html"
rel="up" title="Chapter 5. Customizing JAWS"><link href="ch05s02.html" rel="previous"
title="Specifying a datasource"><link href="ch05s04.html" rel="next" title="Telling
JAWS about your tables"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch05.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch05s02.html"><img border="0" height="65!
" src="images/prev.gif" width="76"></a><a href="ch05s04.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1365"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1365"></a><span class="title">JAWS
Options</span></h2></div></div><p>
+Here are the options you can set in JAWS:</p><div
class="itemizedlist"><ul><li><p><a name="N136e"></a>
create-table: this tells JAWS whether it has to try and create the
table for your beans at deployment time. It is turned on by
default. If the table already exists, JAWS will tell it to you, and
proceed.
- </p></li><li><a name="N12f8"></a><p>
+ </p></li><li><p><a name="N1372"></a>
remove-table: this tells JAWS whether it has to remove (drop) the table
of your bean at undeployment time. It is turned off by
default. You may want to turn it on to clean the database. Note that if
you change a cmp-field in a bean, you will probably have to
drop the table and create it again, since the schema will have changed.
- </p></li><li><a name="N12fc"></a><p>
+ </p></li><li><p><a name="N1376"></a>
tuned-updates: when this option is turned on (default) JAWS will only
update in the database the fields of your bean that have
actually changed.
- </p></li><li><a name="N1300"></a><p>
+ </p></li><li><p><a name="N137a"></a>
read-only: tells whether JAWS will allow client application to modify
the state of your beans. Default is false. If true, JAWS will
perform no INSERT/UPDATE.
- </p></li><li><a name="N1304"></a><p>
+ </p></li><li><p><a name="N137e"></a>
time-out: this option is only used when read-only is true. In this
case, JAWS will not refresh the state of your beans from the
database more than once every time-out milliseconds.
1.2 +1 -1 newsite/documentation/HTML/ch05s04.html
Index: ch05s04.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch05s04.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch05s04.html 2001/02/11 16:02:04 1.1
+++ ch05s04.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Telling JAWS about your tables</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch05.html" rel="up" title="5. Customizing JAWS"><link
href="ch05s03.html" rel="previous" title="JAWS Options"><link href="ch05s05.html"
rel="next" title="Declaring finders"></head><body alink="#0000FF" bgcolor="white"
link="#0000FF" text="black" vlink="#840084"><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/jboss.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch05.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch05s03.html"><img border="0" height="65"
src="images/!
prev.gif" width="76"></a><a href="ch05s05.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="section"
id="N1320"><div class="titlepage"><h2 class="title" style="clear: all"><a
name="N1320"></a><span class="title">Telling JAWS about your
tables</span></h2></div><p>
+<html><head><title>Telling JAWS about your tables</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch05.html" rel="up" title="Chapter 5. Customizing
JAWS"><link href="ch05s03.html" rel="previous" title="JAWS Options"><link
href="ch05s05.html" rel="next" title="Declaring finders"></head><body alink="#0000FF"
bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch05.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch05s03.html"><img border="0" height="65" src=!
"images/prev.gif" width="76"></a><a href="ch05s05.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N139a"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N139a"></a><span class="title">Telling JAWS about your
tables</span></h2></div></div><p>
JAWS will use one different table for each of your CMP entity beans. The table
for one entity bean will contain one column for each of the
CMP fields of this entity.</p><p>
1.2 +4 -4 newsite/documentation/HTML/ch05s05.html
Index: ch05s05.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch05s05.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch05s05.html 2001/02/11 16:02:05 1.1
+++ ch05s05.html 2001/03/12 01:54:47 1.2
@@ -1,13 +1,13 @@
-<html><head><title>Declaring finders</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch05.html" rel="up" title="5. Customizing JAWS"><link
href="ch05s04.html" rel="previous" title="Telling JAWS about your tables"><link
href="ch05s06.html" rel="next" title="Defining a type mapping"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch05.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch05s04.html"><img border="0" height="65" s!
rc="images/prev.gif" width="76"></a><a href="ch05s06.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="section"
id="N1347"><div class="titlepage"><h2 class="title" style="clear: all"><a
name="N1347"></a><span class="title">Declaring finders</span></h2></div><p>.
+<html><head><title>Declaring finders</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch05.html" rel="up" title="Chapter 5. Customizing
JAWS"><link href="ch05s04.html" rel="previous" title="Telling JAWS about your
tables"><link href="ch05s06.html" rel="next" title="Defining a type
mapping"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch05.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch05s04.html"><img border="0" heigh!
t="65" src="images/prev.gif" width="76"></a><a href="ch05s06.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N13c1"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N13c1"></a><span class="title">Declaring
finders</span></h2></div></div><p>.
The finders to access your beans are all declared in the home interface. JAWS
automatically generates the following finders for you:
-</p><div class="itemizedlist"><ul><li><a name="N1350"></a><p>
+</p><div class="itemizedlist"><ul><li><p><a name="N13ca"></a>
findAll() will return a Collection of all the beans available
- </p></li><li><a name="N1354"></a><p>
+ </p></li><li><p><a name="N13ce"></a>
findByPrimaryKey(YourPK pk) will return a single bean with the
corresponding primary key (the primary key class is defined in
ejb-jar.xml)
- </p></li><li><a name="N1358"></a><p>
+ </p></li><li><p><a name="N13d2"></a>
for each of the cmp-fields of your bean, findByXX(YY fieldValue), where
XX is the name of the cmp-field (NOT case-sensitive)
and YY its class, will return a Collection of all the beans with the
1.2 +4 -4 newsite/documentation/HTML/ch05s06.html
Index: ch05s06.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch05s06.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch05s06.html 2001/02/11 16:02:05 1.1
+++ ch05s06.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Defining a type mapping</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch05.html" rel="up" title="5. Customizing JAWS"><link
href="ch05s05.html" rel="previous" title="Declaring finders"><link href="ch06.html"
rel="next" title="6. Advanced container configuration"></head><body alink="#0000FF"
bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch05.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch05s05.html"><img border="0" height="65"!
src="images/prev.gif" width="76"></a><a href="ch06.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="section"
id="N1384"><div class="titlepage"><h2 class="title" style="clear: all"><a
name="N1384"></a><span class="title">Defining a type mapping</span></h2></div><p>
+<html><head><title>Defining a type mapping</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch05.html" rel="up" title="Chapter 5. Customizing
JAWS"><link href="ch05s05.html" rel="previous" title="Declaring finders"><link
href="ch06.html" rel="next" title="Chapter 6. Advanced container
configuration"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch05.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch05s05.html"><img border!
="0" height="65" src="images/prev.gif" width="76"></a><a href="ch06.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N13fe"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N13fe"></a><span class="title">Defining a type mapping</span></h2></div></div><p>
A type mapping tells JAWS how to map java objects to a specific database. For
example, some databases have a boolean type, and other
don't, so you have to map a java.lang.Boolean to a CHAR(5).</p><p>
@@ -10,16 +10,16 @@
that you need to map. If your class is not found in the mappings,
JAWS will use the mapping for java.lang.Object.</p><p>
A mapping comes in 3 parts:
-</p><div class="itemizedlist"><ul><li><a name="N1396"></a><p>
+</p><div class="itemizedlist"><ul><li><p><a name="N1410"></a>
the <java-type> is the name of the java class you want to
map.
- </p></li><li><a name="N139a"></a><p>
+ </p></li><li><p><a name="N1414"></a>
the <jdbc-type> is the jdbc type to use. Its value must be
one of the fields of java.sql.Types (e.g. BIT, CHAR...). This jdbc type will
be used by JAWS to determine which method to call on PreparedStatement
and ResultSet for INSERT / UPDATE / SELECT
queries.
- </p></li><li><a name="N139e"></a><p>
+ </p></li><li><p><a name="N1418"></a>
the <sql-type> is the actual type in the database. This
value will only be used when JAWS creates your table.
</p></li></ul></div><p>
1.2 +2 -2 newsite/documentation/HTML/ch06.html
Index: ch06.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch06.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch06.html 2001/02/11 16:02:05 1.1
+++ ch06.html 2001/03/12 01:54:47 1.2
@@ -1,7 +1,7 @@
-<html><head><title>6. Advanced container configuration</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.25" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="index.html" rel="up" title="JBoss 2.0
documentation"><link href="ch05s06.html" rel="previous" title="Defining a type
mapping"><link href="ch06s02.html" rel="next" title="Specifying the deployment name of
your beans"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch05s!
06.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch06s02.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N13a8"><div
class="titlepage"><h2 class="title"><a name="N13a8">6. Advanced container
configuration</a></h2></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>
<a href="ch06.html#N13b9">What is jboss.xml?</a></dt><dt> <a
href="ch06s02.html">Specifying the deployment name of your beans</a></dt><dt> <a
href="ch06s03.html">Declaring an ejb references</a></dt><dt> <a
href="ch06s04.html">Container configuration</a></dt></dl></div><p>Author:
+<html><head><title>Chapter 6. Advanced container configuration</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="index.html" rel="up" title="JBoss 2.0
documentation"><link href="ch05s06.html" rel="previous" title="Defining a type
mapping"><link href="ch06s02.html" rel="next" title="Specifying the deployment name of
your beans"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a hre!
f="ch05s06.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch06s02.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N1422"><div
class="titlepage"><div><h2 class="title"><a name="N1422"></a>Chapter 6. Advanced
container configuration</h2></div></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="ch06.html#N1433">What is jboss.xml?</a></dt><dt> <a
href="ch06s02.html">Specifying the deployment name of your beans</a></dt><dt> <a
href="ch06s03.html">Declaring an ejb references</a></dt><dt> <a
href="ch06s04.html">Container configuration</a></dt></dl></div><p>Author:
<span class="author">Sebastien Alborini</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
- </p><div class="section" id="N13b9"><div class="titlepage"><h2 class="title"
style="clear: all"><a name="N13b9"></a><span class="title">What is
jboss.xml?</span></h2></div><p>
+ </p><div class="section"><a name="N1433"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1433"></a><span class="title">What is
jboss.xml?</span></h2></div></div><p>
To deploy your beans, you have to specify (nearly) everything about them in a
file called ejb-jar.xml.
This file will be stored in the META-INF directory in your ejb-jar file. The
1.2 +1 -1 newsite/documentation/HTML/ch06s02.html
Index: ch06s02.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch06s02.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch06s02.html 2001/02/11 16:02:05 1.1
+++ ch06s02.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Specifying the deployment name of your beans</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.25" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch06.html" rel="up" title="6. Advanced container
configuration"><link href="ch06.html" rel="previous" title="6. Advanced container
configuration"><link href="ch06s03.html" rel="next" title="Declaring an ejb
references"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch06.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a !
href="ch06.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch06s03.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N13ce"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N13ce"></a><span
class="title">Specifying the deployment name of your beans</span></h2></div><p>
+<html><head><title>Specifying the deployment name of your beans</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch06.html" rel="up" title="Chapter 6. Advanced
container configuration"><link href="ch06.html" rel="previous" title="Chapter 6.
Advanced container configuration"><link href="ch06s03.html" rel="next"
title="Declaring an ejb references"></head><body alink="#0000FF" bgcolor="white"
link="#0000FF" text="black" vlink="#840084"><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/jboss.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch06.html"><img border="0" height="65"
src="images/toc.gif" wi!
dth="60"></a><a href="ch06.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch06s03.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1448"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1448"></a><span class="title">Specifying the deployment
name of your beans</span></h2></div></div><p>
You have coded your beans. You now want to deploy them and be
able to access them from your clients.
</p><p>
1.2 +1 -1 newsite/documentation/HTML/ch06s03.html
Index: ch06s03.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch06s03.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch06s03.html 2001/02/11 16:02:05 1.1
+++ ch06s03.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Declaring an ejb references</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch06.html" rel="up" title="6. Advanced container
configuration"><link href="ch06s02.html" rel="previous" title="Specifying the
deployment name of your beans"><link href="ch06s04.html" rel="next" title="Container
configuration"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch06.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch0!
6s02.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch06s04.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N140c"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N140c"></a><span
class="title">Declaring an ejb references</span></h2></div><p>
+<html><head><title>Declaring an ejb references</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch06.html" rel="up" title="Chapter 6. Advanced container
configuration"><link href="ch06s02.html" rel="previous" title="Specifying the
deployment name of your beans"><link href="ch06s04.html" rel="next" title="Container
configuration"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch06.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a h!
ref="ch06s02.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch06s04.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N1486"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1486"></a><span class="title">Declaring an ejb
references</span></h2></div></div><p>
An ejb reference (see ejb1.1 specification, 14.3, p207) is when a bean A wants
to call methods on a bean B.
We are talking about intra-bean calls also called B2B calls. This is not for
1.2 +15 -15 newsite/documentation/HTML/ch06s04.html
Index: ch06s04.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch06s04.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch06s04.html 2001/02/11 16:02:05 1.1
+++ ch06s04.html 2001/03/12 01:54:47 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Container configuration</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch06.html" rel="up" title="6. Advanced container
configuration"><link href="ch06s03.html" rel="previous" title="Declaring an ejb
references"><link href="ch07.html" rel="next" title="7. Container architecture -
design notes"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch06.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch06s03.ht!
ml"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch07.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section" id="N1444"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N1444"></a><span
class="title">Container configuration</span></h2></div><p>
+<html><head><title>Container configuration</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch06.html" rel="up" title="Chapter 6. Advanced container
configuration"><link href="ch06s03.html" rel="previous" title="Declaring an ejb
references"><link href="ch07.html" rel="next" title="Chapter 7. Working with Message
Driven Beans"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch06.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href!
="ch06s03.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch07.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N14be"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N14be"></a><span class="title">Container configuration</span></h2></div></div><p>
When you deploy an application, JBoss creates a container for each of your
beans. This container will be used
only for this particular bean. It must be configured according to the type of
@@ -188,19 +188,19 @@
</container-configurations>
...
</jboss>
-</pre><div class="itemizedlist"><ul><li><a
name="N1488"></a><p><cache-policy-conf> and its subtags are optional, so you
+</pre><div class="itemizedlist"><ul><li><p><a
name="N1502"></a><cache-policy-conf> and its subtags are optional, so you
can specify none, few or all of them.
<min-capacity> specifies the minimum capacity of the cache. The
cache can be empty, but will have room for at least
5 beans (in the above case); this value cannot be less than 2; the resizer
(see below) will shrink the cache capacity
down to but not less than this value.
-</p></li><li><a name="N148e"></a><p><max-capacity> specifies the maximum
capacity of the
+</p></li><li><p><a name="N1508"></a><max-capacity> specifies the maximum
capacity of the
cache. The cache can be empty, but will have room for at most 200
beans (in the above case); this value cannot be less than the minimum
capacity; the resizer (see below) will enlarge the
cache capacity up to but not more than this value.
-</p></li><li><a name="N1494"></a><p><overager-period> specifies the period of
the overager,
+</p></li><li><p><a name="N150e"></a><overager-period> specifies the period of
the overager,
that is a periodic task that runs (in the above case) every 300
seconds. Purpose of this periodic task is to see if in the cache there are
very old beans, and to passivate them.
@@ -208,7 +208,7 @@
below). While the period of this task is 300 seconds, the first run happens at
a random time between 0 and 300 seconds.
To disable the overager set the period to 0.
-</p></li><li><a name="N149a"></a><p><max-bean-age> specifies the max age a
bean can have
+</p></li><li><p><a name="N1514"></a><max-bean-age> specifies the max age a
bean can have
before being passivated by the overager (in this case 600 seconds).
The tag <resizer-period> specifies the period of the resizer, that
is a periodic task that runs (in the above case) every
@@ -217,7 +217,7 @@
While the period of this task is 400 seconds, the first run happens at a
random time between 0 and 400 seconds.
To disable the resizer set the period to 0.
-</p></li><li><a
name="N14a0"></a><p><max-cache-miss-period>,<min-cache-miss-period>
+</p></li><li><p><a
name="N151a"></a><max-cache-miss-period>,<min-cache-miss-period>
and <cache-load-factor> control the resizer in this way: the
number of
cache misses is internally recorded. When the resizer runs, it sees what is
@@ -243,32 +243,32 @@
<container-configuration> tag in jboss.xml. See the jboss.xml DTD
for
more details:
-</p><div class="itemizedlist"><ul><li><a name="N14af"></a><p><call-logging>
this tag must have a boolean value: true
+</p><div class="itemizedlist"><ul><li><p><a name="N1529"></a><call-logging>
this tag must have a boolean value: true
or false. It tells the container if calls to this bean must be
logged or not. It is set to false in standard configurations.
-</p></li><li><a name="N14b5"></a><p><container-invoker> the container invoker.
-</p></li><li><a name="N14bb"></a><p><instance-pool> the instance pool is a
set (a "pool") of
+</p></li><li><p><a name="N152f"></a><container-invoker> the container invoker.
+</p></li><li><p><a name="N1535"></a><instance-pool> the instance pool is a
set (a "pool") of
free (ie not currently associated to a context) instances of the
bean. When an instance of the bean is no longer used, it is thrown back to the
pool. This is not used for Stateful Session
Beans, since the instances are not reusable.
-</p></li><li><a name="N14c1"></a><p><instance-cache> the cache contains the
instances of a
+</p></li><li><p><a name="N153b"></a><instance-cache> the cache contains the
instances of a
bean which are currently associated to a context. If it grows too
big, the cache may decide to passivate some of the instances. This is not used
for Stateless Session Beans, since these
are directly reusable after a call.
-</p></li><li><a name="N14c7"></a><p><persistence-manager> the persistence
manager is in
+</p></li><li><p><a name="N1541"></a><persistence-manager> the persistence
manager is in
charge of storing permanent information in the instance of a bean.
For BMP Entities, it will merely transmit orders to the bean; for Stateful
Sessions and CMP Entities, it has to save the
state of the bean. This is not used for Stateless Session Beans, since they
don't have a state to save.
-</p></li><li><a name="N14cd"></a><p><container-invoker-conf> configuration of
the container
+</p></li><li><p><a name="N1547"></a><container-invoker-conf> configuration of
the container
invoker.
-</p></li><li><a name="N14d3"></a><p><container-cache-conf> configuration of
the cache. For
+</p></li><li><p><a name="N154d"></a><container-cache-conf> configuration of
the cache. For
example, you may specify the time interval between passivations.
-</p></li><li><a name="N14d9"></a><p><container-pool-conf> configuration of
the pool. Mainly,
+</p></li><li><p><a name="N1553"></a><container-pool-conf> configuration of
the pool. Mainly,
the size of the pool.
-</p></li><li><a name="N14df"></a><p><commit-option> must be A, B or C. See
the ejb
+</p></li><li><p><a name="N1559"></a><commit-option> must be A, B or C. See
the ejb
specification for more details.
</p></li></ul></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch06.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch06s03.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch07.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.2 +4 -43 newsite/documentation/HTML/ch07.html
Index: ch07.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch07.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch07.html 2001/02/11 16:02:05 1.1
+++ ch07.html 2001/03/12 01:54:48 1.2
@@ -1,43 +1,4 @@
-<html><head><title>7. Container architecture - design notes</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.25" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="index.html" rel="up" title="JBoss 2.0
documentation"><link href="ch06s04.html" rel="previous" title="Container
configuration"><link href="ch07s04.html" rel="next" title="Client
Objects"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch06s04.html"><img border="0" !
height="65" src="images/prev.gif" width="76"></a><a href="ch07s04.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N14e8"><div
class="titlepage"><h2 class="title"><a name="N14e8">7. Container architecture - design
notes</a></h2></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="ch07.html#N1501">Introduction</a></dt><dt> <a href="ch07s04.html">Client
Objects</a></dt><dt> <a href="ch07s17.html">JMX - foundation of JBoss
infrastructure</a></dt><dt> <a href="ch07s21.html">ContainerInvoker - Container entry
point</a></dt><dt> <a href="ch07s31.html">Container</a></dt><dt> <a
href="ch07s63.html"> Transaction support </a></dt><dt> <a
href="ch07s68.html">Security</a></dt><dt> <a href="ch07s72.html">Tracing the call
through container</a></dt></dl></div><p>Author:
- <span class="author">Vladimir Blagojevic</span>
- <tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
- <span class="author">Rickard Oberg</span>
- <tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
- </p><div class="section" id="N1501"><div class="titlepage"><h2 class="title"
style="clear: all"><a name="N1501"></a><span
class="title">Introduction</span></h2></div><div class="section" id="N1506"><div
class="titlepage"><h3 class="title"><a name="N1506"></a><span class="title">JBoss 1.0
(a.k.a EJBoss/NextGen)</span></h3></div><p>JBoss 1.0, a.k.a EJBoss was started in
March 1999 and reached 1.0
- status in February 2000. The long march towards the promised land of
- 1.0'ness was not taken lightly. JBoss 1.0 established itself as a
- technological leader with many ease of use features pioneered here
- before finding their way to the broader audience of commercial
- container developers. Mostly thanks to Rickard Oberg, the design
- of 1.0 introduced many standard setting features such
- as Proxy based deployment and distributed containers.</p><p>Marc Fleury had been
working for almost 6 months on a traditional,
- compilation heavy approach to the container design, when Rickard came
- along with the logical skeletons and the dynamic proxies as the basis
- for a radically new design. Marc started coding feverishly and codenamed
- the container "NextGen" truly believing it was a blueprint of things to
- come, a "next generation" container.</p></div><div class="section"
id="N1512"><div class="titlepage"><h3 class="title"><a name="N1512"></a><span
class="title">JBoss 2.0</span></h3></div><p>JBoss 2.0 that we are about to explore is
truly a 3rd generation
- container. It takes the patterns and ideas that were investigated in
- 1.0 and then does it right. Designed from the ground up to be modular,
- JBoss introduces yet again many ground breaking features, such as
- automated re-deploy, but most importantly a plug-in approach to
- container implementation. Borrowing from the success that met with
- Linux 2.0 and a it's modular approach to Open Source software
- implementation, JBoss 2.0 is meant to be developed by distributed
- parties each working on a cleanly separated part of the server.</p><p>JBoss 2.0
also standardizes on JMX, the Java Management eXtension
- (TM) to offer standard interfaces to the management of its components
- as well as the applications deployed on it. Ease of use is still the
- number one priority here at JBoss, and JBoss 2.0 will set a new
- standard.</p><p>We have to admit that it was hard to decide where to begin and how
- to proceed on this journey through JBoss. Although it's architecture is
- clean, modular, and a mecca of best programming practices we know of,
- the inhereted complexity of a distributed system carries it's weight.</p><p>In
order to understand how JBoss 2.0 works one could go many ways.
- The approach we chose could be loosely described as "follow the call".
- We'll not dwelve into container architecture directly, but in contrast
- will build the foundation first on understanding client object structures,
- how they pass the call to container over the network layer. Finally,
- before we discuss container architecture in detail, we'll focus on
- the container entry point.</p><p> With regard to container architecture, we'll
explore all the
- slices from the container entry point to database access structures,
- focusing on various patterns, the renowned container plugin-in approach,
- and how they relate to key points in EJB in general. </p><p>Now, let's not spoil
all the fun parts.
- Put your helmets on, we are going straight to the
trenches!!!</p></div></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch06s04.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch07s04.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
+<html><head><title>Chapter 7. Working with Message Driven Beans</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="index.html" rel="up" title="JBoss 2.0
documentation"><link href="ch06s04.html" rel="previous" title="Container
configuration"><link href="ch07s02.html" rel="next" title="Six steps to MDB nirvana in
JBoss"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch06s04!
.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch07s02.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N1562"><div
class="titlepage"><div><h2 class="title"><a name="N1562"></a>Chapter 7. Working with
Message Driven Beans</h2></div></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="ch07.html#N1573">Introduction</a></dt><dt> <a
href="ch07s02.html">Six steps to MDB nirvana in JBoss</a></dt><dt> <a
href="ch07s03.html">Writing Message Driven Bean</a></dt><dt> <a
href="ch07s07.html">Advanced MDB configuration</a></dt></dl></div><p>Author:
+ <span class="author">Peter Antman</span>
+ <tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
+ </p><div class="section"><a name="N1573"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1573"></a><span
class="title">Introduction</span></h2></div></div><p>This chapter describes how to use
Message Driven Beans with JBoss. Message Driven Beans are a new bean type added in the
EJB 2.0 specification. They are therefore still somewhat unknown and under utilized.
Hopefully this documentation will lessen that a bit, since JBoss has full support for
Message Driven Beans.</p></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch06s04.html"><img border="0" height="65"
src="imag!
es/prev.gif" width="76"></a><a href="ch07s02.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
1.2 +43 -114 newsite/documentation/HTML/ch08.html
Index: ch08.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/ch08.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ch08.html 2001/02/11 16:02:07 1.1
+++ ch08.html 2001/03/12 01:54:49 1.2
@@ -1,114 +1,43 @@
-<html><head><title>8. Howto</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.25" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="index.html"
rel="up" title="JBoss 2.0 documentation"><link href="ch07s72.html" rel="previous"
title="Tracing the call through container"><link href="ch08s07.html" rel="next"
title="Running the Examples from Enterprise JavaBeans, by Richard Monson-Haefel (Unix)
"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60!
"></a><a href="ch07s72.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch08s07.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="chapter"
id="N1a2b"><div class="titlepage"><h2 class="title"><a name="N1a2b">8.
Howto</a></h2></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="ch08.html#N1a2f">Running Tomcat with JBoss</a></dt><dt> <a
href="ch08s07.html">Running the Examples from Enterprise JavaBeans, by Richard
Monson-Haefel (Unix) </a></dt><dt> <a href="ch08s08.html">JMX Connector Description
and HowTo</a></dt><dt> <a href="ch08s24.html">How To us the Timer MBean</a></dt><dt>
<a href="ch08s27.html">Deployment on JBoss</a></dt><dt> <a href="ch08s32.html">JAAS
Based Security in JBoss</a></dt><dt> <a href="ch08s39.html">Using JavaMail in
JBoss</a></dt><dt> <a href="ch08s42.html">How to Run JBoss in JBuilder's
Debugger</a></dt><dt> <a href="ch08s45.html">EJX/AWT Develop!
ment HowTo</a></dt><dt> <a href="ch08s70.html">JBossCX
Configuration</a></dt></dl></div><div class="section" id="N1a2f"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="N1a2f"></a><span
class="title">Running Tomcat with JBoss</span></h2></div><div class="section"
id="N1a33"><div class="titlepage"><h3 class="title"><a name="N1a33"></a><span
class="title">Goal</span></h3></div><p>
- As part of project Game Over, the JBoss organization wants to deliver a complete
J2EE based product to the market. The JBoss organization decided to integrate the
Tomcat
- engine stack with a running version of JBoss in a single VM. Now you can serve
all your servlet and JSP needs with 2 simple downloads and a couple of configuration
files.
- Check out the Tomcat homepage for information related to Tomcat. </p><p>
- The goal of this page is to explain how to make JBoss automatically start Tomcat,
so that it runs in the same VM.</p></div><div class="section" id="N1a3e"><div
class="titlepage"><h3 class="title"><a name="N1a3e"></a><span
class="title">Benefits</span></h3></div><p>
- One benefit of running Tomcat inside the same VM as JBoss is to have an easier to
manage application server. The main goal, however, is greater performance. By
eliminating
- unnecessary network calls and keeping all the invocations inside one VM the
performance is significantly enhanced.</p><p>
- If you have Servlets/JSPs which access some EJBs, you'll get dramatically
improved performance because the calls will be intra-VM (no network access).</p><p>
- WARNING
- THIS IS STILL A BETA VERSION. </p></div><div class="section" id="N1a4c"><div
class="titlepage"><h3 class="title"><a name="N1a4c"></a><span
class="title">Requirements</span></h3></div><p>
- JBoss 2.0. BETA-PROD 03
- Tomcat Version 3.2b4. You can get the latest release of tomcat from the
jakarta website.</p><p>
- NOTE: This has been tested with tomcat up to 3.2b6, and should work with the
forthcoming final 3.2 version. However it won't run on tomcat 3.1, and tomcat 3.3 is
not
- suppported yet. </p></div><div class="section" id="N1a57"><div
class="titlepage"><h3 class="title"><a name="N1a57"></a><span class="title">How-to
setup jboss for tomcat</span></h3></div><p>
- <div class="itemizedlist"><ul><li><a name="N1a5f"></a><p>Setup environment
variables.In whatever batch or shell script you use to launch JBoss and Tomcat, add
entries for the following environment variables
-
- <div class="table"><p><a name="N1a62"></a><b>Table 8.1. Enviromental
variables</b></p><table border="1" summary="Enviromental
variables"><colgroup><col><col></colgroup><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>TOMCAT_HOME</td><td>The
base directory of Tomcat's binaries. With the binary distribution, this would be
jakarta-tomcat under your installation root</td></tr><tr><td>JAVA_HOME</td><td>The
base directory of your JDK 1.2.2 or 1.3
installation</td></tr><tr><td>CLASSPATH</td><td>This should not include anything
(unless you really know what you're doing!). Both Tomcat and JBoss have startup
scripts that load the necessary
- JARs onto the classpath.</td></tr></tbody></table></div>
- </p></li><li><a name="N1a98"></a><p>Edit jboss.conf. It is located in the conf
directory under the base of your JBoss binary distribution, or the dist/conf directory
- if you built from the JBoss source. There are some commented-out lines near
the end of the file that deal with Tomcat:
-
- <pre class="programlisting">
- <!--
- -- Uncomment this to add "Integrated Stack (fast) Tomcat support".
- -- This service allows you to integrate the stack of Tomcat and jboss.
- -- Invocations are not going through network but pass native
- -- pointers resulting in dramatic speed increases.
- -- This service allows the J2EE deployer to add and remove Tomcat contexts
dynamically
- -- through JMX for you and in effect deploy EARs. Note that tomcat's
- -- server.xml file will be partially processed for context support: you can
- -- also use JMX to add contexts.
- -- Use the J2EE deployer to deploy full EARs on this stack
- -- Be sure to set your 'TOMCAT_HOME' environment variable before starting
JBoss.
- --
- -- The ARG tags are the config file and the port to run tomcat on. Note:
only the url
- -- contexts will be parsed, (path and docBase attruibutes only) all other
- -- configurations are not yet supported.
- --
- -- MLET CODE = "org.jboss.tomcat.EmbeddedTomcatService" ARCHIVE="jboss.jar"
CODEBASE="../../lib/ext/">
- -- ARG TYPE="java.lang.String" VALUE="full path to tomcat config file">
- -- ARG TYPE="int" VALUE=8080>
- -- /MLET>
- </pre>
- </p><p>
- You need to uncomment these lines so they read as follows (note you must add
the < signs at the beginning of the
- three relevant lines and the file path must always begin with a '/'):
- <pre class="programlisting">
- <MLET CODE = "org.jboss.tomcat.EmbeddedTomcatService" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
- <ARG TYPE="java.lang.String" VALUE="/yyy/server.xml">
- <ARG TYPE="int" VALUE=8080>
- </MLET>
-
- </pre>
- </p></li><li><a name="N1aaa"></a><p>Start JBoss. If you start JBoss now by
typing run.sh (or run.bat for Windows) you should see the following Tomcat related
output
- in your log messages:
-
- <pre class="programlisting">
- ...
- [EmbeddedTomcat] Initializing
- [EmbeddedTomcat] Initialized
- [EmbeddedTomcat] Starting
- [EmbeddedTomcat] Testing if Tomcat is present....
- [EmbeddedTomcat] OK
- [EmbeddedTomcat] ContextManager: Adding context Ctx( )
- [EmbeddedTomcat] path="" :jsp: init
- [EmbeddedTomcat] PoolTcpConnector: Starting HttpConnectionHandler on 8080
- [EmbeddedTomcat] Started
- ...
-
- </pre>
- </p></li></ul></div>
- </p><p>
- That's it !! You just have to launch JBoss now and it will start Tomcat and you
will have an EJB/JSPs/Servlets server running in one VM... </p></div><div
class="section" id="N1aba"><div class="titlepage"><h3 class="title"><a
name="N1aba"></a><span class="title">How-to build web applications for jboss and
tomcat</span></h3></div><p>
- In order to benefit from the classloader integration, you have to deploy your
application in an ear file as recommended by the J2EE specification.</p><p>
- Tomcat's server.xml file will not be processed!</p><p>
- The reason is that we want to share the classloader for your application between
tomcat and jboss. Since this classloader must be initialized at
- deployment time, your EJBs and your servlets/JSPs must be bundled together for
jboss to know who talks to whom! </p><p>
- In case you don't want to read all the J2EE spec, here is a brief summary of what
you have to do:</p><div class="orderedlist"><ol type="1"><li><a
name="N1ad0"></a><p>Write your beans and package them in an ejb-jar file. You don't
have to do anything special here.
- See the manual for details on how to package beans for jboss.</p></li><li><a
name="N1ad4"></a><p>Write your servlets/JSPs and package them in a war file. Assuming
you have a bean deployed under the jndi name "myBean",
- the calls to this bean from your servlets will look like that: </p><pre
class="programlisting">
- MyBeanHome home = (MyBeanHome)new InitialContext().lookup("myBean");
- MyBean bean = home.create();
- </pre><p>
- Notes:
- We don't support lookups in the "java:" namespace from the servlets yet,
but work is in progress.
- Since jboss takes care of the classloader stuff, you don't have to
include much in the WEB-INF/lib directory: you don't any of your beans interfaces, and
you
- don't need the usual jboss-client.jar, jnp-client.jar... </p></li><li><a
name="N1ae1"></a><p>Package your application in an ear file. An ear file is a jar
archive which contains:</p><div class="itemizedlist"><ul><li><a
name="N1ae7"></a><p>Your jar files</p></li><li><a name="N1aeb"></a><p>Your war
files</p></li><li><a name="N1aef"></a><p>A deployment descriptor for your application.
This file must be named "application.xml", and must be located in the META-INF
- directory in the ear archive. This file tells jboss which modules are
EJBs, which ones are web modules, and the context paths for the web-modules.
- Here is a sample application.xml file:
-
- <pre class="programlisting">
- <?xml version="1.0" encoding="ISO-8859-1"?>
-
- <application>
- <display-name>My application</display-name>
-
- <module>
- <web>
- <web-uri>webmodule.war</web-uri>
- <context-root>/servlets</context-root>
- </web>
- </module>
-
- <module>
- <ejb>beans.jar</ejb>
- </module>
-
- </application>
- </pre>
- </p></li></ul></div><p>
- See also the DTD for application.xml on Javasoft's website.
</p></li><li><a name="N1afd"></a><p>Deploy your ear file. Surf to
http://yourhost:8082, and find the J2eeDeployer service. Give it the URL of your ear
file
- (don't forget the protocol, be it http: or file:), and click on the deploy
button.</p></li><li><a name="N1b01"></a><p>That's it! The server console should show
your application being deployed on tomcat and jboss, and your web module should be
available on
- http://yourhost:8080/servlets (assuming the context-root was
"/servlets").</p></li></ol></div><p>
- For a full example including a servlet and an EJB, see the contrib module
</p></div></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch07s72.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch08s07.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
+<html><head><title>Chapter 8. Container architecture - design notes</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="index.html" rel="up" title="JBoss 2.0
documentation"><link href="ch07s07.html" rel="previous" title="Advanced MDB
configuration"><link href="ch08s04.html" rel="next" title="Client
Objects"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch07s07.html"><img !
border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch08s04.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="chapter" id="N17cd"><div
class="titlepage"><div><h2 class="title"><a name="N17cd"></a>Chapter 8. Container
architecture - design notes</h2></div></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="ch08.html#N17e6">Introduction</a></dt><dt> <a
href="ch08s04.html">Client Objects</a></dt><dt> <a href="ch08s17.html">JMX -
foundation of JBoss infrastructure</a></dt><dt> <a
href="ch08s21.html">ContainerInvoker - Container entry point</a></dt><dt> <a
href="ch08s31.html">Container</a></dt><dt> <a href="ch08s63.html"> Transaction support
</a></dt><dt> <a href="ch08s68.html">Security</a></dt><dt> <a
href="ch08s72.html">Tracing the call through container</a></dt></dl></div><p>Author:
+ <span class="author">Vladimir Blagojevic</span>
+ <tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
+ <span class="author">Rickard Oberg</span>
+ <tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
+ </p><div class="section"><a name="N17e6"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N17e6"></a><span
class="title">Introduction</span></h2></div></div><div class="section"><a
name="N17eb"></a><div class="titlepage"><div><h3 class="title"><a
name="N17eb"></a><span class="title">JBoss 1.0 (a.k.a
EJBoss/NextGen)</span></h3></div></div><p>JBoss 1.0, a.k.a EJBoss was started in March
1999 and reached 1.0
+ status in February 2000. The long march towards the promised land of
+ 1.0'ness was not taken lightly. JBoss 1.0 established itself as a
+ technological leader with many ease of use features pioneered here
+ before finding their way to the broader audience of commercial
+ container developers. Mostly thanks to Rickard Oberg, the design
+ of 1.0 introduced many standard setting features such
+ as Proxy based deployment and distributed containers.</p><p>Marc Fleury had been
working for almost 6 months on a traditional,
+ compilation heavy approach to the container design, when Rickard came
+ along with the logical skeletons and the dynamic proxies as the basis
+ for a radically new design. Marc started coding feverishly and codenamed
+ the container "NextGen" truly believing it was a blueprint of things to
+ come, a "next generation" container.</p></div><div class="section"><a
name="N17f7"></a><div class="titlepage"><div><h3 class="title"><a
name="N17f7"></a><span class="title">JBoss 2.0</span></h3></div></div><p>JBoss 2.0
that we are about to explore is truly a 3rd generation
+ container. It takes the patterns and ideas that were investigated in
+ 1.0 and then does it right. Designed from the ground up to be modular,
+ JBoss introduces yet again many ground breaking features, such as
+ automated re-deploy, but most importantly a plug-in approach to
+ container implementation. Borrowing from the success that met with
+ Linux 2.0 and a it's modular approach to Open Source software
+ implementation, JBoss 2.0 is meant to be developed by distributed
+ parties each working on a cleanly separated part of the server.</p><p>JBoss 2.0
also standardizes on JMX, the Java Management eXtension
+ (TM) to offer standard interfaces to the management of its components
+ as well as the applications deployed on it. Ease of use is still the
+ number one priority here at JBoss, and JBoss 2.0 will set a new
+ standard.</p><p>We have to admit that it was hard to decide where to begin and how
+ to proceed on this journey through JBoss. Although it's architecture is
+ clean, modular, and a mecca of best programming practices we know of,
+ the inhereted complexity of a distributed system carries it's weight.</p><p>In
order to understand how JBoss 2.0 works one could go many ways.
+ The approach we chose could be loosely described as "follow the call".
+ We'll not dwelve into container architecture directly, but in contrast
+ will build the foundation first on understanding client object structures,
+ how they pass the call to container over the network layer. Finally,
+ before we discuss container architecture in detail, we'll focus on
+ the container entry point.</p><p> With regard to container architecture, we'll
explore all the
+ slices from the container entry point to database access structures,
+ focusing on various patterns, the renowned container plugin-in approach,
+ and how they relate to key points in EJB in general. </p><p>Now, let's not spoil
all the fun parts.
+ Put your helmets on, we are going straight to the
trenches!!!</p></div></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch07s07.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch08s04.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
1.2 +1 -1 newsite/documentation/HTML/index.html
Index: index.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/index.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- index.html 2001/02/11 16:02:08 1.1
+++ index.html 2001/03/12 01:54:54 1.2
@@ -1 +1 @@
-<html><head><title>JBoss 2.0 documentation</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.25"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="pr01.html" rel="next" title="Preface"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif"
width="63"></a> <a href="pr01.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="book"
id="Na21"><div class="titlepage"><h1 class="title"><a name="Na21"></a>JBoss 2.0
documentation</h1><p class="copyright">Copyright © 2000, 2001 by JBo!
ss Organization</p><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>
<a href="pr01.html">Preface</a></dt><dd><dl><dt> <a
href="pr01.html#Na37">Docbook</a></dt></dl></dd><dt>1. <a href="ch01.html">First
steps</a></dt><dd><dl><dt> <a href="ch01.html#Na78">Introduction</a></dt><dt> <a
href="ch01s05.html">Installing JBoss</a></dt><dt> <a href="ch01s06.html">Creating the
Bean</a></dt><dt> <a href="ch01s07.html">EJBs: review</a></dt><dt> <a
href="ch01s08.html">Coding the classes</a></dt><dt> <a href="ch01s09.html">The
deployment descriptor</a></dt><dt> <a href="ch01s10.html">Packaging and deploying the
bean</a></dt><dt> <a href="ch01s11.html">Coding the test client</a></dt><dt> <a
href="ch01s12.html">Compiling and running test client</a></dt></dl></dd><dt>2. <a
href="ch02.html">Basic configuration</a></dt><dd><dl><dt> <a href="ch02.html#Nc96">In
a nutshell</a></dt></dl></dd><dt>3. <a href="ch03.html">JDBC/Database
configuration</a></dt><dd><dl><dt> <a href="ch03.h!
tml#Nd5e">Introduction</a></dt><dt> <a href="ch03s05.html">Creating DB Connection
Pools</a></dt></dl></dd><dt>4. <a href="ch04.html">Using container-managed
persistence</a></dt><dd><dl><dt> <a href="ch04.html#N10e1">Introduction</a></dt><dt>
<a href="ch04s07.html">Container Managed Persistence - CMP</a></dt><dt> <a
href="ch04s09.html">Creating the Beans</a></dt><dt> <a href="ch04s10.html">Packaging
and deploying the Beans</a></dt><dt> <a href="ch04s11.html">Creating a test client
</a></dt><dt> <a href="ch04s12.html">Discussion: container-managed
persistence</a></dt></dl></dd><dt>5. <a href="ch05.html">Customizing
JAWS</a></dt><dd><dl><dt> <a href="ch05.html#N1289">Introduction</a></dt><dt> <a
href="ch05s02.html">Specifying a datasource</a></dt><dt> <a href="ch05s03.html">JAWS
Options</a></dt><dt> <a href="ch05s04.html">Telling JAWS about your
tables</a></dt><dt> <a href="ch05s05.html">Declaring finders</a></dt><dt> <a
href="ch05s06.html">Defining a type mapping</a></dt></dl>!
</dd><dt>6. <a href="ch06.html">Advanced container configuration</a></dt><dd><dl><dt>
<a href="ch06.html#N13b9">What is jboss.xml?</a></dt><dt> <a
href="ch06s02.html">Specifying the deployment name of your beans</a></dt><dt> <a
href="ch06s03.html">Declaring an ejb references</a></dt><dt> <a
href="ch06s04.html">Container configuration</a></dt></dl></dd><dt>7. <a
href="ch07.html">Container architecture - design notes</a></dt><dd><dl><dt> <a
href="ch07.html#N1501">Introduction</a></dt><dt> <a href="ch07s04.html">Client
Objects</a></dt><dt> <a href="ch07s17.html">JMX - foundation of JBoss
infrastructure</a></dt><dt> <a href="ch07s21.html">ContainerInvoker - Container entry
point</a></dt><dt> <a href="ch07s31.html">Container</a></dt><dt> <a
href="ch07s63.html"> Transaction support </a></dt><dt> <a
href="ch07s68.html">Security</a></dt><dt> <a href="ch07s72.html">Tracing the call
through container</a></dt></dl></dd><dt>8. <a
href="ch08.html">Howto</a></dt><dd><dl><dt> <a href="ch08!
.html#N1a2f">Running Tomcat with JBoss</a></dt><dt> <a href="ch08s07.html">Running the
Examples from Enterprise JavaBeans, by Richard Monson-Haefel (Unix) </a></dt><dt> <a
href="ch08s08.html">JMX Connector Description and HowTo</a></dt><dt> <a
href="ch08s24.html">How To us the Timer MBean</a></dt><dt> <a
href="ch08s27.html">Deployment on JBoss</a></dt><dt> <a href="ch08s32.html">JAAS Based
Security in JBoss</a></dt><dt> <a href="ch08s39.html">Using JavaMail in
JBoss</a></dt><dt> <a href="ch08s42.html">How to Run JBoss in JBuilder's
Debugger</a></dt><dt> <a href="ch08s45.html">EJX/AWT Development HowTo</a></dt><dt> <a
href="ch08s70.html">JBossCX Configuration</a></dt></dl></dd></dl></div></div><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src!
="images/doc.gif" width="63"></a> <a href="pr01.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
+<html><head><title>JBoss 2.0 documentation</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="pr01.html" rel="next" title="Preface"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif"
width="63"></a> <a href="pr01.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="book"
id="Na21"><div class="titlepage"><div><h1 class="title"><a name="Na21"></a>JBoss 2.0
documentation</h1></div><div><p class="copyright">Copyright © 2!
000, 2001 JBoss Organization</p></div><hr></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="pr01.html">Preface</a></dt><dd><dl><dt> <a
href="pr01.html#Na37">Docbook</a></dt></dl></dd><dt>1. <a href="ch01.html">First
steps</a></dt><dd><dl><dt> <a href="ch01.html#Na78">Introduction</a></dt><dt> <a
href="ch01s05.html">Installing JBoss</a></dt><dt> <a href="ch01s06.html">Creating the
Bean</a></dt><dt> <a href="ch01s07.html">EJBs: review</a></dt><dt> <a
href="ch01s08.html">Coding the classes</a></dt><dt> <a href="ch01s09.html">The
deployment descriptor</a></dt><dt> <a href="ch01s10.html">Packaging and deploying the
bean</a></dt><dt> <a href="ch01s11.html">Coding the test client</a></dt><dt> <a
href="ch01s12.html">Compiling and running test client</a></dt></dl></dd><dt>2. <a
href="ch02.html">Basic configuration</a></dt><dd><dl><dt> <a href="ch02.html#Nc9f">In
a nutshell</a></dt></dl></dd><dt>3. <a href="ch03.html">JDBC/Database
configuration</a></dt><dd><dl><!
dt> <a href="ch03.html#Nd67">Introduction</a></dt><dt> <a href="ch03s05.html">Creating
DB Connection Pools</a></dt></dl></dd><dt>4. <a href="ch04.html">Using
container-managed persistence</a></dt><dd><dl><dt> <a
href="ch04.html#N1158">Introduction</a></dt><dt> <a href="ch04s07.html">Container
Managed Persistence - CMP</a></dt><dt> <a href="ch04s09.html">Creating the
Beans</a></dt><dt> <a href="ch04s10.html">Packaging and deploying the
Beans</a></dt><dt> <a href="ch04s11.html">Creating a test client </a></dt><dt> <a
href="ch04s12.html">Discussion: container-managed persistence</a></dt></dl></dd><dt>5.
<a href="ch05.html">Customizing JAWS</a></dt><dd><dl><dt> <a
href="ch05.html#N1303">Introduction</a></dt><dt> <a href="ch05s02.html">Specifying a
datasource</a></dt><dt> <a href="ch05s03.html">JAWS Options</a></dt><dt> <a
href="ch05s04.html">Telling JAWS about your tables</a></dt><dt> <a
href="ch05s05.html">Declaring finders</a></dt><dt> <a href="ch05s06.html">Defining a
type ma!
pping</a></dt></dl></dd><dt>6. <a href="ch06.html">Advanced container
configuration</a></dt><dd><dl><dt> <a href="ch06.html#N1433">What is
jboss.xml?</a></dt><dt> <a href="ch06s02.html">Specifying the deployment name of your
beans</a></dt><dt> <a href="ch06s03.html">Declaring an ejb references</a></dt><dt> <a
href="ch06s04.html">Container configuration</a></dt></dl></dd><dt>7. <a
href="ch07.html">Working with Message Driven Beans</a></dt><dd><dl><dt> <a
href="ch07.html#N1573">Introduction</a></dt><dt> <a href="ch07s02.html">Six steps to
MDB nirvana in JBoss</a></dt><dt> <a href="ch07s03.html">Writing Message Driven
Bean</a></dt><dt> <a href="ch07s07.html">Advanced MDB
configuration</a></dt></dl></dd><dt>8. <a href="ch08.html">Container architecture -
design notes</a></dt><dd><dl><dt> <a href="ch08.html#N17e6">Introduction</a></dt><dt>
<a href="ch08s04.html">Client Objects</a></dt><dt> <a href="ch08s17.html">JMX -
foundation of JBoss infrastructure</a></dt><dt> <a href="ch08s!
21.html">ContainerInvoker - Container entry point</a></dt><dt> <a
href="ch08s31.html">Container</a></dt><dt> <a href="ch08s63.html"> Transaction support
</a></dt><dt> <a href="ch08s68.html">Security</a></dt><dt> <a
href="ch08s72.html">Tracing the call through container</a></dt></dl></dd><dt>9. <a
href="ch09.html">Howto</a></dt><dd><dl><dt> <a href="ch09.html#N1d14">Running Tomcat
with JBoss</a></dt><dt> <a href="ch09s07.html">Running the Examples from Enterprise
JavaBeans, by Richard Monson-Haefel (Unix) </a></dt><dt> <a href="ch09s08.html">JMX
Connector Description and HowTo</a></dt><dt> <a href="ch09s24.html">How To us the
Timer MBean</a></dt><dt> <a href="ch09s27.html">Deployment on JBoss</a></dt><dt> <a
href="ch09s32.html">JAAS Based Security in JBoss</a></dt><dt> <a
href="ch09s50.html">Using JavaMail in JBoss</a></dt><dt> <a href="ch09s53.html">How to
Run JBoss in JBuilder's Debugger</a></dt><dt> <a href="ch09s56.html">EJX/AWT
Development HowTo</a></dt><dt> <a href="ch0!
9s81.html">JBossCX Configuration</a></dt><dt> <a href="ch09s92.html">External JNDI
Configuration and JNDI Viewing</a></dt></dl></dd></dl></div></div><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif"
width="63"></a> <a href="pr01.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
\ No newline at end of file
1.2 +1 -1 newsite/documentation/HTML/pr01.html
Index: pr01.html
===================================================================
RCS file: /products/cvs/ejboss/newsite/documentation/HTML/pr01.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- pr01.html 2001/02/11 16:02:08 1.1
+++ pr01.html 2001/03/12 01:54:55 1.2
@@ -1,4 +1,4 @@
-<html><head><title>Preface</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.25" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="index.html"
rel="up" title="JBoss 2.0 documentation"><link href="index.html" rel="previous"
title="JBoss 2.0 documentation"><link href="ch01.html" rel="next" title="1. First
steps"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="index.html"><img border="0" height="65"
src="images/prev.gif" width=!
"76"></a><a href="ch01.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="preface" id="Na35"><div
class="titlepage"></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="pr01.html#Na37">Docbook</a></dt></dl></div><div class="section" id="Na37"><div
class="titlepage"><h2 class="title" style="clear: all"><a name="Na37"></a><span
class="title">Docbook</span></h2></div><p>The approach of writing documentation in
HTML was inheretly problem infested. The content was "polluted" with
+<html><head><title>Preface</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="index.html"
rel="up" title="JBoss 2.0 documentation"><link href="index.html" rel="previous"
title="JBoss 2.0 documentation"><link href="ch01.html" rel="next" title="Chapter 1.
First steps"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="index.html"><img border="0" height="65"
src="images/prev.gif!
" width="76"></a><a href="ch01.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="preface" id="Na35"><div
class="titlepage"><div><h2 class="title"><a
name="Na35"></a>Preface</h2></div></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="pr01.html#Na37">Docbook</a></dt></dl></div><div
class="section"><a name="Na37"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Na37"></a><span
class="title">Docbook</span></h2></div></div><p>The approach of writing documentation
in HTML was inheretly problem infested. The content was "polluted" with
HTML presentational tags and such impossible to convert to any other view. Another
big issue was L&F
consistency. Despite the explicit instruction of which HTML tags to use, authors
couldn't keep up with all complexities
and issue faced when writing HTML documents. Documents were also hard to shuffle
around in a document book thus
1.1 newsite/documentation/HTML/ch07s02.html
Index: ch07s02.html
===================================================================
<html><head><title>Six steps to MDB nirvana in JBoss</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch07.html" rel="up" title="Chapter 7. Working with Message
Driven Beans"><link href="ch07.html" rel="previous" title="Chapter 7. Working with
Message Driven Beans"><link href="ch07s03.html" rel="next" title="Writing Message
Driven Bean"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch07.html"><img border="0" height="65"
src="images/toc.gif" width="60"><!
/a><a href="ch07.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch07s03.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N157b"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N157b"></a><span class="title">Six steps to MDB nirvana in
JBoss</span></h2></div></div><p>If you don't need to do any special configuration and
already know how to code a message driven bean (MDB), here are 6 easy step to get it
up and working with JBoss. (The easiest way to get up and working with Message Driven
Beans in JBoss is the check out the jbosstest from cvs and look into the mdb
test.)</p><div class="orderedlist"><ol type="1"><li><p><a name="N1588"></a>
Check out the latest JBoss from cvs and compile.
</p></li><li><p><a name="N158e"></a>
Write the source code for a Message Driven Bean.
</p></li><li><p><a name="N1594"></a>Write the ejb-jar.xml
descriptor.</p><p>Here is an example for a bean listening on a queue with bean managed
transactions :</p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar>
<!--
PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd"
-->
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>QueueBean</ejb-name>
<ejb-class>org.jboss.test.mdb.bean.QueueBean</ejb-class>
<message-selector></message-selector>
<transaction-type>Bean</transaction-type>
<acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
<message-driven-destination>
<destination-type>javax.jms.Queue</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
</ejb-jar>
</pre><p>
And here are one for a durable topic with container managed
transactions:</p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar>
<message-driven>
<ejb-name>DurableTopicBean</ejb-name>
<ejb-class>org.jboss.test.mdb.bean.TopicBean</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>Durable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>DurableTopicBean</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
</pre></li><li><p><a name="N15aa"></a>
Write the jboss.xml deployment descriptor (this MUST always be done with MDB in
jboss), but for a MDB without special need the container configuration need not be
filled in. </p><p>The destination-jndi-name element points to the queue.</p><p> Here
are the one for the queue bean:</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>QueueBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>queue/testQueue</destination-jndi-name>
</message-driven>
</enterprise-beans>
</jboss>
</pre><p> And here for the durable topic:</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>DurableTopicBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>topic/testDurableTopic</destination-jndi-name>
<mdb-user>john</mdb-user>
<mdb-passwd>needle</mdb-passwd>
<mdb-client-id>DurableSubscriberExample</mdb-client-id>
</message-driven>
</jboss>
</pre></li><li><p><a name="N15c3"></a>
Edit jbossmq.xml in conf/default and ad the queue or topic
</p><p>Eg:</p><pre class="programlisting">
<Queue>
<Name>testQueue</Name>
</Queue>
</pre><p> For the queue, and </p><pre class="programlisting">
<Topic>
<Name>testDurableTopic</Name>
</Topic>
</pre><p>plus</p><pre class="programlisting">
<User>
<Name>john</Name>
<Password>needle</Password>
<Id>DurableSubscriberExample</Id>
<DurableSubscription>
<Name>DurableSubscriberExample</Name>
<TopicName>testDurableTopic</TopicName>
</DurableSubscription>
</User>
</pre><p>for the durable topic.</p></li><li><p><a name="N15e4"></a>
Deploy the bean, for example by packing it in a jar and copy it into the jboss
deploy directory.</p></li></ol></div><p>Start sending messages to your
bean</p></div><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch07.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch07.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch07s03.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch07s03.html
Index: ch07s03.html
===================================================================
<html><head><title>Writing Message Driven Bean</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch07.html" rel="up" title="Chapter 7. Working with Message
Driven Beans"><link href="ch07s02.html" rel="previous" title="Six steps to MDB nirvana
in JBoss"><link href="ch07s07.html" rel="next" title="Advanced MDB
configuration"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch07.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch0!
7s02.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch07s07.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N15ef"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N15ef"></a><span class="title">Writing Message Driven
Bean</span></h2></div></div><p>Message Driven Beans are a new part of EJB 2.0. The
reason these beast where added is that there was no way in EJB 1.1 to handle
asynchronous invocation. The primary reason behind this is that an EJB bean may never
be invoke from other objects other than through its remote interface. Therefore a bean
could never set itself up as a listener for asynchronous invocation.</p><p>With MDB
this lack is filled. An MDB is a bean without a remote interface, where the container
sets itself up as a listener for asynchronous invocation and handles the invocation of
the concrete bean, which follows all th!
e usual roles for EJB beans.</p><p>Message Driven Beans are primarily focused on JMS.
An MDB is either a topic or a queue subscriber. One nice feature with MDB is that one
gets multithreaded subscribers (even for Topics) without having to care about the
subtle difficulties to write multithreaded code and to write multithreaded JMS message
consumers.</p><p>What should you use your beans to then? Basically you would use MDB
any time you are about to create a JMS subscriber. Typical conditions for doing this
is:</p><div class="itemizedlist"><ul><li><a name="N1601"></a>
Decouple an invoker from the invoked code.
</li><li><a name="N1604"></a>
Make it possible for multiple parties to get you messages.
</li><li><a name="N1607"></a>
Get asynchronous behavior, i.e. start long running code without the need to wait for
the call to return.
</li></ul></div><p>Here we will write some typical MDB.</p><div class="section"><a
name="N160e"></a><div class="titlepage"><div><h3 class="title"><a
name="N160e"></a><span class="title">Hello World MDB</span></h3></div></div><p>An MDB
follows a typical EJB contract. It must implement the following two
interfaces:</p><div class="itemizedlist"><ul><li><a name="N1617"></a>
javax.ejb.MessageDrivenBean
</li><li><a name="N161a"></a>
javax.jms.MessageListener
</li></ul></div><p>An MDB must therefore typically contain the following four
methods:</p><pre class="programlisting">
public void setMessageDrivenContext(MessageDrivenContext ctx);
public void ejbCreate();
public void ejbRemove();
public void onMessage(Message message);
</pre><p>The full program listing of a simple Hello World bean could look like
this:</p><pre class="programlisting">
package test.bean;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.ejb.EJBException;
import javax.jms.MessageListener;
import javax.jms.Message;
public class MDB implements MessageDrivenBean, MessageListener{
private MessageDrivenContext ctx = null;
public MDB() {
}
public void setMessageDrivenContext(MessageDrivenContext ctx)
throws EJBException {
this.ctx = ctx;
}
public void ejbCreate() {}
public void ejbRemove() {ctx=null;}
public void onMessage(Message message) {
System.err.println("Bean got message" + message.toString() );
}
}
</pre><p>To deploy this into JBoss we will have to write two deployment descriptors.
One standard ejb-jar and one that is JBoss specific. We will chose to make this bean a
Topic subscriber. Since we do not do anything we could typically chose to use
container managed transaction with NotRequired (although this would in most cases not
be the best thing to do)</p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar>
<message-driven>
<ejb-name>MDB</ejb-name>
<ejb-class>test.bean.MDB</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>DurableTopicBean</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>NotRequired</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
</pre><p>We also need to write a small deployment descriptor that is specific for
JBoss. The full version of this is quite big, and with it it is possible to configure
the MDB container quite a bit. For most users this is not necessary, and the may use
the standard configuration. The most important part of the descriptor is the
specification of the destination. We chose the testTopic since it is always available
in JBoss.</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>MDB</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>test/testTopic</destination-jndi-name>
</message-driven>
</enterprise-beans>
</jboss>
</pre><p>Then you will have to pack these into a jar. Here is one way to do
it:</p><pre class="programlisting">
mkdir dist
mkdir dist/META-INF
mkdir dist/test
cp MDB.class dist/test
cp MDB-jar.xml dist/META-INF/ejb-jar.xml
cp MDB-jboss.xml dist/META-INF/jboss.xml
cd dist
java jar -cvf mdb.jar .
</pre><p>Copy the bean into the deploy directory of JBoss.</p><p>To send stuff to
your bean you need a JMS publisher. This is standard JMS programming, but here is one
way to do it:</p><pre class="programlisting">
import javax.naming.*;
import javax.jms.*;
public class Main {
public static void main(String arg[]) {
try {
// Get access to JNDI
Context context = new InitialContext();
// Lookup the managed connection factory for a topic
TopicConnectionFactory topicFactory =
(TopicConnectionFactory)context.lookup(TOPIC_FACTORY);
// Create a connection to the JMS provider
TopicConnection topicConnection = topicFactory.createTopicConnection();
// Creat a topic session
TopicSession session = topicConnection.createTopicSession(
// No transaction
false,
// Auto ack
Session.AUTO_ACKNOWLEDGE);
// Lookup the destination you want to publish to
Topic topic = (Topic)context.lookup("topic/testTopic");
// Create a publisher
TopicPublisher pub = session.createPublisher(topic);
// Create a message
TextMessage message = session.createTextMessage();
message.setText("Hello World!");
// Publish the message
pub.publish(topic, message);
// Close the stuff
session.close();
topicConnection.close();
catch (Exception e) {
e.printStackTrace();
}
}
}
</pre><p>
You will typically have to include the following jars in your classpath:
jbossmq.client.jar, jms.jar, jnp-client.jar and jta-spec1_0_1.jar.
</p></div><div class="section"><a name="N1655"></a><div class="titlepage"><div><h3
class="title"><a name="N1655"></a><span class="title">MDB as a
listener</span></h3></div></div><p>We will here look at an example that does something
more real. One nice way to use MDB is to have them act/emulate the listener pattern.
The normal way with listeners is to have them register them self on the object
emitting events. This is not possible with MDB, since the bean them self may only do
some work when the receive an even (a message). Set up of MDB as a listener will
therefore have to be done outside of the MDB. This could be as simple as defining a
topic or queue and hardwire into the event generator to publish it's events/messages
to that destination. It's also possible to create a more generic framework for message
driven callback, something I have done with JMS and JMX. But that is for another
document. Lets instead look on the MDB side.</p><p>One way to partition the logic in
EJ!
B is to have one bean that does the real work (contains the logic), this could be a
stateless session bean or an entity bean, and one bean acting as a listener. Lets
write a working, but simplified version of this patter. We start with a very simple
stateless session bean, with just one method: doWork. To make it easy we let it take a
String as its mission. This is straight forward. First we need a home
interface:</p><pre class="programlisting">
package msgbean.interfaces;
import java.rmi.RemoteException;
import javax.ejb.*;
public interface WorkerHome extends EJBHome {
public Worker create() throws RemoteException, CreateException;
} // WorkerHome
</pre><p>We also need a remote interface</p><pre class="programlisting">
package msgbean.interfaces;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface Worker extends EJBObject {
public void doWork(String work) throws RemoteException;
} // Worker
</pre><p>And finally we need the bean class:</p><pre class="programlisting">
package msgbean.server;
import javax.ejb.*;
import java.rmi.RemoteException;
import javax.naming.*;
public class WorkerBean implements SessionBean {
private SessionContext ctx;
public WorkerBean() {
}
public void setSessionContext(javax.ejb.SessionContext ctx) throws
RemoteException { this.ctx = ctx; }
public void unsetSessionContext() throws RemoteException { this.ctx = null; }
public void ejbActivate() throws RemoteException {}
public void ejbPassivate() throws RemoteException {}
public void ejbRemove() throws RemoteException {}
public void ejbCreate() throws CreateException {}
public void doWork(String work) {
System.out.println("WorkerBean doing work: " + work);
}
} // WorkerBean
</pre><p>We will write the deployment descriptor for the bean later, since we will
pack it with the listener.</p><p>The next step is to write the listener bean. Here we
will ad basically one thing: the ability to lookup the Worker bean and invoke it. We
look up the bean through a an JNDI reference defined via ejb-ref. This might be done
in ejbCreate().</p><pre class="programlisting">
Context initCtx = new InitialContext();
workerHome = (WorkerHome)initCtx.lookup("java:comp/env/ejb/worker");
</pre><p>In the onMessage() method we get what we need out of the message. Here we
could have sent an object of some kind, known to the listener. For simplicity we here
chose to send a TextMessage and send the content of the message to the worker.</p><pre
class="programlisting">
Worker worker = workerHome.create();
if (message instanceof TextMessage) {
TextMessage m = (TextMessage)message;
worker.doWork(m.getText());
}
</pre><p>Here is the complete listing of the class:</p><pre class="programlisting">
package msgbean.server;
import javax.ejb.*;
import javax.naming.*;
import javax.jms.*;
import msgbean.interfaces.WorkerHome;
import msgbean.interfaces.Worker;
public class ListenerBean implements MessageDrivenBean, MessageListener{
private MessageDrivenContext ctx = null;
private WorkerHome workerHome = null;
public ListenerBean() {
}
public void setMessageDrivenContext(MessageDrivenContext ctx)
throws EJBException {
this.ctx = ctx;
}
public void ejbCreate() throws CreateException {
try {
Context initCtx = new InitialContext();
workerHome = (WorkerHome)initCtx.lookup("java:comp/env/ejb/worker");
}catch(Exception ex) {
throw new CreateException("Could not get worker: " + ex);
}
}
public void ejbRemove() {ctx=null;}
public void onMessage(Message message) {
try {
Worker worker = workerHome.create();
// Get the message, here we could have an ObjectMessage containg
// an object of a known class. We use Text here for simplicity
if (message instanceof TextMessage) {
TextMessage m = (TextMessage)message;
worker.doWork(m.getText());
}
}catch(Exception ex) {
throw new EJBException("Could not call worker " + ex);
}
}
}
</pre><p>To deploy this into JBoss we need to write two deployment descriptors, one
standard ejb, and one for JBoss. Lets begin with the standard one. For ease of use we
include both beans into one jar. For the Message Driven Bean we have to decide if its
a topic or not, and what kind of transactions it should run under. In this case we
chose a topic and container managed transaction. We also have to specify an ejb-ref so
that the listener can lookup the home of the WorkerBean:</p><pre
class="programlisting">
<message-driven>
<ejb-name>ListenerBean</ejb-name>
<ejb-class>msgbean.server.ListenerBean</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<ejb-ref>
<description>The Workers home</description>
<ejb-ref-name>ejb/worker</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<ejb-link>WorkerBean</ejb-link>
<home>msgbean.interfaces.WorkerHome</home>
<remote>msgbean.interfaces.Worker</remote>
</ejb-ref>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</pre><p>We also have to ad an entry for the Worker bean:</p><pre
class="programlisting">
<session>
<description>Worker bean</description>
<display-name>Worker</display-name>
<ejb-name>WorkerBean</ejb-name>
<home>msgbean.interfaces.WorkerHome</home>
<remote>msgbean.interfaces.Worker</remote>
<ejb-class>msgbean.server.WorkerBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</pre><p>Here is the complete deployment descriptor, including defintions of the
transaction type.</p><pre class="programlisting">
<!DOCTYPE ejb-jar>
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>ListenerBean</ejb-name>
<ejb-class>msgbean.server.ListenerBean</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<ejb-ref>
<description>The Workers home</description>
<ejb-ref-name>ejb/worker</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<ejb-link>WorkerBean</ejb-link>
<home>msgbean.interfaces.WorkerHome</home>
<remote>msgbean.interfaces.Worker</remote>
</ejb-ref>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
<session>
<description>Worker bean</description>
<display-name>Worker</display-name>
<ejb-name>WorkerBean</ejb-name>
<home>msgbean.interfaces.WorkerHome</home>
<remote>msgbean.interfaces.Worker</remote>
<ejb-class>msgbean.server.WorkerBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>ListenerBean</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>WorkerBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
</pre><p>We also need to write a jboss.xml deployment descriptor. This is needed
because it the destination JNDI name must be defined somewhere. Here we can not use on
a default.</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>ListenerBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>topic/testTopic</destination-jndi-name>
</message-driven>
<secure>false</secure>
</enterprise-beans>
</jboss>
</pre><p>We then have to compile the beans. You will have to add several jar-files
to your class-path to have success with this. Among the most important, and special
for MDB, is that you will need ejb2.0 from lib/ext to be able to compile. You also
need to pack them into a jar-file. Do this as described above. Deploy by copying the
jar-file to deploy. You may use the example publisher above to publish messages to the
bean.</p></div><div class="section"><a name="N16b3"></a><div
class="titlepage"><div><h3 class="title"><a name="N16b3"></a><span class="title">The
adapter pattern</span></h3></div></div><p>Another way to use MDB is as an adapter, for
example between different messaging systems. This is rewarding, especially if you have
an J2EE Connector resource adapter for the other system, since you then will get a
very effective, multithreaded and pooled system, without any advanced programing.
Since I have written such a resource adapter for the messaging server XmlBlaste!
r we will here look at one way to adapt between JMS and <a
href="http://www.xmlblaster.org" target="_top"><i>XmlBlaster</i></a>.</p><p>The
adapter uses an MDB to subscribe to a topic. It then republish it to an XmlBlaster
server through the XmlBlasterK2 J2EE Connector adapter.The code is pretty straight
forward. A J2EE Connector resource adapter must be deployed into the JBoss server. It
is then referenced from within the bean the same way you would reference a JDBC
resource. You would look it up this way:</p><pre class="programlisting">
factory = (BlasterConnectionFactory)new InitialContext ().lookup
("java:comp/env/xmlBlaster");
</pre><p>And use it this way:</p><pre class="programlisting">
con = factory.getConnection();
// Construct Blaster Headers
String key ="<key oid=\"" + message.getJMSMessageID() +"\"
contentMime=\"text/xml\"></key>";
String qos = "<qos></qos>";
con.publish( new MessageUnit(key,msg.getBytes(),qos));
</pre><p>The complete bean is pretty straight forward (almost the same code could be
used to write directly to a database for example):</p><pre class="programlisting">
package javaclients.j2ee.k2;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.ejb.EJBException;
import javax.jms.MessageListener;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.JMSException;
import javax.resource.ResourceException;
import org.xmlBlaster.j2ee.k2.client.*;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.engine.helper.MessageUnit;
public class JmsAdapter implements MessageDrivenBean, MessageListener{
private MessageDrivenContext ctx = null;
private BlasterConnectionFactory factory = null;
public JmsAdapter() {
}
public void setMessageDrivenContext(MessageDrivenContext ctx)
throws EJBException {
this.ctx = ctx;
try {
factory = (BlasterConnectionFactory)new InitialContext ().lookup
("java:comp/env/xmlBlaster");
} catch (NamingException ex) {
throw new EJBException ("XmlBlaster not found: "+ex.getMessage ());
}catch(Throwable th) {
System.err.println("Throwable: " +th);
th.printStackTrace();
throw new EJBException("Throwable in setContext: " +th);
}
}
public void ejbCreate() {}
public void ejbRemove() {ctx=null;}
public void onMessage(Message message) {
BlasterConnection con = null;
try {
// Get message to handle
System.err.println("Got message: " + message);
if (message instanceof TextMessage) {
String msg = ((TextMessage)message).getText();
// Get connection
con = factory.getConnection();
// Construct Blaster Headers - howto hanlde key here?
String key ="<key oid=\"" + message.getJMSMessageID() +"\"
contentMime=\"text/xml\"></key>";
String qos = "<qos></qos>";
con.publish( new MessageUnit(key,msg.getBytes(),qos));
} else {
System.err.println("Got message type I cant handle");
}
}catch(ResourceException re) {
System.err.println("Resource ex: " +re);
re.printStackTrace();
} catch(XmlBlasterException be) {
System.err.println("Blaster ex: " +be);
be.printStackTrace();
}catch(JMSException je) {
System.err.println("JMSException ex: " +je);
je.printStackTrace();
}catch(Throwable th) {
System.err.println("Throwable: " +th);
th.printStackTrace();
}finally {
try {
if (con != null)
con.close ();
}
catch (Exception ex) {}
}
}
} // MessageBeanImpl
</pre><p>The deployment descriptors for this bean follows the normal way to write
them, except that you will have to add entries for the resource-ref. Here is the ejb
deployment descriptor:</p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar>
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>JmsAdapter</ejb-name>
<ejb-class>javaclients.j2ee.k2.JmsAdapter</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>xmlBlaster</res-ref-name>
<res-type>org.xmlBlaster.j2ee.k2.client.BlasterConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>JmsAdapter</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
</pre><p>And here is the jboss.xml descriptor:</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<resource-managers>
<resource-manager>
<res-name>xmlBlaster</res-name>
<res-jndi-name>java:/XmlBlasterDS</res-jndi-name>
</resource-manager>
</resource-managers>
<enterprise-beans>
<message-driven>
<ejb-name>JmsAdapter</ejb-name>
<configuration-name>Standrad Message Driven
Bean</configuration-name>
<destination-jndi-name>topic/testTopic</destination-jndi-name>
<resource-ref>
<res-ref-name>xmlBlaster</res-ref-name>
<resource-name>xmlBlaster</resource-name>
</resource-ref>
</message-driven>
<secure>false</secure>
</enterprise-beans>
</jboss>
</pre></div></div><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch07.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch07s02.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch07s07.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch07s07.html
Index: ch07s07.html
===================================================================
<html><head><title>Advanced MDB configuration</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch07.html" rel="up" title="Chapter 7. Working with Message
Driven Beans"><link href="ch07s03.html" rel="previous" title="Writing Message Driven
Bean"><link href="ch08.html" rel="next" title="Chapter 8. Container architecture -
design notes"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch07.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a>!
<a href="ch07s03.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch08.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N16ea"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N16ea"></a><span class="title">Advanced MDB
configuration</span></h2></div></div><p>The MDB implementation for JBoss have been
written such that a user should not have to know a lot about the internals of JBoss. A
part from the feew necessary lines in jboss.xml nothing else than standard knowledge
of Message Driven Beans should suffice.</p><p>Following the design of JBoss, the MDB
implementation is also extremely configurable, if one want to tune or totally change
the default configuration and implementation! Here follows some short notes on howto
configure MDB for JBoss</p><div class="section"><a name="N16f4"></a><div
class="titlepage"><div><h3 class="title"><a nam!
e="N16f4"></a><span class="title">EJB deployment
descriptor</span></h3></div></div><p>All MDB:s are quite configurable, apart from them
being deployed in JBoss. Here are the basic choices that can be made:</p><div
class="itemizedlist"><ul><li><p><a name="N16fd"></a>A bean may be either a
javax.jms.Topic or a javax.jms.Queue bean, which is decided in the stanza
"destination-type", eg.</p><pre class="programlisting">
<message-driven-destination>
<destination-type>javax.jms.Queue</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</pre></li><li><p><a name="N1708"></a>If a bean is a Topic it may be either
NonDurable or Durable, wich is described in the stanza
"subscription-durability".</p><pre class="programlisting">
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>Durable</subscription-durability>
</message-driven-destination>
</pre></li><li><p><a name="N1713"></a>A bean may be have transaction either as bean
managed or container managed, which is described in the stanza "transaction-type",
eg.</p><pre class="programlisting">
<transaction-type>Container</transaction-type>
</pre></li><li><p><a name="N171e"></a>A bean managed bean may have an acknowledge
type of either AUTO_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE. This is currently not
supported in JBoss since the container always are receiving messages under a
transaction. But it is described in the stanza "acknowledge-mode".</p><pre
class="programlisting">
<transaction-type>Bean</transaction-type>
<acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
</pre></li><li><p><a name="N1729"></a>A container managed bean may either specify
transactions as Required or NotSupported, which is done in the container-transaction
transaction part.</p><pre class="programlisting">
</container-transaction>
<container-transaction>
<method>
<ejb-name>DurableTopicBean</ejb-name>
<method-name>*</method-name>
</method>
<!-- May also be NotSupported -->
<trans-attribute>Required</trans-attribute>
</container-transaction>
</pre></li><li><p><a name="N1734"></a>An MDB may also specify a selector which
follows the JMS syntax for a selector. Which is specified in the stanza
"message-selector".</p><pre class="programlisting">
<message-selector>JMSType='activityCompletion'</message-selector>
</pre></li></ul></div><p>In a message-driven stanza one may also have the normal
stuff that may be in a ejb deployment descriptor, such as "ejb-ref" and
"resource-ref".</p></div><div class="section"><a name="N1744"></a><div
class="titlepage"><div><h3 class="title"><a name="N1744"></a><span class="title">JBoss
configuration</span></h3></div></div><p>The meat of the configuration options are in
the jboss.xml deployment descriptor. This may be divided into two part. The necessary
one that configures a particular bean. And the optional one (that will be taken from
standardjboss.xml if not found and which configures the container. We will describe
both here, but the container configuration will be broken into several parts since it
involves stuff outside the jboss.xml file.</p><p>In the bean part one always have to
specify the JNDI for the JMS destination. In JBossMQ this always begins with either
"topic/" or "queue/" followed by the name of the destination.</p><pre class="prog!
ramlisting">
<destination-jndi-name>queue/testObjectMessage</destination-jndi-name>
</pre><p>You also have to tell the beans name and the name of the container
configuration. To use the one in standardjboss.xml you should give the name "Standard
Message Driven Bean".</p><pre class="programlisting">
<message-driven>
<ejb-name>QueueBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>queue/testQueue</destination-jndi-name>
</message-driven>
</pre><p>It is also possible to use a name and a password to log in to JBossMQ.
These may be used by them self. If you have specified a Durable Topic they are however
required. Then one also have to specify a client-id. All these stuff are configurable
in conf/default/jbossmq.xml. Using one of the default in that file we could have a
deployment descriptor looking like this:</p><pre class="programlisting">
<message-driven>
<ejb-name>DurableTopicBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>topic/testDurableTopic</destination-jndi-name>
<mdb-user>john</mdb-user>
<mdb-passwd>needle</mdb-passwd>
<mdb-client-id>DurableSubscriberExample</mdb-client-id>
</message-driven>
</pre><p>The container stuff for MDB are in standardjboss.xml. It is however
possible to override this configuration by including it in the jboss.xml deployment
descriptor. I will first give you the complete look if doing like this, and then go
through the individual entries.</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>ObjectMessageBean</ejb-name>
<configuration-name>My Config</configuration-name>
<destination-jndi-name>queue/testObjectMessage</destination-jndi-name>
</message-driven>
<secure>false</secure>
</enterprise-beans>
<container-configurations>
<container-configuration>
<container-name>My Config</container-name>
<call-logging>false</call-logging>
<container-invoker>org.jboss.ejb.plugins.jms.JMSContainerInvoker</container-invoker>
<container-interceptors>
<interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.SecurityInterceptor</interceptor>
<!-- CMT -->
<interceptor
transaction="Container">org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
<interceptor transaction="Container"
metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
<interceptor
transaction="Container">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor</interceptor>
<!-- BMT -->
<interceptor
transaction="Bean">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor</interceptor>
<interceptor
transaction="Bean">org.jboss.ejb.plugins.MessageDrivenTxInterceptorBMT</interceptor>
<interceptor transaction="Bean"
metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
</container-interceptors>
<instance-pool>org.jboss.ejb.plugins.MessageDrivenInstancePool</instance-pool>
<instance-cache></instance-cache>
<persistence-manager></persistence-manager>
<transaction-manager>org.jboss.tm.TxManager</transaction-manager>
<container-invoker-conf>
<JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
<ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
<MaximumSize>15</MaximumSize>
<MaxMessages>1</MaxMessages>
<Optimized>True</Optimized>
</container-invoker-conf>
<container-pool-conf>
<MaximumSize>100</MaximumSize>
<MinimumSize>10</MinimumSize>
</container-pool-conf>
</container-configuration>
</container-configurations>
<resource-managers />
</container-configurations>
</pre><p>Here we go through some ways to configure the MDB container</p><div
class="section"><a name="N176e"></a><div class="titlepage"><div><h4 class="title"><a
name="N176e"></a><span class="title">Container invoker</span></h4></div></div><p>The
container invoker is what sends messages into the container system. It is this that is
responsible for handling everything that has to do with JMS. The rest of the MDB
container parts are basically agnostic to what kind of message system that the
container invoker uses. It is therefore possible to write a new container invoker for
other types of message system. Currently there are one limitation to this. The bean
class still has to implement the MessageListener interface and the invoker therefore
have to adopt to this interface. This will be made pluggable in a later release of
MDB. </p></div><div class="section"><a name="N1776"></a><div
class="titlepage"><div><h4 class="title"><a name="N1776"></a><span
class="title">Container int!
erceptor</span></h4></div></div><p>The container interceptor are an integral part of
the container system and each does something particular to fulfill the EJB container
contract. All of them are pluggable, meaning that it is possible to write new
implementations of the and plug them in for a bean with a particular need. This should
be considered a very advanced task.</p></div><div class="section"><a
name="N177e"></a><div class="titlepage"><div><h4 class="title"><a
name="N177e"></a><span class="title">Container invoker
configuration</span></h4></div></div><p>This is probably the most interesting part to
understand. Lets look at it in smaller pieces. First it defines a
"JMSProviderAdapterJNDI":</p><pre class="programlisting">
<JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
</pre><p>There should be a JNDI name to a JMX bean where one might lookup a provider
adapter class. This class is then used by the invoker to find the names of the
connection factories, all IntitialContext lookups are done through this class, to make
it possible to get access to a JMS provider outside of JBoss.</p><p>The name is by
default bound to the JbossMQProvider in jboss.jcml</p><pre class="programlisting">
<mbean code="org.jboss.jms.jndi.JMSProviderLoader"
name=":service=JMSProviderLoader,name=JBossMQProvider">
<attribute name="ProviderName">DefaultJMSProvider</attribute>
<attribute
name="ProviderAdapterClass">org.jboss.jms.jndi.JBossMQProvider</attribute>
</mbean>
</pre><p>It is however possible to add more JMSProviders to the jboss.jcml and use
them in the container configuration. On possible reason to do this is if one want to
listen to a queue or topic in another JBoss server. The one could define another
provider and configure its context. Say we have a JBoss server on a machine
remote.com. We might then ad this to jboss.jcml:</p><pre class="programlisting">
<mbean code="org.jboss.jms.jndi.JMSProviderLoader"
name=":service=JMSProviderLoader,name=RemoteJMSProvider">
<attribute name="ProviderName">RemoteJMSProvider</attribute>
<attribute
name="ProviderAdapterClass">org.jboss.jms.jndi.JBossMQProvider</attribute>
<attribute name="ProviderUrl">remote.com:1099</attribute>
</mbean>
</pre><p>Note how we added a "ProviderUrl" attribute. In jboss.xml we would write
this in the JMSProviderAdapterJNDI element:</p><pre class="programlisting">
<JMSProviderAdapterJNDI>RemoteJMSProvider</JMSProviderAdapterJNDI>
</pre><p>OBSERVE. I have this working for non transacted connections. It has not
bean fully verified to work with the current JBossMQProvider.</p><p>Another way to use
this configuration option is to integrate another JMS provider into JBoss. This was
actually how MDB was first implemented in JBoss through the OpenJMS implementation. To
do this one have to implement the interface org.jboss.jms.jndi.JMSProviderAdapter. Be
aware though that if the JMS provider does not support the full JMS ASF (chapter 8 in
the JMS spec) you will have to write a full implementation of both the ProvuderAdapter
and the ServerSession stuff.</p><p>Next we have the "ServerSessionPoolFactoryJNDI"
element</p><pre class="programlisting">
<ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
</pre><p>This also points to a class loaded through jboss.jcml. It is the entry
point to the ServerSessionPool. If one needs to write a provider specific pool or do
some customization of the existing one, it would be possible to load that for a
particular bean. The existing one is defined this way in jboss.jcml:</p><pre
class="programlisting">
<mbean code="org.jboss.jms.asf.ServerSessionPoolLoader"
name=":service=ServerSessionPoolMBean,name=StdJMSPool">
<attribute name="PoolName">StdJMSPool</attribute>
<attribute
name="PoolFactoryClass">org.jboss.jms.asf.StdServerSessionPoolFactory</attribute>
</mbean>
</pre><p>The first implementation of MDB for JBoss was based on another
ServerSessionPoolFactory, specially written for OpenJMS. This is currently not
verified to work. What do work is the pluggability of ServerSessionPool
factories.</p><p>The last two entries looks like this:</p><pre class="programlisting">
<MaximumSize>15</MaximumSize>
<MaxMessages>1</MaxMessages>
</pre><p>The first of these - "MaximumSize" - defines how large the pool will be,
i.e how many session it will have ready to serve incoming messages. The second one is
used to configure the maximum number of messages a session is allowed to handle at
once. I have never tweaked that one, and do not know if JBossMQ actually support that
option. It might enhance performance if used.</p></div></div></div><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch07.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch07s03.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch08.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td><!
/tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch08s04.html
Index: ch08s04.html
===================================================================
<html><head><title>Client Objects</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch08.html"
rel="up" title="Chapter 8. Container architecture - design notes"><link
href="ch08.html" rel="previous" title="Chapter 8. Container architecture - design
notes"><link href="ch08s17.html" rel="next" title="JMX - foundation of JBoss
infrastructure"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch08.html"><img border="0" height="65"
src="images/toc.gif" width="60"!
></a><a href="ch08.html"><img border="0" height="65" src="images/prev.gif"
>width="76"></a><a href="ch08s17.html"><img border="0" height="65"
>src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
>class="section"><a name="N1810"></a><div class="titlepage"><div><h2 class="title"
>style="clear: all"><a name="N1810"></a><span class="title">Client
>Objects</span></h2></div></div><div class="section"><a name="N1815"></a><div
>class="titlepage"><div><h3 class="title"><a name="N1815"></a><span
>class="title">EJBObject and EJBHome</span></h3></div></div><p>As previously discussed
>in many EJB resources, an
<tt>EJBObject</tt> is an
object that represents a client's view of the Enterprise Java Bean. It is
generated by the container provider. A client never references an ejb bean
instance directly, but rather references the
<tt>EJBObject</tt> which implements the
bean remote interface. The <tt>EJBHome</tt> object is very
similar to <tt>EJBObject</tt> in
the sense that it is also generated by the container. Also, it implements
the bean's home interface, which is defined by the bean provider. Rather
than implementing business logic, however, it provides life-cycle
operations on the enteprise beans.</p></div><div class="section"><a
name="N182a"></a><div class="titlepage"><div><h3 class="title"><a
name="N182a"></a><span class="title">Virtual EJBObject - the big
picture</span></h3></div></div><p><tt>EJBObject</tt> is more of an abstract idea than
a
physical
implementation. So far, we know that
clients are given a remote
handle to EJBObjects, but how is the
EJBObject physically
implemented on the server side? Well,
it is not implemented at all !</p><p>Most EJB servers that are available today are
literally implementing
the EJB
specification. That is, for each
logical EJBObject there is one physical EJBObject that
receives requests.</p><p>This approach is
very naive and may easily lead to scalability
problems if there are many EJBObjects
alive at any one time.
In addition, this gives a rather
complex structure to the EJB container.</p><p>For example, one can have a finder
method that returns an enumeration
of
1.000.000 EJBObjects. Does this mean
that we now have to create 1.000.000
server EJBObject counterparts? This
would be a serious resource drain ! </p><p>In JBoss there is only one physical
EJBObject that serves all logical
EJBObjects. That physical EJBObject is
Container. For each EJB type there is
one container object, which plays the
role of EJBObject by wrapping all instances
of a particular EJB type.</p><p>JBoss'
approach is superior in many aspects, and it simplifies the
container architecture immensely.
Clients, however, never notice this. They have
something that looks and feels like a
real server EJBObject, but this is merely an
illusion. Behind the scenes there is
only one object (Container) handling all method
invocations. The final result is full
EJBObject conformity.</p></div><div class="section"><a name="N1844"></a><div
class="titlepage"><div><h3 class="title"><a name="N1844"></a><span class="title">Two
flavours of implementation</span></h3></div></div><p>JBoss's client objects
(<tt>EJBObject</tt> and
<tt>EJBHome</tt>) are constructed as
dynamic proxies. But before we investigate dynamic proxies, it is
important to notice that there are two different implementations of
dynamic proxies, that are in fact almost totally the same. The package
jrmp13.interfaces* contains default implementation of
<tt>EJBObject</tt>
proxies that utilizes the core java.lang.reflect package of j2se 1.3.
In contrast, the package jrmp12.interfaces* contains
<tt>EJBObjects</tt> proxies
that are using JBoss's home brewed proxy framework of j2se 1.2.
This package is primarly intended to serve for "history proofing"
of JBoss (i.e., enabling JBoss to be used with j2se 1.2 version).</p><p>*Full
package names are:</p><p>
<tt>org.jboss.ejb.plugins.jrmp13.interfaces</tt>
</p><p>
<tt>org.jboss.ejb.plugins.jrmp12.interfaces</tt>
</p></div><div class="section"><a name="N1868"></a><div
class="titlepage"><div><h3 class="title"><a name="N1868"></a><span
class="title">Relation to ContainerInvoker</span></h3></div></div><p> The
ContainerInvoker component, which we will focus on in detail
later,
is responsible for maintaining <tt>EJBObject</tt> and
<tt>EJBHome</tt>. A closer look
at <tt>ContainerInvoker</tt> reveals an interface for
obtaining these objects.
Dynamic proxies of <tt>EJBObject</tt> and
<tt>EJBHome</tt> are created in
<tt>JRMPContainerInvoker</tt>,
a default implementation of the <tt>ContainerInvoker</tt>
interface.</p></div><div class="section"><a name="N1886"></a><div
class="titlepage"><div><h3 class="title"><a name="N1886"></a><span
class="title">Dynamic proxies</span></h3></div></div><p>A dynamic proxy is an object
that implements a list of interfaces
specified at runtime when the object is created. A proxy interface
is an interface that is implemented by a proxy class. Each proxy
class instance has an associated invocation handler object, which
implements the interface InvocationHandler. </p></div><div class="section"><a
name="N188f"></a><div class="titlepage"><div><h3 class="title"><a
name="N188f"></a><span class="title">EJBObject as a dynamic
proxy</span></h3></div></div><p>EJBObject and EJHome object are created by following
classical
proxy instantiation technique:</p><p>
<pre
class="programlisting">Proxy.newProxyInstance(bean.getRemoteClass().getClassLoader(),
new Class[] { bean.getRemoteClass() },
new EntityProxy());</pre>*</p><p>*Not exactly as is,
simplified to a certain degree</p><div class="section"><a name="N18a2"></a><div
class="titlepage"><div><h4 class="title"><a name="N18a2"></a><span class="title">What
do we need to create a client proxy ?</span></h4></div></div><p>In this particular
case, given the classloader that loaded
the entity bean's remote interface, its Class class, and the invocation
handler (<tt>EntityProxy</tt>), we are able to create a new
Proxy instance
which implements the bean's remote interface. Since
<tt>java.lang.reflect.Proxy</tt>
class is serializible, it can be sent to the remote client across
the network.</p></div><div class="section"><a name="N18b1"></a><div
class="titlepage"><div><h4 class="title"><a name="N18b1"></a><span
class="title">Relation between proxy and invocation
handler</span></h4></div></div><p>The remote client, having a dynamic proxy class that
implements
the bean's remote interface, dispatches all method invocation on that
interface to the instance of the underlying invocation handler.</p></div><div
class="section"><a name="N18ba"></a><div class="titlepage"><div><h4 class="title"><a
name="N18ba"></a><span class="title">EJB proxy
types</span></h4></div></div><p>Depending on the type of the EJB bean on the server,
there are four
proxy classes: <tt>EntityProxy</tt>,
<tt>HomeProxy</tt>,<tt>StatelessSessionProxy</tt>
and <tt>StatefulSessionProxy</tt>.</p></div><p>All four proxies implement the
<tt>java.lang.reflect.InvocationHandler</tt>
interface and also subclass <tt>GenericProxy</tt>, which in
turn contains a
stub of the <tt>ContainerRemote</tt> interface implementor
from the server side.
That implementor is <tt>JRMPContainerInvoker</tt>.</p></div><div
class="section"><a name="N18df"></a><div class="titlepage"><div><h3 class="title"><a
name="N18df"></a><span class="title">Invoke method</span></h3></div></div><p>Each of
the proxy classes implements the only method defined
in the <tt>InvocationHandler</tt> interface: invoke.
The invoke method intercepts all calls to the EJB remote
interface (client side) and depending on the particular type of EJB
method, does one of the following:</p></div><p>- handles the method locally in
the <tt>Proxy</tt> class
- passes the method call accross the wire to the remote EJB container
- invokes the method in the local EJB container</p><div class="section"><a
name="N18f1"></a><div class="titlepage"><div><h3 class="title"><a
name="N18f1"></a><span class="title">Advantages</span></h3></div></div><p>This design
of client objects gives maximum flexibility in the
following sense: all calls that can be handled by clients themselves
are handled locally, preventing the roundtrip across the wire and
saving the container from unneccessary loading. Calls coming from other
EJBs, but local to the JVM, are also optimized since they bypass the network
transport layer and call the specific underlying container directly.
Finally, only calls that absolutely must leave the local VM are passed
across the wire.</p></div><div class="section"><a name="N18fa"></a><div
class="titlepage"><div><h3 class="title"><a name="N18fa"></a><span
class="title">Closing the first half of the circle</span></h3></div></div><p>Let's
trace the remote call on busines method B of an entity
bean.</p><p>First, the method call goes on the proxy interface where it is
dispatched to its invocation handler, which in this case is EntityProxy.
Entity proxy converts the call into a
<tt>RemoteMethodInvocation</tt>object and stuffs it
into a <tt>MarshalledObject</tt>. Using a stub of the
<tt>JRMPContainerInvoker</tt>, the remote
call is sent over the "wire" to the server's
<tt>JRMPContainerInvoker</tt> object
where it is unpacked from <tt>MarshalledObject</tt> and handed
off to the container.</p><p>*Note that, since the jdk1.2 release, skeletons are
avoided on the
server side. Consult RMI specification for more info.</p></div></div><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch08.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch08.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch08s17.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch08s17.html
Index: ch08s17.html
===================================================================
<html><head><title>JMX - foundation of JBoss infrastructure</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch08.html" rel="up" title="Chapter 8. Container
architecture - design notes"><link href="ch08s04.html" rel="previous" title="Client
Objects"><link href="ch08s21.html" rel="next" title="ContainerInvoker - Container
entry point"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch08.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a>!
<a href="ch08s04.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch08s21.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1919"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1919"></a><span class="title">JMX - foundation of JBoss
infrastructure</span></h2></div></div><div class="section"><a name="N191e"></a><div
class="titlepage"><div><h3 class="title"><a name="N191e"></a><span
class="title">Introduction</span></h3></div></div><p>JMX technology represents a
standard coherent framework for
instrumentation and management of Java
technology-based resources. JMX defines a management architecture, APIs, and
management services all
under a single umbrella specification. On top of this specification promises
hooks into existing management
systems.</p></div><div class="section"><a name="N1927"></a><div
class="titlepage"><div><h3 class="title"><a name="N1927"></a><span class="title">JMX
core components</span></h3></div></div><p>MBeanServer is core JMX abstraction, a
component which provides
services for manipulating MBeans. All
management operations performed on MBeans are done through MBeanServer
interface. MBeanServer
contains the necessary methods for the creation, registration, and deletion of
MBeans as well as the access
methods for registered MBeans. This is the core component of the JMX
infrastructure.</p><p>MBean is a "regular" Java component volunteering to be
instrumented.
Every MBean component which is
added to the MBeanServer becomes manageable: its attributes and operations
become remotely accessible
through the connectors/adaptors connected to that MBeanServer. A Java object
cannot be registered in
the MBeanServer unless it is a JMX compliant MBean.</p></div><div class="section"><a
name="N1933"></a><div class="titlepage"><div><h3 class="title"><a
name="N1933"></a><span class="title">JBoss and
JMX</span></h3></div></div><p>MBeanServer in Jboss architecture plays a role of
microkernel
aggregator component. All other managable
MBeans components are plugged into MBeanServer. The kernel in that sense is
only an aggregator, and not
a source of actual functionality. The functionality is provided by MBeans and
infact all major JBoss
components, are managable MBeans interconnected through MBeanServer. The
managibility is provied by
MBeanServer which instuments registered MBeans.</p><p>The modular architecture of
JBoss , provided by JMX foundation
moves all dependency checking from
compile time to run-time enviroment. The rigourous runtime depedencies
check mechanism, in the form
of JBoss' DependencyManager component, enforces dependencies between different
resources and services.</p><p>It is important to notice that "management
dependencies" are
something independent of the managed
blocks but dependent on the context of a particular deployment/environment. In
any case, the dependencies
are runtime oriented and the external management of them (JMX) is the way
to go.</p></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch08.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch08s04.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch08s21.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch08s21.html
Index: ch08s21.html
===================================================================
<html><head><title>ContainerInvoker - Container entry point</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch08.html" rel="up" title="Chapter 8. Container
architecture - design notes"><link href="ch08s17.html" rel="previous" title="JMX -
foundation of JBoss infrastructure"><link href="ch08s31.html" rel="next"
title="Container"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch08.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a hr!
ef="ch08s17.html"><img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch08s31.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N1943"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1943"></a><span class="title">ContainerInvoker - Container entry
point</span></h2></div></div><div class="section"><a name="N1948"></a><div
class="titlepage"><div><h3 class="title"><a name="N1948"></a><span
class="title">Introduction</span></h3></div></div><p>Certainly one of the most
important parts of a distributed system
is its RPC interface, as well as techniques used in passing that RPC
call between different parts of the system.</p><p>The component that plays the
role of the container entry point, a
"call
router", to insides of the container is the
<tt>ContainerInvoker</tt>. By closely
looking at this entry point to the JBoss container, one would understand
the semantics of calls made from clients, client object structure, the
passing
of client calls over the network layer (a.k.a "wire") and unpacking
them in a local VM. Similar semantics are employed in returning the result
of the call and how it is handled on the client side. Also, great attention
has to be dedicated to methods employed in bypassing the network layer if
these
calls are made from clients local to the container, i.e intra-VM.</p></div><div
class="section"><a name="N1957"></a><div class="titlepage"><div><h3 class="title"><a
name="N1957"></a><span class="title">ContainerInvoker in
focus</span></h3></div></div><div class="section"><a name="N195c"></a><div
class="titlepage"><div><h4 class="title"><a name="N195c"></a><span class="title">How
are calls passed into a container?</span></h4></div></div><p>Container invoker
utilizes RMI exporting* to make itself
available to remote clients. By implementing
<tt>ContainerRemote</tt> interface,
which in turn extends the familiar <tt>java.rmi.Remote</tt>
interface,
ContainerInvoker acts as an RMI server object and as such is able to
accept calls that come from both remote clients (other JVMs) and
from other beans "living" in containers of the same EJB
application (within the same JVM).</p></div><div class="section"><a
name="N196b"></a><div class="titlepage"><div><h4 class="title"><a
name="N196b"></a><span class="title">ContainerRemote interface - two flavours of
invoke methods</span></h4></div></div><p>Before going further into the details, let's
look closer into
<tt>ContainerRemote</tt> interface. It has two methods,
<tt>invoke</tt> and <tt>invokeHome</tt>, each of
which
has two flavors:</p><p>
<pre class="programlisting">public
MarshalledObject invoke(MarshalledObject mi)
throws Exception;</pre>
</p><p>
<pre class="programlisting">public Object
invoke(Object id, Method m, Object[] args,
Transaction tx,
Principal identity,
Object credential )
throws Exception;</pre>
</p><p>The first accepts only one parameter
(<tt>MarshalledObject</tt>), while
second accepts "regular" java objects. Why is this distinction
between the two sets important? </p><p>The distinction exists exactly for the
reason that it enables the
container to accept both remote and local client calls. But it is
important
to notice that not only does this design approach enable two different
call methodologies, it optimizes them at the same time.</p></div><div
class="section"><a name="N199a"></a><div class="titlepage"><div><h4 class="title"><a
name="N199a"></a><span class="title">Remote call unpacking
stage</span></h4></div></div><p>Remote calls are unpacked from
<tt>MarshalledObject</tt>.
<tt>MarshalledObject</tt>
contains a byte stream with serialized representation
of an object given to its constructor. In our case, this object is
<tt>RemoteMethodInvocation</tt>.
The <tt>RemoteMethodInvocation</tt> instance,
created by a remote client proxy, describes all needed attributes
of an EJB method call. Some of these attributes, as you
may have guessed by now, are the ID of the object, a method to
invoke, security credentials, principal of the caller(identity),
and a transactional context of the call.</p></div><div class="section"><a
name="N19af"></a><div class="titlepage"><div><h4 class="title"><a
name="N19af"></a><span class="title">MethodInvocation</span></h4></div></div><p>Upon
receving <tt>MarshalledOjbect</tt> from client
proxy, <tt>ContainerInvoker</tt>
recreates a copy of the original
<tt>RemoteMethodInvocation</tt>
object, by deserializing it from the contained byte stream in
<tt>MarshalledObject</tt>.
<tt>RemoteMethoInvocation</tt> is then converted to
<tt>MethodInvocation</tt> and handed off to the
container.</p></div><div class="section"><a name="N19ca"></a><div
class="titlepage"><div><h4 class="title"><a name="N19ca"></a><span class="title">Bean
to Bean calls</span></h4></div></div><p>Local calls coming from clients in the same
VM, usually a
"bean/bean" method call, are directly handed off to the container.
This bypasses the network layer, and serialization/deserialization
stage of the call that remote method calls have to go through.</p></div><div
class="section"><a name="N19d3"></a><div class="titlepage"><div><h4 class="title"><a
name="N19d3"></a><span class="title">Other ContainerInvoker
duties</span></h4></div></div><p>Before forwarding a call to the container,
<tt>ContainerInvoker</tt> also
resets the call's thread classloader with the specified container
classloader, propagates transaction, and security context. </p><p>Another
important role played by
<tt>ContainerInvoker</tt> is that it
provides implementation of <tt>EJBObject</tt> and
<tt>EJBHome</tt> parts of container.
As mentioned before, <tt>ContainerInvoker</tt> creates
<tt>EJBObject</tt> and <tt>EJBHome</tt>
in the form of dynamic proxies.</p><p>For example, an <tt>EntityBean</tt> finder
may result
in a set of primary
keys whose EJB-objects should be returned to the client. The
<tt>ContainerInvoker</tt> is then responsible for creating
<tt>EJBObject</tt>
instances that can be used by the client, as specified in the
EJB 1.1 specification. The client must then be able to remotely
access the container and actual bean instances through
these <tt>EJBObjects</tt>.</p></div><div class="section"><a name="N1a03"></a><div
class="titlepage"><div><h4 class="title"><a name="N1a03"></a><span class="title">Why
ContainerInvoker if we have container?</span></h4></div></div><p>One may wonder why
there is such a big distinction between
container invoker and the container.
<tt>ContainerInvoker</tt> also
uses the naming tree. Why should the container invoker know
anything about the naming tree? You end up having the container
invoker taking care of all the important registrations...</p><p>Wasn't the
container responsible for all this crucial work?</p><p>No, this architectural approach
was intentional in JBoss. Since
different distribution protocols use different naming systems
(IIOP would use the CORBA naming system), the only part of the
container that knows what naming system to use is the container invoker.
Now, if we want to add another/different distribution protocol to JBoss, we
can
simply implement it in the container invoker; everything else stays
untouched.
ContainerInvoker is free to choose which distribution protocol to use
to access the container. Valid options would be JRMP, IIOP, or SOAP. The
default
plugin uses the standard RMI protocol JRMP to allow client access to
the container. </p><p>*Exporting - making object available to accept incoming
calls by
listening on specified TCP port</p></div></div></div><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch08.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch08s17.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch08s31.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch08s31.html
Index: ch08s31.html
===================================================================
<html><head><title>Container</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch08.html"
rel="up" title="Chapter 8. Container architecture - design notes"><link
href="ch08s21.html" rel="previous" title="ContainerInvoker - Container entry
point"><link href="ch08s63.html" rel="next" title=" Transaction support "></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch08.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch08s21.html"><!
img border="0" height="65" src="images/prev.gif" width="76"></a><a
href="ch08s63.html"><img border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N1a1a"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1a1a"></a><span class="title">Container</span></h2></div></div><div
class="section"><a name="N1a1f"></a><div class="titlepage"><div><h3 class="title"><a
name="N1a1f"></a><span class="title">Concepts</span></h3></div></div><p>A
<tt>Container</tt> is the component that runs a
particular EJB. When an
EJB-jar is deployed, typically a number of containers are created
which are connected internally into Applications. The
Application lets Containers handle references between beans, for
example for JNDI EJB-references as specified in the EJB 1.1
specification.</p><p>But let's not dive into the nuts and bolts of the container
component without first looking into the container's creation process.
The component responsible for creating the container is the container
factory.</p></div><div class="section"><a name="N1a2e"></a><div
class="titlepage"><div><h3 class="title"><a name="N1a2e"></a><span
class="title">Container Factory</span></h3></div></div><p>The container factory, as
its name implies, simply creates containers.
Simple, right? Wrong !!! Lets investigate this process in more
detail.</p><div class="section"><a name="N1a36"></a><div class="titlepage"><div><h4
class="title"><a name="N1a36"></a><span
class="title">Introduction</span></h4></div></div><p>Given an EJB-jar that is ready
for deployment, the container factory
will create and initialize the necessary EJB-containers - one for each
deployed EJB. The factory contains two central methods:
<tt>deploy</tt> and
<tt>undeploy</tt>. The <tt>deploy</tt> method takes
a URL, which either points to an
EJB-jar, or to a directory whose structure is the same as a valid
EJB-jar(convenient for development purposes). Once a deployment has
been made, it can be undeployed by calling <tt>undeploy</tt> on
the same URL.
A call to <tt>deploy</tt> with an already deployed URL will
cause an <tt>undeploy</tt>
followed by deployment of the URL, i.e. a re-deploy. JBoss has support
for full re-deployment of both implementation and interface classes,
and will reload any changed classes. This will allow you to develop
and update EJBs without ever stopping a running server.</p></div><div
class="section"><a name="N1a5d"></a><div class="titlepage"><div><h4 class="title"><a
name="N1a5d"></a><span class="title">What the container factory needs to
know</span></h4></div></div><p>In order to properly deploy the bean into a container,
the container
factory
has to have "intimate" knowledge about the bean being deployed to the
finest level of granularity. This is where the notion of bean metadata
comes into the picture. The metadata package, which in turn utilizes a
standard DOM document model, creates an "object-tree" in-memory replica of
ejb-jar.xml file. Having an object tree structure of bean metadata,
the container factory can easily access it and then succesfully deploy
a bean into a container. Bean metadata is actually a super set of
other finer-grained metadata components like method, ejb-ref, environment
entries, resource entries metadata.</p></div><div class="section"><a
name="N1a66"></a><div class="titlepage"><div><h4 class="title"><a
name="N1a66"></a><span class="title">Container
configuration</span></h4></div></div><p>Besides standard EJB 1.1 ejb-jar.xml file that
contains metadata
about beans being deployed, JBoss defines its own container
configuration file - standardjboss.xml. Standardjboss.xml specifies
default container configurations for each EJB bean type. Each configuration
specifies which components to use, such as container invoker type, instance
caches/pools and their sizes, persistence manager etc.</p></div><div
class="section"><a name="N1a6f"></a><div class="titlepage"><div><h4 class="title"><a
name="N1a6f"></a><span class="title">Configuration
flexibility</span></h4></div></div><p>A quick look at standardjboss.xml gives us a
hint about all default
container configurations. EJB adminstrator/developer is also given an
opportunity to override these default container settings in jboss.xml
file. The advantage of this approach is that it gives great flexibility
in the configuration of containers. As we have seen, all container
configuration attributes have been externalized and as such are easily
modifiable. Knowledgeable developers can even implement specialized
container components such as instance pools or caches and easily integrate
them with the container.</p></div><div class="section"><a name="N1a78"></a><div
class="titlepage"><div><h4 class="title"><a name="N1a78"></a><span class="title">Bean
Verifier</span></h4></div></div><p>As an option, Jboss also attempts to verify EJB 1.1
specification
compliance of
the beans. For more details, the curious reader should look into the
verifier
package.</p></div><div class="section"><a name="N1a81"></a><div
class="titlepage"><div><h4 class="title"><a name="N1a81"></a><span
class="title">Deployment semantics</span></h4></div></div><p>Having a bean and
container metadata, the container factory iterates
over
all beans it has to deploy and:</p><p>- creates specific container subclass
- sets all container attributes from container metadata*
- adds all container interceptors*
- adds container to application
- after all beans have been succesfully deployed, starts application</p><p>*Note
the difference between container interceptors in specific
container
subclasses</p><p>*The metadata specifies the type of TM (transaction manager)
to use but, in fact, we need look it up from the naming tree. In fact,
there is (and should be) only
one TM per VM since transactions have to be coordinated across containers.
Also note that <tt>EJBSecurityManager</tt> and
<tt>RealmMapping</tt> are shared between
containers (for more details refer to the security section of this
paper).</p></div></div><div class="section"><a name="N1a9a"></a><div
class="titlepage"><div><h3 class="title"><a name="N1a9a"></a><span
class="title">Automatic deployment</span></h3></div></div><div class="section"><a
name="N1a9f"></a><div class="titlepage"><div><h4 class="title"><a
name="N1a9f"></a><span class="title">Introduction</span></h4></div></div><p>The
container factory can be invoked manually from a management
console or automatically by using the <tt>AutoDeployer</tt>.
AutoDeployer
(which is an MBean) is a component that periodically checks EJB-jars
for modification timestamps. If an update has been made the EJB-jar
is re-deployed. When the server is started and an EJB-jar is found
it will be deployed automatically.</p></div><p>The deployer is given a URL to
watch. The URL can point to one of
three things:</p><p>- EJB-jar</p><p>- directory whose contents are structured like
an EJB-jar. Timestamp
checks will be done on the META-INF/ejb-jar.xml file.</p><p>- directory
into which EJB-jar files or directories containing
valid EJB-jar contents is placed. This may only be a file URL,
since it is not possible to do file listing checks on HTTP
URL's.</p><div class="section"><a name="N1ab7"></a><div class="titlepage"><div><h4
class="title"><a name="N1ab7"></a><span class="title">Advantage of automatic
deployment</span></h4></div></div><p>The last variant is very powerful. The default
configuration of
JBoss starts an <tt>AutoDeployer</tt> that checks the /deploy
directory. Here
you can place any EJB-jars that you want to be deployed on startup.
If you want to add deployments at runtime you simply drop them in
that directory.</p></div></div><div class="section"><a name="N1ac4"></a><div
class="titlepage"><div><h3 class="title"><a name="N1ac4"></a><span
class="title">EnterpriseContext</span></h3></div></div><p>
<tt>EnterpriseContext</tt> and its subclasses,
<tt>StatefulSessionEnterpriseContext</tt>,
<tt>StatelessSessionEntepriseContext</tt>,
and <tt>EntityEntepriseContext</tt> implement
<tt>EJBContext</tt> part of EJB 1.1 spec.</p><div class="section"><a
name="N1adb"></a><div class="titlepage"><div><h4 class="title"><a
name="N1adb"></a><span class="title">Client view</span></h4></div></div><p>From a
bean's perspective <tt>EJBContext</tt> is a
gateway to container;
it represents a way for a bean to perform callbacks to the
container.</p></div><div class="section"><a name="N1ae7"></a><div
class="titlepage"><div><h4 class="title"><a name="N1ae7"></a><span
class="title">Container view</span></h4></div></div><p>From a container's perspective,
the container uses
<tt>EntepriseContext</tt> to
associate a bean instance with all information that the container
needs about
that instance to properly manage it. This infomation includes
a callback reference to the container hosting the instance,
synchronization associated with
that instance, instance's transaction,
<tt>Principal</tt> and object Id.
Simply put, <tt>EntepriseContext</tt> associates a
bean's instance with its metadata.
It is the container's responsibilty to manage bean's context, which
changes over the lifecycle of a bean.</p></div></div><div class="section"><a
name="N1afa"></a><div class="titlepage"><div><h3 class="title"><a
name="N1afa"></a><span class="title">Container's nuts and
bolts</span></h3></div></div><div class="section"><a name="N1aff"></a><div
class="titlepage"><div><h4 class="title"><a name="N1aff"></a><span
class="title">Container class itself</span></h4></div></div><p>JBoss container is
mainly a framework into which one can plug in
implementations of various parts. The
<tt>Container</tt> itself does not perform
any significant work other than connecting the various plugins.
There are three subclasses of <tt>Container</tt>, each
one implementing a
particular bean-type:</p><p>
<tt>EntityContainer</tt> handles EntityBeans,
<tt>StatelessSessionContainer</tt> handles Stateless
SessionBeans, and
<tt>StatefulSessionContainer</tt> handles Stateful
SessionBeans.</p><p>They are very similar, but are different in some respects. The
stateless session container does not have an instance cache (since
no instances have identity), and the entity container has an
<tt>EntityPersistenceManager</tt> to help it with
persisting entity beans in
various storages.</p></div><div class="section"><a name="N1b20"></a><div
class="titlepage"><div><h4 class="title"><a name="N1b20"></a><span
class="title">Container plugin framework</span></h4></div></div><p>The plugins can be
added by implementing various interfaces, and
by selecting them in the JBoss-specific deployment XML file (which
can be edited in a GUI-tool). The interfaces are:</p><p>
<tt>InstanceCache</tt>,
<tt>InstancePool</tt>,
<tt>Interceptor</tt>,
<tt>EntityPersistenceManager</tt>,
<tt>StatefulSessionPersistenceManager</tt>
</p><p>
<tt>InstancePool</tt> and
<tt>Interceptors</tt> are used in all three different types of
containers. <tt>InstanceCache</tt> is only used for
entity beans and stateful
session beans. <tt>EntityPersistenceManager</tt> is
only used for entity beans.
<tt>StatefulSessionPersistenceManager</tt> is only used
for stateful session
beans.</p><p>These interfaces are described in detail below. All plugins
have
a callback to the container through which they can access all other
plugins or configuration information. The container's main
responsibility
is therefore to manage the plugins, and to see to it that the plugins
have all
the information they need in order to implement some
functionality.</p><div class="section"><a name="N1b4f"></a><div
class="titlepage"><div><h5 class="title"><a name="N1b4f"></a><span
class="title">Interceptor</span></h5></div></div><div class="section"><a
name="N1b54"></a><div class="titlepage"><div><h6 class="title"><a
name="N1b54"></a><span class="title">Creation and
ordering</span></h6></div></div><p>All interceptors are created and added to the
interceptor
linked-list by
the container factory. The last interceptor is not added by the
container
factory but rather by the container itself.</p></div><p>The order of the
interceptor in the chain is not accidental. The
idea
behind ordering is that intereceptors that are not tied to a particular
EnterpriseContext instance are positioned before interceptors that
interact with caches and pools.</p></div><div class="section"><a
name="N1b61"></a><div class="titlepage"><div><h5 class="title"><a
name="N1b61"></a><span class="title">Structure, complexity,
cardinality</span></h5></div></div><p>Implementors of the <tt>Interceptor</tt>
interface
form
a linked-list like
structure through which the <tt>MethodInvocation</tt>
object
is passed. The first
interceptor in the chain is invoked when
<tt>ContainerInvoker</tt> hands off
<tt>MethodInvocation</tt> to the container. The last
interceptor invokes the business
method on the bean. There are usually between 3 and 6 interceptors in
a chain depending on the bean type and container configuration.
Interceptor
semantic complexity ranges from simple to complex ones, but under the
cover they all present the same simple interface. An example of a
simple interceptor would be <tt>LoggingInterceptor</tt>,
while a complex example is
<tt>EntitySynchronizationInterceptor</tt>.</p></div><div class="section"><a
name="N1b7c"></a><div class="titlepage"><div><h5 class="title"><a
name="N1b7c"></a><span class="title">Advantages</span></h5></div></div><p>One of the
main advantages of <tt>Interceptor</tt>
pattern is flexibility
in the arrangement of interceptors, as well as a clear semantic
distinction
between different interceptors. For example, logic for transaction and
security is in <tt>TXInterceptor</tt> and
<tt>SecurityInterceptor</tt> correspondingly.</p><p>If any of the interceptors fail,
we don't have to continue the call
further
through, which is very useful if the interceptor that failed is before
complex
structures like caches.</p></div></div><div class="section"><a
name="N1b92"></a><div class="titlepage"><div><h4 class="title"><a
name="N1b92"></a><span class="title">Instance Pool</span></h4></div></div><div
class="section"><a name="N1b97"></a><div class="titlepage"><div><h5 class="title"><a
name="N1b97"></a><span class="title">Recycling pool for bean
instances</span></h5></div></div><p>
<tt>InstancePool</tt> is used to
manage the EJB-bean
instances that are
not associated with any identity. In fact, to be exact,
<tt>EnterpriseContext</tt> objects that wrap
non-associated bean instances
are pooled in this data structure.</p></div><div class="section"><a
name="N1ba6"></a><div class="titlepage"><div><h5 class="title"><a
name="N1ba6"></a><span class="title">Pool types and
cardinality</span></h5></div></div><p>Depending on the underlying bean type hosted in
a container, there
are three different instance pool types. However, it is important
to notice that each container has only one pool of either
type.</p></div><div class="section"><a name="N1baf"></a><div
class="titlepage"><div><h5 class="title"><a name="N1baf"></a><span class="title">Size
and roles</span></h5></div></div><p>Depending on the configuration, a container may
choose to have a
certain
size of the pool containing recycled instances, or it may choose to
instantiate and initialize an instance on demand.</p><p>The pool is used by
the <tt>InstanceCache</tt> to
acquire free instances
for activation, and it is used by Interceptors to acquire instances
to be
used for Home interface methods (create and finder
calls).</p></div></div><div class="section"><a name="N1bbf"></a><div
class="titlepage"><div><h4 class="title"><a name="N1bbf"></a><span
class="title">Instance Cache</span></h4></div></div><div class="section"><a
name="N1bc4"></a><div class="titlepage"><div><h5 class="title"><a
name="N1bc4"></a><span class="title">Container's cache
structure</span></h5></div></div><p>
<tt>InstanceCache</tt> handles all
EJB-instances that are
in a active
state, i.e. bean instances that have an identity attached to
them.</p></div><div class="section"><a name="N1bd0"></a><div
class="titlepage"><div><h5 class="title"><a name="N1bd0"></a><span
class="title">Entity and stateful session bean cache</span></h5></div></div><p>Only
entity and stateful session beans are cached. The cache key
of an entity bean is the primary key. It is the session id for
stateful
session beans.</p></div><div class="section"><a name="N1bd9"></a><div
class="titlepage"><div><h5 class="title"><a name="N1bd9"></a><span
class="title">Roles</span></h5></div></div><p>
<tt>InstanceCache</tt> handles the
list of active
instances, and is also
responsible for activating and passivating these instances. If
an instance with a given identity is requested, and it is not
currently active, the <tt>InstanceCache</tt> must use
the <tt>InstancePool</tt>
to acquire a free instance, and the persistence manager to
activate the instance. Similarly, if it decides to passivate
a certain active instance, it must call the persistence manager
to passivate it and release the instance to the
<tt>InstancePool</tt>.</p></div></div><div class="section"><a name="N1bef"></a><div
class="titlepage"><div><h4 class="title"><a name="N1bef"></a><span
class="title">EntityPersistenceManager</span></h4></div></div><p>The
<tt>EntityPersistenceManager</tt> is responsible
for the persistence
of EntityBeans. This includes:</p><p>- Creating EntityBeans in a storage
- Loading the state of a given primary key into an EJB-instance
- Storing the state of a given EJB-instance
- Removing the state from storage
- Activating an EJB-instance
- Passivating an EJB-instance</p><p>As per EJB 1.1 specification, JBoss
supports two entity bean
persistance semantics: CMP (Container Managed Persistence) and
BMP (Bean Managed Persistence).</p><p>The CMP plugin,
<tt>CMPPersistanceManager</tt> uses
the default implementor of
<tt>EntityPersistanceManager</tt>,
<tt>JAWSPersistanceManager</tt> (JAWS-Just Another Web Store).
JAWS performs performs basic O/R functionality against a
JDBC-store.</p><p>The BMP implementor of the
<tt>EntityPersistenceManager</tt>
interface is
<tt>BMPPersistanceManager</tt>. BMP persistance manager
is fairly simple
since all persistence logic is in the entity bean itself. The only
duty of the
persistence manager is to perform container callbacks.</p></div><div
class="section"><a name="N1c16"></a><div class="titlepage"><div><h4 class="title"><a
name="N1c16"></a><span
class="title">StatefulSessionPersistenceManager</span></h4></div></div><p>The
<tt>StatefulSessionPersistenceManager</tt> is
responsible for
the persistence of Stateful SessionBeans. This includes:</p><p>- Creating
stateful sessions in a storage
- Activating stateful sessions from a storage
- Passivating stateful sessions to a storage
- Removing stateful sessions from a storage</p><p>The default implementation
of the
<tt>StatefulSessionPersistenceManager</tt>
is <tt>StatefulSessionFilePersistenceManager</tt>. As
its name implies,
<tt>StatefulSessionFilePersistenceManager</tt> utilizes
the underlying file system
to persist stateful SessionBeans. More specifically, persistence
manager
serializes beans in flat file under bean name + bean Id .ser files.
Having a .ser file per bean instance, the Persistance Manager is able
to
restore a
bean's state for activation and respectively store its state during
passivation.</p></div></div></div><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/gbar.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch08.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch08s21.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch08s63.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch08s63.html
Index: ch08s63.html
===================================================================
<html><head><title> Transaction support </title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch08.html" rel="up" title="Chapter 8. Container
architecture - design notes"><link href="ch08s31.html" rel="previous"
title="Container"><link href="ch08s68.html" rel="next" title="Security"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch08.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch08s31.html"><img border="0" height="65" src="!
images/prev.gif" width="76"></a><a href="ch08s68.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1c33"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1c33"></a><span class="title"> Transaction support
</span></h2></div></div><div class="section"><a name="N1c38"></a><div
class="titlepage"><div><h3 class="title"><a name="N1c38"></a><span
class="title">Background</span></h3></div></div><p>In the world of distributed
transaction processing (DTP) a series of
specifications developed by OpenGroup
(www.opengroup.org) represent the most widely adopted DTP model.
</p><p>Opengroup specifications define major components participating in the
DTP
model as well as a set of APIs
that define communication between these components. Components
participating in the DTP model are:
application programs, resource managers, and a transaction manager. The
interface
defined between application
programs wishing to participate in global trasactions and the transaction
manager is called the TX
interface, while the interface between transaction managers and the resource
managers is called the XA interface.</p><p>Sun Microsystems Inc followed this DTP
model and as part of J2EE
introduced the Java Transaction Service (JTS)
and the Java Transaction API (JTA) specifications.</p></div><div class="section"><a
name="N1c45"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c45"></a><span class="title">JTS and JTA</span></h3></div></div><p>The
difference between JTS and JTA is often a source of confusion.
Simply
put JTS defines above mentioned components
participating in the DTP model, while JTA captures interfaces between
them.</p><p>JTS defines five major players in the DTP model of Java Enterprise
middleware:</p><p>Transaction Manager as a core component which provides services of
transaction resource management ( i.e resource
enlistment, delistment), transaction demarcation, synchronization notification
callbacks, trasaction context
propagation and two-phase commit initiation and recovery coordination with
resource managers.</p><p>The application server provides infrastructure required to
support the
application run-time environment.</p><p>A resource manager is a component that
manages access to a persistent
stable storage system. Each resource manager cooperates with a
Transaction Manager in two-phase commit intiation and failure recovery. An
example of resource manager would be
database driver.</p><p>EJB's can either use declarative transaction management
specified in
the ejb-jar.jar xml descriptor, or programmatic transaction manager
using the <tt>UserTransaction</tt> interface. Either way, the
transaction services are provided by the application server.</p><p>A communication
resource manager supports transactional context
propagation. Simply put this component allows
the transaction manager to participate in transactions initiated by other
transaction managers. JTS does not
specify a protocol for this component.</p></div><div class="section"><a
name="N1c61"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c61"></a><span class="title">Core
implementation</span></h3></div></div><p>Jboss includes it's support of JTS and JTA
specifications in the
jboss.tm package. This package include implementation of
TransactionManager , Transaction, Xid and Synchronization from JTA
specification. </p><p>However, the key class is TxCapsule. TxCapsule is has a very
abstract notion but it closely matches the idea of
transaction context. Transaction context in turn is best thought of as a
state of all transactional operations on the
participating resources that make up one global transaction . Therefore
transactional context, or in Jboss's case
TxCapsule, captures all participating XaResources and their states, all
particiating threads as well as a global Xid
identifying global transaction.</p><p>TxCapsule provides the real meat. It enables
enlisting and delisting
of transactional resources, importing of
transactions into capsule, provides creational point and access to Xid of the
current global transaction, calls
Synchronization callback but most importantly it initiates the two-phase commit
protocol as well as rollback mechanisms
defined by the two-phase commit protocol.</p><p>TransactionImpl implements
Transaction interface from JTA. Each
transaction is a part of TxCapsule which in turn can
"host" transactions representing the TxCapsule. All of TransactionImpl methods
are basically indirection calls to the hosting
TxCapsule. </p><p>TxManager implements TransactionManager interface defined in JTA.
As
you might have guessed by now, it controls the lifecycle of all
TxCapsules. Since TxCapsule is a relatively heavyweight object, capsules
are recycled in a soft reference queue.</p></div><div class="section"><a
name="N1c74"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c74"></a><span class="title">TxInterceptor</span></h3></div></div><p>Following
the previously introduced interceptor framework JBoss
introduces two transactional interceptors TXIntereceptorBMT
and TXIntereceptorCMT. Both interceptors closely interact with TxManager in
order to achieve proper transactional semantics.</p><p>TXIntereceptorBMT provides an
instance of UserTransaction to the right
transactional context. TxInterceptorBMT is used
in the case of user demarcated, i.e explicit transactional management. For
more information on details of semantics
refer to p174 of EJB1.1 spec.</p><p>TxInterceptorCMT moves all transactional
management work to the
container. Depending on the transaction attributes specified in th
ejb-jar.xml file
(i.e TX_REQUIRED, TX_SUPPORTS, TX_REQUIRES_NEW etc) the container decides how
to manage
the transactional context of the invoked call.</p></div></div><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch08.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch08s31.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch08s68.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch08s68.html
Index: ch08s68.html
===================================================================
<html><head><title>Security</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch08.html"
rel="up" title="Chapter 8. Container architecture - design notes"><link
href="ch08s63.html" rel="previous" title=" Transaction support "><link
href="ch08s72.html" rel="next" title="Tracing the call through container"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch08.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch08s63.html"><img bor!
der="0" height="65" src="images/prev.gif" width="76"></a><a href="ch08s72.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N1c82"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1c82"></a><span class="title">Security</span></h2></div></div><div
class="section"><a name="N1c87"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c87"></a><span class="title">Authentication - checking
credentials</span></h3></div></div><p>
<tt>Credential</tt> is an object that the client
supplies to
authenticate himself to the
system. <tt>Credential</tt> might be a password, a digital
signature, or another identifier.
It might also be a wrapper of that credential to indicate that the jboss
server trusts the invoker about the principal and no authentication is
necessary (e.g. for in-VM invocations, or invocations from a web
container).</p><p>The authentication interface is:</p><p>
<pre class="programlisting">public interface
org.jboss.system.SecurityManager
{
public boolean isValid( Principal principal,
Object credential );
}</pre>
</p><p>Judgments about validity are based on the
<tt>Principal</tt> class type,
<tt>Principal</tt> name, and credential. Typically, one
implementation
exists per security realm.</p><p>The security manager implementation is
registered in the JNDI
namespace as "SecurityManager." and is shared between containers.
This system level implementation would only delegate to the realm-level
implementations to see if the Principal/credential pair were
valid.</p></div><div class="section"><a name="N1cad"></a><div
class="titlepage"><div><h3 class="title"><a name="N1cad"></a><span
class="title">Authorization - checking access to
resources</span></h3></div></div><p>Authorization interface is defined as
follows:</p><p>
<pre class="programlisting">public interface RealmMapping
{
public boolean doesUserHaveRole( Principal principal,
Set roleNames );
}</pre>
</p><p>A <tt>RealmMapping</tt> describes a relation between a
list of principals,
and a set of roles assigned to each principal. Unlike
SecurityManagers, RealmMappings are specific to a particular
J2EE application. So the relationship is the following:
J2EE app has many realms, a realm has many principals,
and a principal has many roles.</p><p>The <tt>RealmMapping</tt> interface is
used in
conjunction with the
authorization information in the EJB 1.1 or 2.0 deployment
descriptor. It is also used for the implementation of
<tt>isCallerInRole</tt> call. Set of roleNames would have
only one role in
that case.</p><p>A <tt>CacheRealmMapping</tt> is a "meta-level"
implementation of
RealmMapping that handles lists of realms for a particular J2EE
application. It is called <tt>CacheRealmMapping</tt>
because we cache
information about a particular principal if access to the
persistent mapping is expensive.</p></div><div class="section"><a
name="N1cd8"></a><div class="titlepage"><div><h3 class="title"><a
name="N1cd8"></a><span class="title">SecurityInterceptor</span></h3></div></div><p>The
<tt>SecurityInterceptor's</tt> first task would be
to use the
SecurityManager to authenticate the <tt>Principal</tt>,
based on the
credential available in <tt>MethodInvocation</tt>.</p><p>Then,
<tt>SecurityInterceptor</tt>, given a method that
has to be invoked,
retrieves methodPermissions (set of roles) from the container and checks
if caller's principal has any of those retreived roles.</p></div></div><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch08.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch08s63.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch08s72.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch08s72.html
Index: ch08s72.html
===================================================================
<html><head><title>Tracing the call through container</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch08.html" rel="up" title="Chapter 8. Container
architecture - design notes"><link href="ch08s68.html" rel="previous"
title="Security"><link href="ch09.html" rel="next" title="Chapter 9.
Howto"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch08.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch08s68.html"><img border="0" !
height="65" src="images/prev.gif" width="76"></a><a href="ch09.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1cf1"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1cf1"></a><span class="title">Tracing the call through
container</span></h2></div></div><p>The preceding sections discussed specific pieces
of call handling
at length. Now it is time to put all the pieces together to see how a
complete method invocation is handled. In particular, let's look at the
handling of method calls on an Entity Bean.</p><p>The call is first logged. Then
the TxInterceptor decides how to manage
transactions for this call. The information needed for this decision
comes from the standard XML descriptor. Then, the SecurityInterceptor
checks if the caller is allowed to perform this call, again by using
information from the XML descriptor. Up until this point no instance
has been acquired. After all interceptors have been passed the container
will invoke the business method on the EJB instance, so now we
acquire this instance.</p><p>The interceptor calls the InstanceCache with
the given primary key to perform this. Since the cache does not yet
have an instance associated with the given primary key, it first gets
a free instance from the instance pool, which it associates with the
primary key. It then calls the persistence manager which will activate
the instance. This usually only involves calling ejbActivate.</p><p>After
instance acquisition the next interceptor deals with how this
instance is
synchronized with the database. There are a number of options (load on
transaction start, load on each call, load on activate, etc.) and the
interceptor has been configured to perform one of these options. In
this example it will load on activate, so it calls the persistence
manager to perform this. This will cause an ejbLoad call to be made
on the instance.</p><p>Next, the last interceptor is invoked, which is the
container itself. The container always adds itself as the last interceptor
at the end of the chain. The call is now delegated to the EJB instance.
The instance performs some work, and returns a result. The interceptor
chain is now followed in reverse by having each interceptor return from
the invoke-operation. The instance synchronization interceptor chooses
to store the current state into the database and hence calls storeEntity
on the persistence manager. Another valid option would be to wait until
transaction commit.</p><p>Next, the instance is returned to the cache. If the
transaction does not end with this call, it will first lock the instance
to this transaction so that no other transaction may use it for the
duration of this current transaction. This is the same as pessimistic
locking. The transaction interceptor handles the method return according
to the transaction settings, possibly commiting or rollbacking the current
transaction. Finally, the container invoker returns the result to the
client. This completes the call.</p><p>As you can see, all implementation
decisions are performed by various
plugins.
These decisions are fairly loosely coupled, which allows the deployer of
the EJB-application to tweak the behaviour of the container to a great
degree. This also allows for a number of independent plugins to co-exist,
each one allowing for slightly, or radically, different behaviour.</p><p>For
example, some persistence managers could use an XML-file as the
backing
store instead of an RDBMS, and some security interceptor could use ACL's
from a database instead of the XML descriptor to perform security checks.
Or multiple security checks could be done by configuring the container
to have several security interceptors of different types. All of these
options are available by this componentized container
architecture.</p></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch08.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch08s68.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch09.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09.html
Index: ch09.html
===================================================================
<html><head><title>Chapter 9. Howto</title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="index.html"
rel="up" title="JBoss 2.0 documentation"><link href="ch08s72.html" rel="previous"
title="Tracing the call through container"><link href="ch09s07.html" rel="next"
title="Running the Examples from Enterprise JavaBeans, by Richard Monson-Haefel (Unix)
"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" wi!
dth="60"></a><a href="ch08s72.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch09s07.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div class="chapter"
id="N1d10"><div class="titlepage"><div><h2 class="title"><a name="N1d10"></a>Chapter
9. Howto</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="ch09.html#N1d14">Running Tomcat with JBoss</a></dt><dt> <a
href="ch09s07.html">Running the Examples from Enterprise JavaBeans, by Richard
Monson-Haefel (Unix) </a></dt><dt> <a href="ch09s08.html">JMX Connector Description
and HowTo</a></dt><dt> <a href="ch09s24.html">How To us the Timer MBean</a></dt><dt>
<a href="ch09s27.html">Deployment on JBoss</a></dt><dt> <a href="ch09s32.html">JAAS
Based Security in JBoss</a></dt><dt> <a href="ch09s50.html">Using JavaMail in
JBoss</a></dt><dt> <a href="ch09s53.html">How to Run JBoss in JBuilder's
Debugger</a></dt><dt> <a href="ch0!
9s56.html">EJX/AWT Development HowTo</a></dt><dt> <a href="ch09s81.html">JBossCX
Configuration</a></dt><dt> <a href="ch09s92.html">External JNDI Configuration and JNDI
Viewing</a></dt></dl></div><div class="section"><a name="N1d14"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N1d14"></a><span
class="title">Running Tomcat with JBoss</span></h2></div></div><div class="section"><a
name="N1d18"></a><div class="titlepage"><div><h3 class="title"><a
name="N1d18"></a><span class="title">Goal</span></h3></div></div><p>
As part of project Game Over, the JBoss organization wants to deliver a complete
J2EE based product to the market. The JBoss organization decided to integrate the
Tomcat
engine stack with a running version of JBoss in a single VM. Now you can serve all
your servlet and JSP needs with 2 simple downloads and a couple of configuration files.
Check out the Tomcat homepage for information related to Tomcat. </p><p>
The goal of this page is to explain how to make JBoss automatically start Tomcat,
so that it runs in the same VM.</p></div><div class="section"><a name="N1d23"></a><div
class="titlepage"><div><h3 class="title"><a name="N1d23"></a><span
class="title">Benefits</span></h3></div></div><p>
One benefit of running Tomcat inside the same VM as JBoss is to have an easier to
manage application server. The main goal, however, is greater performance. By
eliminating
unnecessary network calls and keeping all the invocations inside one VM the
performance is significantly enhanced.</p><p>
If you have Servlets/JSPs which access some EJBs, you'll get dramatically improved
performance because the calls will be intra-VM (no network access).</p><p>
WARNING
THIS IS STILL A BETA VERSION. </p></div><div class="section"><a
name="N1d31"></a><div class="titlepage"><div><h3 class="title"><a
name="N1d31"></a><span class="title">Requirements</span></h3></div></div><p>
JBoss 2.0. BETA-PROD 03
Tomcat Version 3.2b4. You can get the latest release of tomcat from the
jakarta website.</p><p>
NOTE: This has been tested with tomcat up to 3.2b6, and should work with the
forthcoming final 3.2 version. However it won't run on tomcat 3.1, and tomcat 3.3 is
not
suppported yet. </p></div><div class="section"><a name="N1d3c"></a><div
class="titlepage"><div><h3 class="title"><a name="N1d3c"></a><span
class="title">How-to setup jboss for tomcat</span></h3></div></div><p>
<div class="itemizedlist"><ul><li><p><a name="N1d44"></a>Setup environment
variables.In whatever batch or shell script you use to launch JBoss and Tomcat, add
entries for the following environment variables
<div class="table"><p><a name="N1d47"></a><b>Table 9.1. Enviromental
variables</b></p><table border="1" summary="Enviromental
variables"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>TOMCAT_HOME</td><td>The
base directory of Tomcat's binaries. With the binary distribution, this would be
jakarta-tomcat under your installation root</td></tr><tr><td>JAVA_HOME</td><td>The
base directory of your JDK 1.2.2 or 1.3
installation</td></tr><tr><td>CLASSPATH</td><td>This should not include anything
(unless you really know what you're doing!). Both Tomcat and JBoss have startup
scripts that load the necessary
JARs onto the classpath.</td></tr></tbody></table></div>
</p></li><li><p><a name="N1d7d"></a>Edit jboss.conf. It is located in the conf
directory under the base of your JBoss binary distribution, or the dist/conf directory
if you built from the JBoss source. There are some commented-out lines near
the end of the file that deal with Tomcat:
<pre class="programlisting">
<!--
-- Uncomment this to add "Integrated Stack (fast) Tomcat support".
-- This service allows you to integrate the stack of Tomcat and jboss.
-- Invocations are not going through network but pass native
-- pointers resulting in dramatic speed increases.
-- This service allows the J2EE deployer to add and remove Tomcat contexts
dynamically
-- through JMX for you and in effect deploy EARs. Note that tomcat's
-- server.xml file will be partially processed for context support: you can
-- also use JMX to add contexts.
-- Use the J2EE deployer to deploy full EARs on this stack
-- Be sure to set your 'TOMCAT_HOME' environment variable before starting
JBoss.
--
-- The ARG tags are the config file and the port to run tomcat on. Note:
only the url
-- contexts will be parsed, (path and docBase attruibutes only) all other
-- configurations are not yet supported.
--
-- MLET CODE = "org.jboss.tomcat.EmbeddedTomcatService" ARCHIVE="jboss.jar"
CODEBASE="../../lib/ext/">
-- ARG TYPE="java.lang.String" VALUE="full path to tomcat config file">
-- ARG TYPE="int" VALUE=8080>
-- /MLET>
</pre>
</p><p>
You need to uncomment these lines so they read as follows (note you must add
the < signs at the beginning of the
three relevant lines and the file path must always begin with a '/'):
<pre class="programlisting">
<MLET CODE = "org.jboss.tomcat.EmbeddedTomcatService" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="/yyy/server.xml">
<ARG TYPE="int" VALUE=8080>
</MLET>
</pre>
</p></li><li><p><a name="N1d8f"></a>Start JBoss. If you start JBoss now by
typing run.sh (or run.bat for Windows) you should see the following Tomcat related
output
in your log messages:
<pre class="programlisting">
...
[EmbeddedTomcat] Initializing
[EmbeddedTomcat] Initialized
[EmbeddedTomcat] Starting
[EmbeddedTomcat] Testing if Tomcat is present....
[EmbeddedTomcat] OK
[EmbeddedTomcat] ContextManager: Adding context Ctx( )
[EmbeddedTomcat] path="" :jsp: init
[EmbeddedTomcat] PoolTcpConnector: Starting HttpConnectionHandler on 8080
[EmbeddedTomcat] Started
...
</pre>
</p></li></ul></div>
</p><p>
That's it !! You just have to launch JBoss now and it will start Tomcat and you
will have an EJB/JSPs/Servlets server running in one VM... </p></div><div
class="section"><a name="N1d9f"></a><div class="titlepage"><div><h3 class="title"><a
name="N1d9f"></a><span class="title">How-to build web applications for jboss and
tomcat</span></h3></div></div><p>
In order to benefit from the classloader integration, you have to deploy your
application in an ear file as recommended by the J2EE specification.</p><p>
Tomcat's server.xml file will not be processed!</p><p>
The reason is that we want to share the classloader for your application between
tomcat and jboss. Since this classloader must be initialized at
deployment time, your EJBs and your servlets/JSPs must be bundled together for
jboss to know who talks to whom! </p><p>
In case you don't want to read all the J2EE spec, here is a brief summary of what
you have to do:</p><div class="orderedlist"><ol type="1"><li><p><a
name="N1db5"></a>Write your beans and package them in an ejb-jar file. You don't have
to do anything special here.
See the manual for details on how to package beans for
jboss.</p></li><li><p><a name="N1db9"></a>Write your servlets/JSPs and package them in
a war file. Assuming you have a bean deployed under the jndi name "myBean",
the calls to this bean from your servlets will look like that: </p><pre
class="programlisting">
MyBeanHome home = (MyBeanHome)new InitialContext().lookup("myBean");
MyBean bean = home.create();
</pre><p>
Notes:
We don't support lookups in the "java:" namespace from the servlets yet,
but work is in progress.
Since jboss takes care of the classloader stuff, you don't have to
include much in the WEB-INF/lib directory: you don't any of your beans interfaces, and
you
don't need the usual jboss-client.jar, jnp-client.jar...
</p></li><li><p><a name="N1dc6"></a>Package your application in an ear file. An ear
file is a jar archive which contains:</p><div class="itemizedlist"><ul><li><p><a
name="N1dcc"></a>Your jar files</p></li><li><p><a name="N1dd0"></a>Your war
files</p></li><li><p><a name="N1dd4"></a>A deployment descriptor for your application.
This file must be named "application.xml", and must be located in the META-INF
directory in the ear archive. This file tells jboss which modules are
EJBs, which ones are web modules, and the context paths for the web-modules.
Here is a sample application.xml file:
<pre class="programlisting">
<?xml version="1.0" encoding="ISO-8859-1"?>
<application>
<display-name>My application</display-name>
<module>
<web>
<web-uri>webmodule.war</web-uri>
<context-root>/servlets</context-root>
</web>
</module>
<module>
<ejb>beans.jar</ejb>
</module>
</application>
</pre>
</p></li></ul></div><p>
See also the DTD for application.xml on Javasoft's website.
</p></li><li><p><a name="N1de2"></a>Deploy your ear file. Surf to
http://yourhost:8082, and find the J2eeDeployer service. Give it the URL of your ear
file
(don't forget the protocol, be it http: or file:), and click on the deploy
button.</p></li><li><p><a name="N1de6"></a>That's it! The server console should show
your application being deployed on tomcat and jboss, and your web module should be
available on
http://yourhost:8080/servlets (assuming the context-root was
"/servlets").</p></li></ol></div><p>
For a full example including a servlet and an EJB, see the contrib module
</p></div></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="index.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch08s72.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch09s07.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s07.html
Index: ch09s07.html
===================================================================
<html><head><title>Running the Examples from Enterprise JavaBeans, by Richard
Monson-Haefel (Unix) </title><link href="styles.css" rel="stylesheet"
type="text/css"><meta content="DocBook XSL Stylesheets V1.30" name="generator"><link
href="index.html" rel="home" title="JBoss 2.0 documentation"><link href="ch09.html"
rel="up" title="Chapter 9. Howto"><link href="ch09.html" rel="previous" title="Chapter
9. Howto"><link href="ch09s08.html" rel="next" title="JMX Connector Description and
HowTo"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></!
a><a href="ch09.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch09s08.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1df0"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1df0"></a><span class="title">Running the Examples from
Enterprise JavaBeans, by Richard Monson-Haefel (Unix)
</span></h2></div></div><p>Author:
<span class="author">Sebastien Alborini</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><p>
This page describes how to run the examples from Richard Monson-Haefel's book
Enterprise JavaBeans, 2nd Edition
(Chapter 4) in JBoss.</p><p>
You can download the examples (zip file) from O'Reilly's site. I will assume you
have unzipped this file and you work in
the chapter4/EJB11 directory.</p><p>
These examples need to be slightly modified to run with JBoss. You can download the
modified version from the files area in the
documentation section on www.jboss.org. The archive name is
“rmh_jboss.zip”. But I
recommend you to follow these instructions which tell exactly what has to be
modified.</p><div class="itemizedlist"><ul><li><p><a name="N1e0e"></a>Setup your
environment.</p><p>JBoss libraries will be needed to compile and run the examples, so
you have to set the environment variable
JBOSS_HOME to your JBoss installation. For example:
<div class="itemizedlist"><ul><li><p><a name="N1e16"></a>export
JBOSS_HOME=$HOME/jboss_pr4 if you have the binary version in your home directory
</p></li><li><p><a name="N1e1a"></a>export JBOSS_HOME=$HOME/jboss/dist if you have the
CVS version.</p></li></ul></div>
</p></li><li><p><a name="N1e21"></a>Compile and deploy the beans.</p><p>The
beans are almost ok for JBoss, the only difference is about the reference made by
TravelAgentBean to
CabinBean: a bean must lookup in the java:comp/env namespace. Edit
com/titan/travelagent/TravelAgentBean.java, and replace
<pre class="programlisting">
Object obj = jndiContext.lookup("ejb/CabinHome");</pre>
with
<pre class="programlisting">
Object obj = jndiContext.lookup("java:comp/env/ejb/CabinHome"); </pre>
</p><p>
This ejb-reference from TravelAgentBean (in travelagent.jar) to CabinBean (in
cabin.jar) is an external
reference (different ejb-jar file). You must then provide the full jndi name
for CabinBean in a jboss.xml for
TravelAgentBean: create and edit com/titan/travelagent/jboss.xml
<pre class="programlisting">
<?xml version="1.0"?>
<jboss>
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<ejb-ref>
<ejb-ref-name>ejb/CabinHome</ejb-ref-name>
<jndi-name>CabinBean</jndi-name>
</ejb-ref>
</session>
</enterprise-beans>
</jboss>
</pre>
</p><p>
You don't jave to change anything in ejb-jar.xml. You can now use the following
script jbossMakeIt.sh to
compile and deploy:
<div class="literallayout"> <br>
<b><br>
#!/bin/sh <br>
<br>
# make cabin bean<br>
<br>
javac -classpath $JBOSS_HOME/lib/ext/ejb.jar:. \<br>
com/titan/cabin/Cabin*.java<br>
<br>
cp com/titan/cabin/ejb-jar.xml META-INF/ejb-jar.xml<br>
jar cvf cabin.jar com/titan/cabin/Cabin*.class META-INF/ejb-jar.xml<br>
<br>
<br>
# make travelagent bean<br>
<br>
javac -classpath $JBOSS_HOME/lib/ext/ejb.jar:. \<br>
com/titan/travelagent/TravelAgent*.java<br>
<br>
cp com/titan/travelagent/ejb-jar.xml \<br>
com/titan/travelagent/jboss.xml \<br>
META-INF/<br>
<br>
# JBoss needs the Home, Remote and primary key (PK) classes<br>
# of the Cabin in travelagent.jar so that TravelAgent*.class<br>
# can access the Cabin bean<br>
<br>
jar cvf travelagent.jar \<br>
com/titan/cabin/CabinHome.class \<br>
com/titan/cabin/Cabin.class \<br>
com/titan/cabin/CabinPK.class \<br>
com/titan/travelagent/TravelAgent*.class \<br>
META-INF/ejb-jar.xml META-INF/jboss.xml<br>
<br>
rm -f META-INF/ejb-jar.xml<br>
rm -f META-INF/jboss.xml<br>
<br>
# deploy<br>
cp cabin.jar travelagent.jar $JBOSS_HOME/deploy<br>
</b></div>
</p></li><li><p><a name="N1e48"></a>Compile the clients.</p><p>
The clients from the examples perform a lookup on the java:comp/env namespace,
which is not
currently supported by JBoss for the clients. You have to make the following
edits: (CabinBean is the jndi
name under which the Cabin Bean is deployed, see the jndi howto)
In com/titan/cabin/Client_1.java replace
<pre class="programlisting">
Object obj = jndiContext.lookup("java:comp/env/ejb/CabinHome");</pre>
by
<pre class="programlisting">
Object obj = jndiContext.lookup("CabinBean");</pre>
In com/titan/cabin/Client_2.java replace
<pre class="programlisting">
Object obj = jndiContext.lookup("ejb/CabinHome");</pre>
by
<pre class="programlisting">
Object obj = jndiContext.lookup("CabinBean");</pre>
In com/titan/travelagent/Client_1.java replace
<pre class="programlisting">
Object obj = jndiContext.lookup("ejb/CabinHome");</pre>
by
<pre class="programlisting">
Object obj = jndiContext.lookup("CabinBean");</pre>
You can now use jBossMakeClients.sh to compile:
<div class="literallayout"><br>
<b><br>
#!/bin/sh <br>
<br>
javac -classpath $JBOSS_HOME/lib/ext/ejb.jar:. \<br>
com/titan/cabin/Client*.java \<br>
com/titan/travelagent/Client*.java<br>
<br>
</b><br>
</div>
</p></li><li><p><a name="N1e79"></a>Run the clients</p><p>
We don't use Sun's RI runclient tool, so RunIt.sh won't work. Instead, we
provide the following script:
jBossRunClient.sh. This file includes all the jBoss libraries needed in the
classpath.
<div class="literallayout"><br>
<b><br>
#!/bin/sh <br>
<br>
CP=$JBOSS_HOME/client/ejb.jar<br>
CP=$CP:$JBOSS_HOME/client/jndi.jar<br>
CP=$CP:$JBOSS_HOME/client/jta-spec1_0_1.jar<br>
CP=$CP:$JBOSS_HOME/client/jboss-client.jar<br>
CP=$CP:$JBOSS_HOME/client/jnp-client.jar<br>
<br>
CP=$CP:.<br>
<br>
java -cp $CP $1<br>
</b><br>
</div>
You also have to set the jndi properties to connect to the server. This is done
in the jndi.properties file (this file
must be in the same directory as jBossRunClient.sh)
<pre class="programlisting">
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost
java.naming.factory.url.pkgs=org.jboss.naming;
</pre>
You can now run the clients. The script take the name of the client as an
argument, try
<div class="literallayout"> <br>
<b><br>
./jBossRunClient.sh com.titan.cabin.Client_1<br>
./jBossRunClient.sh com.titan.cabin.Client_2<br>
./jBossRunClient.sh com.titan.travelagent.Client_1<br>
</b></div>
</p><p>
NOTES:
the clients will only run once, since they use the EJBHome.create() method:
at second run, a
DuplicateKeyException will occur.
I recommend you to turn off debug logging for these examples. Edit
$JBOSS_HOME/conf/jboss.conf, in
the ConsoleLogging section, set the first ARG to "Error".
</p></li></ul></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch09s08.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s08.html
Index: ch09s08.html
===================================================================
<html><head><title>JMX Connector Description and HowTo</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s07.html" rel="previous" title="Running the Examples from Enterprise
JavaBeans, by Richard Monson-Haefel (Unix) "><link href="ch09s24.html" rel="next"
title="How To us the Timer MBean"></head><body alink="#0000FF" bgcolor="white"
link="#0000FF" text="black" vlink="#840084"><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/jboss.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" w!
idth="60"></a><a href="ch09s07.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch09s24.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N1ea2"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1ea2"></a><span class="title">JMX Connector Description
and HowTo</span></h2></div></div><p>Author:
<span class="author">Andreas Shaefer</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N1eb3"></a><div class="titlepage"><div><h3
class="title"><a name="N1eb3"></a><span
class="title">Introduction</span></h3></div></div><div class="section"><a
name="N1eb7"></a><div class="titlepage"><div><h4 class="title"><a
name="N1eb7"></a><span class="title">JMX Spec from Sun</span></h4></div></div><p>
Sun release recently the final specification, API and Reference Implemenation
to the
<a href="http://www.javasoft.com/products/JavaManagement/index.html"
target="_top"><i>Java Management
Extention(JMX)</i></a>.
The idea behind this is to provide an API to which the component vendors can
make their components
manageable and the management tools vendor can use this API to manage these
components. </p><p>
Therefore the whole JMX is separated into 3 parts:
<div class="orderedlist"><ol type="1"><li><p><a name="N1ecc"></a>
Components implement a certain API to offer their management API to
the JMX world. There are 3 ways: through an Interface, through a API
descriptions (Open MBean) and through a Model MBean (but for this
have a look at the spec).
</p></li><li><p><a name="N1ed0"></a>
JMX Agent which contains a MBean Server, certain services like
dynamic download, timers, relations etc. and at least one Connector
or Adaptor.
</p></li><li><p><a name="N1ed4"></a>
Management Tool using a Connector or Adaptor to manage the
components of the JMX Agent the tool is connected to.
</p></li></ol></div>
</p></div><div class="section"><a name="N1edb"></a><div
class="titlepage"><div><h4 class="title"><a name="N1edb"></a><span class="title">
JMX Implementation in JBoss</span></h4></div></div><p>
At the moment (8th of September 2000) JBoss uses the final release JMX API for
its services defined in the
jboss.conf file (in there you see that also HTML
Adaptor and the JMX Connector are manageable components). In addition JBoss
use the MBean Server implementation
and the HTML adaptor from the JMX-RI.
The JMX Connector also follows the JMX final spec and API.</p><p>
You use JMX first when you start JBoss because the Main class loads the MLET
tags from the jboss.conf file and
hand it over to the MBeanServer which loads the
MBean dynamically (MLET is the tag to dynamically load a MBean by the
MBeanServer). Afterwards it went through
the loaded MBeans and starts all the loaded
MBeans. </p><p>
Afterwards you can use JMX either trough the JMX HMTL Adaptor on port 8082 or
through the new JMX Connector. The
JMX HTML Adaptor is provided by the
JMX-RI and the source code is not available (it is part of Sun's JDMK which
you have to buy when you want to get
the source as far as I know). The JMX
Connector is part of the JBoss code and should be considered as first draft
because the Connector is mentioned
within the spec by not further specified.
</p><p>
Finally JMX is used within the shutdown hook to terminate all the services
before JBoss is terminated itself
(whatever this means) by going through all available
MBeans and send them the stop signal (call the appropriate method).
</p></div></div><div class="section"><a name="N1eee"></a><div
class="titlepage"><div><h3 class="title"><a name="N1eee"></a><span
class="title">Design of the JMX Connector</span></h3></div></div><div
class="section"><a name="N1ef3"></a><div class="titlepage"><div><h4 class="title"><a
name="N1ef3"></a><span class="title">Introduction</span></h4></div></div><p>
According to the JMX spec the Connector should allow a management tool to work
on a MBeanServer and its MBeans
from another JVM which can be on the same
computer or a remote computer. One particular Connector is bound to its
protocol it supports but a MBeanServer
can offer more than one (a JMX agent has to offer
at least an Adaptor or a Connector) supporting different protocols. Because
the spec does not say much about
Connectors I take the freedom and implemented the
actual Connector within JBoss to lay the base for a remote JBoss management
which is a little bit more
comfortable than the HTML Adaptor.</p><p>By the way I will take this
opportunity to thanks Rickard ֢erg for his support. </p></div><div
class="section"><a name="N1eff"></a><div class="titlepage"><div><h4 class="title"><a
name="N1eff"></a><span class="title">Goals</span></h4></div></div><p>These are my
goals for a JMX Connector:
<div class="itemizedlist"><ul><li><p><a name="N1f08"></a>Ease of
use</p></li><li><p><a name="N1f0c"></a>From the user perspective the Connector should
appear like a local</p></li><li><p><a name="N1f10"></a>MBeanServer</p></li><li><p><a
name="N1f14"></a>Unsupported methods throw an exception</p></li><li><p><a
name="N1f18"></a>Supports remote notification handling</p></li><li><p><a
name="N1f1c"></a>First draft supports RMI protocol</p></li></ul></div>
</p><p>
According to the spec the JMX Connector should offer the client a Proxy for a
remote MBean but then the MBean
proxy must be available at compile time and this
compete with the JMX agent requirements that an JMX agent has to support
dynamic loading of MBeans therefore this
is not supported now. </p><div class="section"><a name="N1f25"></a><div
class="titlepage"><div><h5 class="title"><a name="N1f25"></a><span
class="title">Design</span></h5></div></div><p>
The JMX Connector is separated into 4 parts:
<div class="orderedlist"><ol type="1"><li><p><a name="N1f32"></a>Server-side
implementation </p></li><li><p><a name="N1f36"></a>Client-side implementation
</p></li><li><p><a name="N1f3a"></a>Connector Factory to lookup servers and protocols
(optional)</p></li><li><p><a name="N1f3e"></a>Test client </p></li></ol></div>
</p><div class="section"><a name="N1f44"></a><div class="titlepage"><div><h6
class="title"><a name="N1f44"></a><span class="title">Server-side
implementation</span></h6></div></div><p>
The server-side implementation is loaded and started by the MBeanServer which
should become available for remote
management. For this we have the necessary
MBean service classes, the Connector implementation and an Object Handler
class.
The Object Handler class is a serializable class allowing the remote client to
deal with remotely instantiated
classes. This eliminates problems with not serializable
classes and with the unique identification of serialized classes (on a round
trip you get a copy of the original
instance). </p><p>
The Object Handler is also used to avoid
troubles with not serializable classes used as a Handback object in the
Notification handling. This class allows
the client to work on the JMX Connector as he
would work on a local MBeanServer.</p></div><div class="section"><a
name="N1f50"></a><div class="titlepage"><div><h6 class="title"><a
name="N1f50"></a><span class="title"> Client-side
implementation</span></h6></div></div><p>
The client-side implementation can either be used directly by instantiating
the RMIClientConnectorImpl or by
using the Connector Factory. The client-side
Connector is more or less a MBeanServer which sends the request over the
supported protocol to the server-side
connector and returns the returned object back to
the caller. There are a few methods which cannot be supported and therefore
throw a unsupported operation
exception. </p><p>
To make it clear and also for documentation purpose the client-side connector
implements the JMXConnector
Interface. At the moment I want still keep this
interface even when MBeanServer is now an interface too because which all good
programming techniques it is (at
least at the moment) not possible to make it
100% transparent (but see later under limitations). </p></div><div
class="section"><a name="N1f5c"></a><div class="titlepage"><div><h6 class="title"><a
name="N1f5c"></a><span class="title"> Connector Factory</span></h6></div></div><p>
When I started with the JMX Connector I had a management tool in mind like the
network administration tool from
CA or the proposed AppCenter from Inprise.
Therefore I want to make it as easy as possible for the client to connector as
many remote MBeanServers as he/she
wants and which any protocol available. The
client should never have to worry about the protocol or to know which classes
are behind. That's why I created
the Connector Factory which allows the client to
search for all the remote available MBeanServers and their supported
protocols. The user only has to select a
server and then a protocol and the Connector Factory
returns the appropriate instance of the JMXConnector interface. </p></div><div
class="section"><a name="N1f65"></a><div class="titlepage"><div><h6 class="title"><a
name="N1f65"></a><span class="title"> Test Client</span></h6></div></div><p>
The JMX Connector Test Client is first a test tool that the JMX Connector is
working and second a demonstration
how to use it. The test tool first starts a local
MBeanServer and register the Connector Factory as first and then only MBean.
Now the test client ask the
Connector Factory for all available, remote
MBeanServers and let the user select one, then it asks the Connector Factory
for all available Connectors or more
precise all the supported protocols of the
available Connectors. Now the user can select the protocol and the Test Client
loads and starts the appropriate
Connector (if available) and register it as a new
MBean at the local MBeanServer. Afterwards it asks the Connector for all
available MBeans on the remote server,
displays it wit all the attributes and operations
on this remote MBean. At the end it will try to register to all remote MBeans
a notification listener which will
inform the client about notification send by the MBean.
That's why the test client will still run after finishing. When the user
terminates the Test Client it will
remove all the notification listeners from the remote
MBeanServer and terminate the Test Client. </p></div></div></div></div><div
class="section"><a name="N1f71"></a><div class="titlepage"><div><h3 class="title"><a
name="N1f71"></a><span class="title">How To use the JMX
Connector</span></h3></div></div><p>
You need the following to use the JMX Connector:
<div class="itemizedlist"><ul><li><p><a name="N1f7a"></a>Connector.jar
(from client directory) </p></li><li><p><a name="N1f7e"></a>jnp-client.jar (from
client directory) </p></li><li><p><a name="N1f82"></a>jmxri.jar (from lib directory)
</p></li><li><p><a name="N1f86"></a>jndi.properties (from conf directory) which you
probably have to
adjust</p></li></ul></div>
</p><div class="section"><a name="N1f8c"></a><div class="titlepage"><div><h4
class="title"><a name="N1f8c"></a><span class="title">How to create a client with the
server and protocol</span></h4></div></div><p>
<div class="orderedlist"><ol type="1"><li><p><a name="N1f99"></a>
Instantiate the RMIClientConnectorImpl.
<pre class="programlisting">
JMXConnector lConnector = new RMIClientConnectorImpl("server-name"
); </pre>
</p></li><li><p><a name="N1fa2"></a>
Use either instance or its interface JMXConnector or MBeanServer. If you
got back an instance you can now
work on the remote MBeanServer like it would be a local one.
</p></li><li><p><a name="N1fa6"></a>
Look up for the available MBeans, its attributes and operations. You can
now retrieve and set the
attributes or perform an operation on the remote MBean.
</p></li><li><p><a name="N1faa"></a>
If you register a Notification Listener then stop this instance before
terminating the program otherwise
the remote MBeanServer will throw an exception when this Notification
Listener is called.
lConnector.stop();
</p></li></ol></div>
</p></div><div class="section"><a name="N1fb1"></a><div
class="titlepage"><div><h4 class="title"><a name="N1fb1"></a><span class="title">How
to create a client without the server and protocol/H3> </span></h4></div></div><p>
First you have to make sure that the JNDI property:
java.naming.provider.url points to the JNDI server your JMX Connectors
are registered to. At the moment you can only have one JMX Connector
running at the same computer (but serveral can be registered at the same
JNDI server) and you can only have one JNDI server. </p><div
class="orderedlist"><ol type="1"><li><p><a name="N1fbf"></a>
Import the necessary classes
<pre class="programlisting">
import com.sun.management.jmx.MBeanServerImpl;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
import javax.naming.InitialContext;
import org.jboss.jmx.interfaces.JMXConnector;
import org.jboss.jmx.client.RMIClientConnectorImpl; </pre>
</p></li><li><p><a name="N1fc8"></a>
Instantiate a local MBeanServer (MBeanServerImpl)
<pre class="programlisting">
final MBeanServer lLocalServer = new MBeanServerImpl(); </pre>
The local variable is made final because it is needed in the shutdown
hook.
</p></li><li><p><a name="N1fd1"></a>
Load the logger MBean (is needed now because the Connector Factory
is a standard JBoss MBean but maybe I should make it to a normal
MBean to make it leaner).
<pre class="programlisting">
lLocalServer.createMBean( "org.jboss.logging.Logger", new
ObjectName( "DefaultDomain :name=Logger" ) ); </pre>
</p></li><li><p><a name="N1fda"></a>
Load and start the ConnectorFactory MBean
<pre class="programlisting">
final ObjectInstance lFactoryInstance =
lLocalServer.createMBean(
"org.jboss.jmx.client.ConnectorFactoryService", new
ObjectName( "DefaultDomain:name=ConnectorFactory" ) );</pre>
</p></li><li><p><a name="N1fe3"></a>
Look for the list of servers (if a null is passed as parameter this
method returns all the servers at the given JNDI server)
<pre class="programlisting">
Collection lServers = (Collection) lLocalServer.invoke(
lFactoryInstance.getObjectName(), "getServers", new
String[] {null}, new String[] {"java.lang.String"} );</pre>
and within a server for the list of protocols (if a null or empty
string is passed then all protocols at
the given JNDI server will be listed)
<pre class="programlisting">
Collection lProtocols = (Collection) lLocalServer.invoke(
lFactoryInstance.getObjectName(), "getProtocols", new
String[] {lServer}, new String[] {"java.lang.String"} ); </pre>
</p></li><li><p><a name="N1ff1"></a>
Create a connection to the selected Connector
<pre class="programlisting">
JMXConnector lConnector = (JMXConnector)lLocalServer.invoke(
lFactoryInstance.getObjectName(),"createConnection", new Object[]
{lServer,lProtocol}, new String[]
{"java.lang.String","java.lang.String");
</pre>
</p></li><li><p><a name="N1ffa"></a>
Use the new Connector MBean on the local MBeanServer to get and set the
attributes and perform
operation on the chosen MBeans on the remote MBeanServer.
<pre class="programlisting">
Iterator i = pConnector.queryMBeans( null, null).iterator();
while( i.hasNext() ) {
MBeanInfo info = pConnector.getMBeanInfo( ( (ObjectInstance)
i.next()).getObjectName() );
MBeanAttributeInfo[] aInfos = info.getAttributes();
.
.
. MBeanOperationInfo[] oInfos = info.getOperations();
}</pre>
</p></li><li><p><a name="N2003"></a>
Register a Notification Listener on a remote MBean and wait for
notification events sent from the
remote MBean.
<pre class="programlisting">
Iterator i = pConnector.queryMBeans( null,
nullitemizedlist).iterator();
int j = 0;
while( i.hasNext() ) {
ObjectInstance lBean = (ObjectInstance) i.next();
try {
pConnector.addNotificationListener( lBean.getObjectName(),
(NotificationListener) new Listener(),(NotificationFilter)
null,
new NotSerializableHandback(lBean.getObjectName() + "" + j++
)
); ... </pre>
But when you terminate the connector you have to remove the connection
by using the Connector
Factory to remove all the Notification Listener from the remote
MBeanServer.
<pre class="programlisting">
lLocalServer.invoke( lFactoryInstance.getObjectName(),
"removeConnection", new Object[] {lServer,lProtocol}, new
String[] {"java.lang.String","java.lang.String"} );</pre>
</p></li></ol></div></div></div><div class="section"><a name="N2014"></a><div
class="titlepage"><div><h3 class="title"><a name="N2014"></a><span class="title">ToDo
List</span></h3></div></div><p>This list contains all the stuff to be done to make the
JMX Connector full
fledged:
<div class="itemizedlist"><ul><li><p><a name="N201c"></a>Implement the server
lookup in the Connector Factory to work with JNDI</p></li><li><p><a
name="N2020"></a>Implement the protocol lookup in the Connector Factory to work with
JNDI</p></li><li><p><a name="N2024"></a>Test all to make sure that it works from any
other JVM that the JBoss VM </p></li></ul></div>
</p><p>
This list contains all the stuff to be done around JMX
<div class="itemizedlist"><ul><li><p><a name="N202e"></a>Initiate and start
full fledged JMX Agent project</p></li><li><p><a name="N2032"></a>Design and implement
Relation Service for the JMX Agent</p></li><li><p><a name="N2036"></a>Design and
implement graphic management tool for JBoss</p></li></ul></div>
</p><p>
If anything is wrong or not correct please contact me at
[EMAIL PROTECTED] Also if you want to know more in detail
or have a request for changes in the JMX Connector.
</p></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s07.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch09s24.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s24.html
Index: ch09s24.html
===================================================================
<html><head><title>How To us the Timer MBean</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s08.html" rel="previous" title="JMX Connector Description and HowTo"><link
href="ch09s27.html" rel="next" title="Deployment on JBoss"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch09.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch09s08.html"><img border="0" height="!
65" src="images/prev.gif" width="76"></a><a href="ch09s27.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N2041"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N2041"></a><span class="title">How To us the Timer
MBean</span></h2></div></div><p>Author:
<span class="author">Andreas Shaefer</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N2052"></a><div class="titlepage"><div><h3
class="title"><a name="N2052"></a><span
class="title">Introduction</span></h3></div></div><p>
As part of the JMX specification each JMX compliant server must provide a
timer service to let the users
beeing notified at a certain time, in a certain interval and/or number of
occurrences.
Therefore you can check for mails, check if some change on target (auto
deployer) or notify the client for a
date.</p></div><div class="section"><a name="N205b"></a><div
class="titlepage"><div><h3 class="title"><a name="N205b"></a><span
class="title">Preparation</span></h3></div></div><div
class="itemizedlist"><ul><li><p><a name="N2062"></a>
First you have to add the timer service into the jboss.conf therefore that
the timer service is loaded, registered
at the JMX server and the initialized and started (done by JBoss's Main.java
class). This MLET tag looks like
this:
<pre class="programlisting">
<MLET CODE = "javax.management.timer.Timer"
NAME="DefaultDomain:service=timer"
ARCHIVE="jmxri.jar" CODEBASE="../../lib"> </MLET>
</pre>
</p></li><li><p><a name="N206d"></a>
If you are not using JBoss then to the following:
<div class="orderedlist"><ol type="1"><li><p><a name="N2077"></a>
Create a MBeanServer
<pre class="programlisting">
MBeanServer lServer =
MBeanServerFactory.createMBeanServer();
</pre>
</p></li><li><p><a name="N2080"></a>
Load and register the Timer MBean
<pre class="programlisting">
ObjectInstance lTimer =
lServer.createMBean(
"javax.management.timer.Timer", new
ObjectName( "DefaultDomain",
"service", "timer" ) );
</pre>
</p></li><li><p><a name="N2089"></a>Initialize and start the timer
service
<pre class="programlisting">
lServer.invoke(
lTimer.getObjectName(), "init", new
Object[] {}, new String[] {} );
lServer.invoke(
lTimer.getObjectName(), "start", new
Object[] {}, new String[] {} );
</pre>
</p></li></ol></div>
</p></li><li><p><a name="N2094"></a>Next step is to get the MBeanServer
within your object to work with the timer.</p><p>
This is quite simple if your are in a MBean registered to the same
JMX server because
then you get it when you overwrite preRegister() method.
When you are in the same JVM as the JMX server (in JBoss is any
instance running
within JBoss like EJBs or other classes). Then you can obtain the
MBeanServer throug: </p><pre class="programlisting">
MBeanServer lServer =
MBeanServerFactory.createMBeanServer();</pre><p>
For the rest it is a little bit more complicated. In a Java client
you can use JBoss RMI
connector which will be released as separat package till mid
December 2000. Then you
connect to a MBeanServer through the JMXConnector interface which is
more or less
the same. </p></li><li><p><a name="N20a5"></a>
We are nearly there: now we need the reference to the timer service to work
on it (lServer can be either of
type MBeanServer or JMXConnector): </p><pre class="programlisting">
Set lBeans = lServer.queryMBeans( new ObjectName(
"DefaultDomain", "service", "timer" ), null ); if(
!lBeans.isEmpty() ) { // Should be the first and
only element ObjectInstance lTimer =
(ObjectInstance) lBeans.iterator().next();
</pre></li><li><p><a name="N20b0"></a>
Let's go to work with the timer. Because the timer sends a Notification Event
to the listeners we have to
register first: </p><pre class="programlisting">
lServer.addNotificationListener(
lTimer.getObjectName(), new Listener(), // No
filter null, // No object handback necessary null
);</pre></li><li><p><a name="N20bb"></a>
The Listener (in this case) is an inner class implementing the
NotificationListener interface: </p><pre class="programlisting">
public class Listener implements
NotificationListener { public handleNotification(
Notification pNotification, Object pHandback ) {
// Here to whatever you want or call a method //
in the outer class System.out.println( "You got a
Notification: " + pNotification ); } } </pre></li><li><p><a
name="N20c6"></a>
Finally we are ready to rock and roll. We set a timer event for a particular
time and at this time the
Listener.handleNotification() get called.</p><pre class="programlisting">
Integer lOneMinuteTimer = lServer.invoke(
lTimer.getObjectName(), "addNotification", new
Object[] { "IDoNotKnowWhatTypeIs", "I call you
with this timer once", // No user object null, //
I one minute from now new Date( new
Date().getTime() + Timer.ONE_MINUTE ), }, new
String[] { String.getClass().getName(),
String.getClass().getName(),
Object.getClass().getName(),
Date.getClass.getName() } ); </pre></li><li><p><a name="N20d1"></a>
A timer notification after an Hour from now repeating every minute for ten
times.</p><pre class="programlisting">
Integer lOneHourTimer = lServer.invoke(
lTimer.getObjectName(), "addNotification", new
Object[] { "IDoNotKnowWhatTypeIs", "I call you
with this timer once", // No user object null, //
I one minute from now new Date( new
Date().getTime() + Timer.ONE_HOUR ),
Timer.ONE_MINUTE, 10 }, new String[] {
String.getClass().getName(),
String.getClass().getName(),
Object.getClass().getName(),
Date.getClass.getName(), Long.TYPE.getName(),
Long.TYPE.getName() } ); </pre></li><li><p><a name="N20dc"></a>
If you want to get ride of the second timer then do:</p><pre
class="programlisting">
lServer.invoke( lTimer.getObjectName(), "removeNotification", new
Object[] {
// You could also use the type: "IDoNotKnowWhatTypeIs" lOneHourTimer },
new String[] { // If you remove by type: String.getClass().getName()
Integer.TYPE.getName() } ); </pre></li></ul></div><p>
Now the rest is quite simple. Have a look at the javax.management.Timer class
description and use the
MBeanServer.invoke() method style.</p><p>Attention: When you have basic data
type in the method signature then
you have to use its wrapper class TYPE variable to get its class instead of
using just "long" etc.</p><p>If anything is wrong or not correct please contact me at
[EMAIL PROTECTED] Also if
you want to know more in detail or have a request for further
infos.</p></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s08.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch09s27.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s27.html
Index: ch09s27.html
===================================================================
<html><head><title>Deployment on JBoss</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s24.html" rel="previous" title="How To us the Timer MBean"><link
href="ch09s32.html" rel="next" title="JAAS Based Security in JBoss"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch09.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch09s24.html"><img border="0" height="65" src!
="images/prev.gif" width="76"></a><a href="ch09s32.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N20f3"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N20f3"></a><span class="title">Deployment on
JBoss</span></h2></div></div><p>
Author:
<span class="author">Daniel Schulze</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N2103"></a><div class="titlepage"><div><h3
class="title"><a name="N2103"></a><span
class="title">Introduction</span></h3></div></div><p>
The application deployment on JBoss is managed by the J2eeDeployer MBean. The
J2eeDeployer is able
to deploy ejb.jar packages, webapplication.war packages and j2ee
application.ear packages.
Furthermore he is able to deploy unpacked ejb.jar files for development
purposes.
</p><p>
The deployment is url based, so it is possible to deploy from whatever source
as long as there is
a url handler for that source available in your environment.
(ie. http://somehost/applications/app.ear or
file:///home/user/development/myapp.ear)
</p></div><div class="section"><a name="N210f"></a><div class="titlepage"><div><h3
class="title"><a name="N210f"></a><span class="title">J2EE
Deployer</span></h3></div></div><p>
The J2eeDeployer currently provides 3 methods:
</p><div class="itemizedlist"><ul><li><p><a name="N2119"></a>
void deploy (URL)
this method starts the deployment process for the application this URL points
to. The URL can be a
file: or a http:// or any other type of url your environment is capable to
handle. In case of
deploying a unpacked ejb.jar package the URL type is currently limited to file.
The deployment of an already deployed application (the name of the app is
significant) will result in an
undeployment of this app followed by a redeployment.
</p></li><li><p><a name="N211f"></a>
void undeploy (URL or Application name)
use this to undeploy an application. the parameter can be the URL that was
used to deploy this application or just the name (application name = file name
of the app package or directory name in case of unpacked) of the application.
</p></li><li><p><a name="N2125"></a>
boolean isDeployed (URL or Application name)
use this method to ask for the state of an application. The argument follows
the same rules as for the undeploy method.
</p></li></ul></div><p>
These 3 methods can be used via the web interface of JBoss at port 8082 at the
host JBoss is running on.
</p></div><div class="section"><a name="N2130"></a><div class="titlepage"><div><h3
class="title"><a name="N2130"></a><span class="title">The AutoDeployer as
helper</span></h3></div></div><p>
The AutoDeployer MBean is a helper for the J2eeDeployer to allow doing
administration smoothly via drag and drop
or to automate the redeployment in case of development. He observes the given
directories for changes and calls
the appropriate methods on the J2eeDeployer.
</p><p>
The AutoDeployer observes the timestamps of the application packages or the
timestamp of the META-INF/ejb-jar.xml
file in case of unpacked ejb.jar files.
</p><p>
The AutoDeployer is configured whether static by the MLET configuration or
dynamic by adding urls to watch for
in its web interface (port 8082 at the host JBoss is running on).
</p><p>
In its current version the AutoDeployer supports only local directories to
observe.
</p><p>
To deploy an ejb, web or ear package simply drop it in one of the observed
directories.
To autodeploy an unpacked ejb application, add the base directory of that
application
(base directory = the directory which containes the META-INF directory) to the
AutoDeployers
observed urls.
</p><p>
Note: There is still a misbehavior when the autodeployer thread wins the race
against the copy thread
which modifies a package!
</p></div><div class="section"><a name="N2148"></a><div class="titlepage"><div><h3
class="title"><a name="N2148"></a><span class="title">Creating J2EE
applications</span></h3></div></div><p>
j2ee applications or .ear files are jar archives containing a collection of
ejb, web, client, connector and/or
other library packages. Currently JBoss only supports ejb, web and other
library packages (client and connector
packages are ignored if present).
</p><p>
Other Library packages are class packages that are needed by your application
and are not provided by the j2ee
runtime environment (ie: some xml tools)
</p><p>
This document will only describe the JBoss relevant stuff in creating j2ee
packages for a detailed description
of how to build such applications see the J2EE specification under chapter 8!
</p><p>
First create all ejb, war and library archives you want to put together to
make up your application. Make sure
that all dependencies are solved, means: all classes that are needed by your
application must be contained in
your application (besides the classes that made up the J2EE platform (java
core, javax.transaction,
javax.sql, javax.servlet ...). Its up to you to create an arbitrary directory
structure for your application
to make it easier to maintain. Once you ve created your structure and moved
all files on their place you have
to create a deployment descriptor. This file must reside in the
<your_app_dir>/META-INF directory and must be
named application.xml.
</p><p>
Example:
the content of a simple application.xml file:
</p><pre class="programlisting">
<application>
<display-name>My Application</display-name>
<module>
<web>
<web-uri>web-app.war</web-uri>
<context-root>/myapp</context-root>
</web>
</module>
<module>
<ejb>ejb-app.jar</ejb>
</module>
</application>
</pre><p>
This descriptor describes an application that contains a web application
package (JSPs/Servlets/HTML) and an
ejb application (EJBs). The web applications war package is located at the
root of the .ear file and is named
web-app.war. It will be deployed under the webcontext /myapp. The ejb package
also resides in the applications
root directory and is called ejb-app.jar.
</p><p>
Understanding the shared classloader architecture in JBoss
</p><p>
When an application in JBoss gets deployed, every module will get deployed by
a separate container.
Every container will get its own classloader - this means that a call from one
module to an other must
be an remote call and all parameters must be serialized, because the classes
(even if they are loaded
from the same physical file) are not compatible across container boundaries.
To allow optimized
interaction across container boundaries (local calls with parameter ... per
reference) the classes
that are involved in this communication must be loaded by the same classloader.
</p><p>
In JBoss we achieve this issue with the following classloader architecture:
</p><p>
On deployment one - common - classloader is created. This classloader will get
all archives in its classpath
that are referenced (MANIFEST.MF/Class-Path)by any module contained in this
application.
</p><p>
When afterwards all modules become deployed in their containers, the
classloaders created by these containers
are all children of the common classloader.
</p><p>
Now on runtime the communication between modules across container
boundaries can be optimized when the classes used for the communication are
loaded by the common classloader.
</p><p>
example (continued):
To allow our previous mentioned simple example to make use of the
optimization, we must provide the classes the web
module needs to communicate with the ejb module in an separate third package,
lets call it ejb-client.jar.
This ejb-client.jar archive contains the remote interfaces of the ejbs and
special method parameter types that are
needed for the communication (if any). Now we put this package in the
directory /lib of our application.
</p><p>
To make sure that this package is now loaded by the common classloader, we
reference it from within the web
package by adding a Class-Path: entry to the web packages MANIFEST.MF file
that it looks something like that:
</p><div class="literallayout"> <br>
<tt><br>
Manifest-Version: 1.0<br>
Class-Path: ./lib/ejb-client.jar<br>
</tt><br>
</div><p>
Now you just jar your applications directory, name it
<anyhow>.ear, and drop it in one of JBoss'
autodeploy directories...
</p><p>
the content of our simple applications archive:
</p><div class="literallayout"> <tt><br>
META-INF/<br>
META-INF/MANIFEST.MF<br>
META-INF/application.xml<br>
ejb-app.jar<br>
web-app.war<br>
lib/<br>
lib/ejb-client.jar<br>
</tt><br>
</div></div></div><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s24.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch09s32.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s32.html
Index: ch09s32.html
===================================================================
<html><head><title>JAAS Based Security in JBoss</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s27.html" rel="previous" title="Deployment on JBoss"><link
href="ch09s50.html" rel="next" title="Using JavaMail in JBoss"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch09.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch09s27.html"><img border="0" height="65" src="!
images/prev.gif" width="76"></a><a href="ch09s50.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N219c"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N219c"></a><span class="title">JAAS Based Security in
JBoss</span></h2></div><div><h2 class="subtitle">Custom Security in JBoss Using the
JBossSX Framework</h2></div></div><p>
Author:
<span class="author">Scott Stark</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3
class="title"><a name="N21b1">Note</a></h3><p>The JBossSX framework is a new addition
to JBoss that requires a
cvs snapshot that is latter than March 4 2001, or the JBoss-2.1 final binary.
</p></div>
</p><div class="section"><a name="Introduction"></a><div class="titlepage"><div><h3
class="title"><a name="Introduction"></a><span
class="title">Introduction</span></h3></div></div><p>
This document describes the setting up secured access to JBoss hosted EJBs
for both the standard declarative J2EE security model as well as custom
JAAS Subject based security. It should be sufficient to allow you to configure
a simple security setup for testing and also give you a good start to being
able to inegrate your own custom security implementation into JBoss. For
a more detailed description of the JBossSX framework see the JBossSX
chapter.
</p><div class="itemizedlist"><ul><li><p><a name="N21c3"></a><a
href="ch09s32.html#jaas1">Security Model Overview</a></p></li><li><p><a
name="N21ca"></a><a href="ch09s32.html#jaas2">How to Associate Security With the
Container SecurityInterceptor</a></p></li><li><p><a name="N21d1"></a><a
href="ch09s32.html#jaas3">Using JaasSecurityManager</a></p></li><li><p><a
name="N21d8"></a><a href="ch09s32.html#jaas4">The Session Beans</a></p></li><li><p><a
name="N21df"></a><a href="ch09s32.html#jaas5">Deploying a Bean with
Security</a></p></li></ul></div></div><div class="section"><a name="jaas1"></a><div
class="titlepage"><div><h3 class="title"><a name="jaas1"></a><span
class="title">Security Model Overview</span></h3></div></div><p>
The security model in JBoss is based on the server container architecture's
pluggable method interceptors and the fact that the container factory always
inserts security interceptor(org.jboss.ejb.plugins.SecurityInterceptor).
The SecurityInterceptor delegates the tasks of principal authentication
and and principal role mapping to two different security interfaces;
org.jboss.security.EJBSecurityManager and org.jboss.security.RealmMapping.
JBoss includes a number of sample implementations of both interfaces which
can be found in the org.jboss.security.plugins.samples package.
</p><p>
The default security implementation that comes pre-configured is JMX service
bean and a JAAS based implementation of both interfaces. The JMX bean is
org.jboss.security.plugins.JaasSecurityManagerService and the security
interfaces implementation is org.jboss.security.plugins.JaasSecurityManager.
This document will focus on setting up the JaasSecurityManager via the
JaasSecurityManagerService for a trivial stateless session bean. Once you can
perform the steps documented to secure the example bean, you should be able
to introduce your own production ready security using this example as a
template.
</p></div><div class="section"><a name="jaas2"></a><div class="titlepage"><div><h3
class="title"><a name="jaas2"></a><span class="title">How to Associate Security With
the Container SecurityInterceptor</span></h3></div></div><p>
Ok, so you know that every EJB container in JBoss includes a SecurityInterceptor
that delegates its security checks to a security manager implementation.
How do you choose which implementations a given container uses?
You specify this information via the jboss deployment descriptor.
</p><div class="section"><a name="N2200"></a><div class="titlepage"><div><h4
class="title"><a name="N2200"></a><span class="title">
The JBoss Deployment Descriptor(jboss.xml and standardjboss.xml)
</span></h4></div></div><p>
The JBoss deployment descriptor is the JBoss application specific deployment
configuration file. It describes implementation behavior that is outside of the
EJB spec ejb-jar.xml deployment descriptor. The standardjboss.xml version of the
file is located in ${jboss_home}/conf/conf_name where ${jboss_home} is the
directory into which you have installed the JBoss distribution and conf_name is
the specific runtime configuration that you specify to the run.sh or
run.bat script when starting the server. The default value for conf_name is
"default". The standardjboss.xml specifies the global configuration default
values. You can also specific ejb-jar or j2ee-ear specific jboss.xml descriptors
that override specific or all configuration properties as appropriate for
your application. There are a quite a few configurable properties that can be
set in the file, but all are optional. For all of the possible configuration
elements and their details see the jboss.dtd. We are only concerned with the
three security specific elements: </p><div class="itemizedlist"><ul><li><p><a
name="N2209"></a>security-domain</p></li><li><p><a
name="N220d"></a>role-mapping-manager</p></li><li><p><a
name="N2211"></a>authentication-module</p></li></ul></div><div class="section"><a
name="N2216"></a><div class="titlepage"><div><h5 class="title"><a
name="N2216"></a><span class="title">security-domain</span></h5></div></div><p>
The security-domain element specifies the an implementation of both the
org.jboss.security.RealmMapping and org.jboss.security.EJBSecurityManager
interfaces to use for all J2EE deployment units in the ear or ejb-jar.
The value is specified as the JNDI name where the object is located.
Hence, the security-domain is like a JMS TopicConnectionFactory in
that it is accessed via a JNDI name whose setup is a managed process.
</p></div><div class="section"><a name="N221e"></a><div class="titlepage"><div><h5
class="title"><a name="N221e"></a><span
class="title">role-mapping-manager</span></h5></div></div><p>
The role-mapping-manager element specifies the implementation of the
org.jboss.security.RealmMapping interface that is to be used by the container
SecurityInterceptor. The value is specified as the JNDI name where the object is
located. As far as the container configuration is concerned, an implementation
of org.jboss.security.RealmMapping exists in the JBoss server JNDI namespace
and role-mapping-manager element provides the location.
</p></div><div class="section"><a name="N2226"></a><div class="titlepage"><div><h5
class="title"><a name="N2226"></a><span
class="title">authentication-module</span></h5></div></div><p>
The authentication-module element specifies the implementation of the
org.jboss.security.EJBSecurityManager interface that is to be used by the
container SecurityInterceptor. The value is specified as the JNDI name to where
the object is located, just like the role-mapping-manager.
</p></div><div class="section"><a name="N222e"></a><div class="titlepage"><div><h5
class="title"><a name="N222e"></a><span class="title">Sample
jboss.xml</span></h5></div></div><p>
The sample jboss.xml descriptor we will use is:
</p><div class="figure"><p><a name="jboss.xml"></a><b>Figure 9.1.
jboss.xml</b></p><pre class="programlisting">
<?xml version="1.0"?>
<jboss>
<!-- All bean containers use this security manager by default -->
<security-domain>java:/jaas/other</security-domain> <a
name="jboss.sample.sd"></a><img alt="1" border="0" src="images/callouts/1.png">
<container-configurations>
<!-- Override the role mapping function from that of the
security-domain setting for stateless session beans -->
<container-configuration>
<!-- Use the standardjboss.xml container-name so we only have
to specify the elements we want to override -->
<container-name>Standard Stateless
SessionBean</container-name>
<role-mapping-manager>java:/jaas/session-roles</role-mapping-manager><a
name="jboss.sample.rmm"></a><img alt="2" border="0" src="images/callouts/2.png">
</container-configuration>
</container-configurations>
</jboss>
</pre><div class="calloutlist"><a name="N224a"></a><table border="0"
summary="Callout list"><tr><td align="left" valign="top" width="5%"><a
name="N224c"></a><a href="#jboss.sample.sd"><img alt="1" border="0"
src="images/callouts/1.png"></a> </td><td align="left" valign="top"><p>
Establishes a global security manager via the
<tt>security-domain</tt> element.
</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="N2259"></a><a
href="#jboss.sample.rmm"><img alt="2" border="0" src="images/callouts/2.png"></a>
</td><td align="left" valign="top"><p>
Overrides the global security manager role mapping function for
stateless session beans.
</p></td></tr></table></div></div><p>
Here we are assigning a global security manager for all beans to the
the object located at java:/jaas/other and we are setting a different
role mapping manager for the “Standard Stateless SessionBean”
container. This means that any stateless session beans bundled in the
ear or jar will use the RealmMapper located at java:/jaas/session-roles rather
the the security-domain element setting.
We will see the reason for choosing JNDI names of the form java:/jaas/XXX
over the next couple of sections.
</p></div></div><div class="section"><a name="N226d"></a><div
class="titlepage"><div><h4 class="title"><a name="N226d"></a><span
class="title">Setting Up the Security Manager Implementation in
JNDI</span></h4></div></div><p>
So we have setup the container configuration security elements to specify the
JNDI names where the desired RealmMapping and EJBSecurityManager implementations
are to be obtained from. Now the question is how to bind implementations into the
JBoss server JNDI namespace. The answer is to create a JMX mbean that creates and
binds the desired implementations at server startup. The
JaasSecurityManagerService is an mbean that has been written that we will use to
perform the required setup.
</p><p>
To configure the JaasSecurityManagerService, open the
${jboss_home}/conf/default/jboss.jcml file and look for an entry like:
</p><pre class="programlisting">
<!-- JAAS security manager and realm mapping -->
<mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
name="Security:name=JaasSecurityManager">
<attribute
name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
<attribute
name="SecurityProxyFactoryClassName">org.jboss.security.SubjectSecurityProxyFactory</attribute>
</mbean>
</pre><p>
If it is commented out or does not exist, uncomment or add the entry. The
JaasSecurityManagerService service creates a reference to a JNDI Context at
java:/jaas that lazily binds instances of
org.jboss.security.plugins.JaasSecurityManager
under java:/jaas as they are requested via JNDI. The details of how this happens are
not important(if they are to you, look at the code). All we care about is that with
the
JaasSecurityManagerService setup, any lookup on the JBoss server JNDI InitialContext
using a name of the form java:/jaas/xyz results in an object of type
org.jboss.security.plugins.JaasSecurityManager that has the name xyz. Translated to
code,
this means:
</p><pre class="programlisting">
InitialContext ctx = new InitialContext();
JaasSecurityManager jsm1 = (JaasSecurityManager) ctx.lookup("java:/jaas/xyz");
String securityDomain = jsm1.getSecurityDomain();
// securityDomain == "xyz"
</pre><p>
where <tt>jsm1</tt> is an instance of JaasSecurityManager that was created
using the name "xyz".
We are using this feature to bind a single instance of JaasSecurityManager for
use as both the RealmMapping and EJBSecurityManager implementations in the preceeding
jboss.xml descriptor. We can do this because JaasSecurityManager implements both
interfaces. Now we need to know how we can actually authenticate users and specify
the
roles/identies they possess with a JaasSecurityManager.
</p></div></div><div class="section"><a name="jaas3"></a><div
class="titlepage"><div><h3 class="title"><a name="jaas3"></a><span class="title">Using
JaasSecurityManager</span></h3></div></div><p>
As you would expect, the JaasSecurityManager uses JAAS(Java Authentication and
Authorization Service) to implement both the user authentication and role mapping
function of the RealmMapping and EJBSecurityManager interfaces. It does this by
creating
a JAAS Subject using the javax.security.auth.login.LoginContext mechanism. When
the JaasSecurityManager needs to authenticate a user, it does a JAAS
login using the following programmatic steps:
</p><pre class="programlisting">
Principal principal = ... passed in by SecurityInterceptor;<a
name="jaas.principal"></a><img alt="1" border="0" src="images/callouts/1.png">
Object credential = ... passed in by SecurityInterceptor;<a
name="jaas.credential"></a><img alt="2" border="0" src="images/callouts/2.png">
/* Access the security domain to which the security manager is bound. This is
the xyz component of java:/jaas/xyz name used when defining the security-domain
or role-mapping-manager config elements. */
String name = getSecurityDomain();
CallbackHandler handler = new
org.jboss.security.plugins.SecurityAssociationHandler();
handler.setSecurityInfo(principal, credential);
LoginContext lc = new LoginContext(name, handler);
// Validate principal, credential using the LoginModules configured for 'name'
lc.login();
Subject subject = lc.getSubject();
Set subjectGroups = subject.getPrincipals(Group.class);
// Get the Group whose name is 'Roles'
Group roles = getGroup(subjectGroups, "Roles");
</pre><div class="calloutlist"><a name="N22a4"></a><table border="0"
summary="Callout list"><tr><td align="left" valign="top" width="5%"><a
name="N22a6"></a><a href="#jaas.principal"><img alt="1" border="0"
src="images/callouts/1.png"></a> </td><td align="left" valign="top"><p>
A Principal is an identity object. Often it represents the username string,
but it can be an X509 cert, an http cookie, etc. This is ultimately passed to
the LoginModule chain and so the interpretation of what the Principal is
depends on the configured LoginModules for the security domain.
</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="N22ae"></a><a
href="#jaas.credential"><img alt="2" border="0" src="images/callouts/2.png"></a>
</td><td align="left" valign="top"><p>
The credential is the value the principal is attempting to use to
verify his identity. It could be a password string or one-way has
of the password, a session key or token, etc.
This is ultimately passed to the LoginModule chain
and so the interpretation of what the credential is depends on the
configured LoginModules for the security domain.
</p></td></tr></table></div><p>
If your familiar JAAS, you'll see that the name that was used in the creation of
the JaasSecurityManager correlates with the LoginContext Configuration
name. The JAAS LoginContext object looks to a configuration object that is made up
of named sections that describe the LoginModules that need to be
executed in order to perform authentication. This abstraction allows the
authentication api to be independent of a particular implementation. The
authentication of users and the assignment of user roles comes down to
implementing a javax.security.auth.spi.LoginModule and creating login
configuration entry that correlates with the JaasSecurityManager name.
There exist a number of sample LoginModule implementation in the
org.jboss.security.plugins.samples package. We are going to use the
JaasServerLoginModule to demonstrate the how to configure a LoginModule to
work with the JaasSecurityManager. For your particular application you would
likely need different authentication and role mapping. You can choose another
LoginModule that integrates with your security environment, or implement you own
and then configure it using the same steps we will use.
</p><div class="section"><a name="N22ba"></a><div class="titlepage"><div><h4
class="title"><a name="N22ba"></a><span class="title">Using
JaasServerLoginModule</span></h4></div></div><p>
The JaasServerLoginModule class is a simple properties file based implemention
that uses two files(users.properties and roles.properities) to perform
authentication and role mapping respectively.
</p><div class="section"><a name="N22c1"></a><div class="titlepage"><div><h5
class="title"><a name="N22c1"></a><span
class="title">users.properties</span></h5></div></div><p>
The users.properties file is a java properties formatted file that specifies the
username to password mapping. Its format is:
<pre class="programlisting">
username1=password1
username2=password2
...
</pre>
with one entry per line.
</p></div><div class="section"><a name="N22ce"></a><div class="titlepage"><div><h5
class="title"><a name="N22ce"></a><span
class="title">roles.properties</span></h5></div></div><p>
The roles.properties file is a java properties formatted file that specifies
the username to role(s) mapping. Its format is:
<pre class="programlisting">
username1=role1[,role2,...]
username2=role1
...
</pre>
with one entry per line. If a user has multiple roles they are specified using a
comma separated list.
</p></div><div class="section"><a name="N22db"></a><div class="titlepage"><div><h5
class="title"><a name="N22db"></a><span class="title">The LoginModule Configuration
File</span></h5></div></div><p>
By default JAAS uses a LoginModule configuration file to describe which
LoginModule instances need to be executed during a login. The default
config for the JBoss server is ${jboss_home)/conf/default/auth.conf.
The syntax is:
<pre class="synopsis">
name {
login_module_class_name (required|optional|...)
[options]
;
};
</pre>
See the JAAS documentation for the complete syntax description. In the JBoss server
auth.conf file there should be an entry like 'other' in the figure below.
Also shown is a 'session-roles' entry that we have added that specfies two
login modules.
</p><div class="figure"><p><a name="auth.conf"></a><b>Figure 9.2. The JBoss Server
JAAS Login Config File</b></p><pre class="programlisting">
// The default server login module
other {
// A realistic server login module...
org.jboss.security.plugins.samples.JaasServerLoginModule required;
};
// Augment the JaasServerLoginModule roles with a CallerPrincipal mapping
// using the RolesLoginModule
session-roles {
org.jboss.security.plugins.samples.JaasServerLoginModule required
password-stacking="useFirstPass"
;
org.jboss.security.plugins.samples.RolesLoginModule required
;
};
</pre></div><p>
This indicates that the JaasServerLoginModule we want to use is setup for
the configuration named 'other'. This name also matches name of the
security domain portion of the JNDI name java:/jaas/other, which is what
we want. Recall that we specified an different security domain for
the role-mapping-manager element for the stateless session bean container
configuration. We used java:/jaas/session-roles. When a user accesses a
stateless session bean, they will be authenticated by the login modules
configured for the 'session-roles' domain. Referring to Figure 1 shows
that both the JaasServerLoginModule and RolesLoginModule login modules
will be executed for perform the authentication in this domain.
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3
class="title"><a name="N22f7">Note</a></h3>The configuration named 'other' is used
JAAS whenever it can't find
an entry matching the name passed to the LoginContext constructor. So
if we had used a JNDI name like java:/jaas/global as the security-domain
configuration element, we would still be using the 'other' login configuration
entry unless there also happened to be a 'global' entry.
</div>
</p></div></div><p>
We have now touched on all of the JBoss security related elements we need to
configure to secure the deployment of EJBs.
Let's now put together two simple session beans that we will secure to
demonstrate how to use what we have gone over.
</p></div><div class="section"><a name="jaas4"></a><div class="titlepage"><div><h3
class="title"><a name="jaas4"></a><span class="title">The Session
Beans</span></h3></div></div><p>
The following figures give the code listings for the the home, remote
and bean classes for the simple stateless and stateful session beans we
are going to secure, along with a simple client that accesses instances
of the session beans.
</p><div class="figure"><p><a name="Session.java"></a><b>Figure 9.3. The Session
Beans Remote Interface</b></p><pre class="programlisting">
import javax.ejb.*;
import java.rmi.*;
public interface Session extends EJBObject
{
public String echo(String arg) throws RemoteException;
}
</pre></div><div class="figure"><p><a name="SessionHome.java"></a><b>Figure 9.4. The
Session Beans Home Interface</b></p><pre class="programlisting">
import javax.ejb.*;
import java.rmi.*;
public interface SessionHome extends EJBHome
{
public Session create() throws RemoteException, CreateException;
}
</pre></div><div class="figure"><p><a name="StatelessSessionBean.java"></a><b>Figure
9.5. The Stateless Session Bean</b></p><pre class="programlisting">
import java.rmi.RemoteException;
import java.security.Principal;
import javax.ejb.*;
/**
@ejbHome: SessionHome
@ejbRemote: Session
*/
public class StatelessSessionBean implements SessionBean
{
private SessionContext sessionContext;
public void ejbCreate() throws RemoteException, CreateException
{
System.out.println("StatelessSessionBean.ejbCreate() called");
}
public void ejbActivate() throws RemoteException
{
System.out.println("StatelessSessionBean.ejbActivate() called");
}
public void ejbPassivate() throws RemoteException
{
System.out.println("StatelessSessionBean.ejbPassivate() called");
}
public void ejbRemove() throws RemoteException
{
System.out.println("StatelessSessionBean.ejbRemove() called");
}
public void setSessionContext(SessionContext context) throws RemoteException
{
sessionContext = context;
}
public String echo(String arg)
{
System.out.println("StatelessSessionBean.echo, arg="+arg);
Principal p = sessionContext.getCallerPrincipal();
System.out.println("StatelessSessionBean.echo, callerPrincipal="+p);
return arg;
}
}
</pre></div><div class="figure"><p><a name="StatefulSessionBean.java"></a><b>Figure
9.6. The Stateful Session Bean</b></p><pre class="programlisting">
import java.rmi.RemoteException;
import java.security.Principal;
import javax.ejb.*;
/**
@ejbHome: SessionHome
@ejbRemote: Session
*/
public class StatefulSessionBean implements SessionBean
{
private SessionContext sessionContext;
public void ejbCreate() throws RemoteException, CreateException
{
System.out.println("StatefulSessionBean.ejbCreate() called");
}
public void ejbActivate() throws RemoteException
{
System.out.println("StatelessSessionBean.ejbActivate() called");
}
public void ejbPassivate() throws RemoteException
{
System.out.println("StatefulSessionBean.ejbPassivate() called");
}
public void ejbRemove() throws RemoteException
{
System.out.println("StatefulSessionBean.ejbRemove() called");
}
public void setSessionContext(SessionContext context) throws RemoteException
{
sessionContext = context;
}
public String echo(String arg)
{
System.out.println("StatefulSessionBean.echo, arg="+arg);
Principal p = sessionContext.getCallerPrincipal();
System.out.println("StatefulSessionBean.echo, callerPrincipal="+p);
return arg;
}
}
</pre></div><div class="figure"><p><a name="ejb-jar.xml"></a><b>Figure 9.7. The
ejb-jar Deployment Descriptor</b></p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans
1.1//EN"
"http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">
<ejb-jar>
<display-name>SecurityTests</display-name>
<enterprise-beans>
<session>
<description>A trival stateless session echo
bean</description>
<ejb-name>StatelessSession</ejb-name>
<home>SessionHome</home>
<remote>Session</remote>
<ejb-class>StatelessSessionBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
<session>
<description>A trival stateful session echo
bean</description>
<ejb-name>StatefulSession</ejb-name>
<home>SessionHome</home>
<remote>Session</remote>
<ejb-class>StatelessSessionBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<security-role>
<role-name>Echo</role-name>
</security-role>
<method-permission>
<role-name>Echo</role-name>
<method>
<ejb-name>StatelessSession</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
<method-permission>
<role-name>Echo</role-name>
<method>
<ejb-name>StatefulSession</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
</assembly-descriptor>
</ejb-jar>
</pre></div><div class="figure"><p><a name="SessionClient.java"></a><b>Figure 9.8.
The Client</b></p><pre class="programlisting">
import java.io.IOException;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
/** Run with -Djava.security.auth.login.config=${jboss_home}/client/auth.conf
where ${jboss_home} is the location of your JBoss distribution.
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class SessionClient
{
static class AppCallbackHandler implements CallbackHandler
{
private String username;
private char[] password;
public AppCallbackHandler(String username, char[] password)
{
this.username = username;
this.password = password;
}
public void handle(Callback[] callbacks) throws
java.io.IOException, UnsupportedCallbackException
{
for (int i = 0; i < callbacks.length; i++)
{
if (callbacks[i] instanceof NameCallback)
{
NameCallback nc = (NameCallback)callbacks[i];
nc.setName(username);
}
else if (callbacks[i] instanceof PasswordCallback)
{
PasswordCallback pc = (PasswordCallback)callbacks[i];
pc.setPassword(password);
}
else
{
throw new UnsupportedCallbackException(callbacks[i],
"Unrecognized Callback");
}
}
}
}
public static void main(String args[]) throws Exception
{
try
{
if( args.length != 2 )
throw new IllegalArgumentException("Usage: username password");
String name = args[0];
char[] password = args[1].toCharArray();
AppCallbackHandler handler = new AppCallbackHandler(name, password);
LoginContext lc = new LoginContext("TestClient", handler);
System.out.println("Created LoginContext");
lc.login();
}
catch (LoginException le)
{
System.out.println("Login failed");
le.printStackTrace();
}
try
{
InitialContext iniContext = new InitialContext();
SessionHome home = (SessionHome) iniContext.lookup("StatelessSession");
System.out.println("Found StatelessSessionHome");
Session bean = home.create();
System.out.println("Created StatelessSession");
System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
bean.remove();
home = (SessionHome) iniContext.lookup("StatefulSession");
System.out.println("Found StatefulSessionHome");
bean = home.create();
System.out.println("Created StatefulSession");
System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
bean.remove();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
</pre></div><p>
The session beans are trivial and both the stateless and stateful bean use the
same home and remote interfaces. The client is also trivial except for the use
of a JAAS LoginContext and CallbackHandler implementation. This is how a client
establishes the username and password that is sent to jboss.
Now, finally let's put everything together and deploy the session bean.
</p></div><div class="section"><a name="jaas5"></a><div class="titlepage"><div><h3
class="title"><a name="jaas5"></a><span class="title">Deploying a Bean with
Security</span></h3></div></div><p>
This section details the procedure for building, deploying and testing
the secured ejb-jar.
The steps I'll go through are on a windows 2000 box using the cygwin port
of the GNU tools, so most things will look like unix with the exception of
the ';' path separator used in the java classpath.
</p><div class="procedure"><p><b>Deployment Steps</b></p><ol><li><p>Compile the
session bean and client
</p><ol><li><p>Save all of the files presented in the figures of this document:
<div class="itemizedlist"><ul><li><p><a name="N2382"></a><a
href="ch09s32.html#jboss.xml">jboss.xml</a></p></li><li><p><a name="N2389"></a><a
href="ch09s32.html#auth.conf">auth.conf</a></p></li><li><p><a name="N2390"></a><a
href="ch09s32.html#Session.java">Session.java</a></p></li><li><p><a
name="N2397"></a><a
href="ch09s32.html#SessionHome.java">SessionHome.java</a></p></li><li><p><a
name="N239e"></a><a
href="ch09s32.html#StatelessSessionBean.java">StatelessSessionBean.java</a></p></li><li><p><a
name="N23a5"></a><a
href="ch09s32.html#StatefulSessionBean.java">StatefulSessionBean.java</a></p></li><li><p><a
name="N23ac"></a><a href="ch09s32.html#ejb-jar.xml">ejb-jar.xml</a></p></li><li><p><a
name="N23b3"></a><a
href="ch09s32.html#SessionClient.java">SessionClient.java</a></p></li></ul></div>
This will give you the following 8 files:
</p><div class="literallayout"><br>
<b><br>
howto-jaas 1053>ls<br>
Session.java StatefulSessionBean.java ejb-jar.xml<br>
SessionClient.java StatelessSessionBean.java jboss.xml<br>
SessionHome.java auth.conf<br>
</b></div></li><li><p>Create a users.properties and
roles.properties with the following
data in each file: </p><div class="literallayout"><br>
<b><br>
bash 1090>cat users.properties<br>
scott=echoman<br>
stark=javaman<br>
bash 1091>cat roles.properties<br>
scott=Echo<br>
stark=Java,Coder<br>
scott.CallerPrincipal=caller_scott<br>
stark.CallerPrincipal=caller_stark<br>
bash 1092><br>
<br>
</b></div></li><li><p>
Next, setup the classpath as follows by substituting the value for jboss_home
appropriate for your system. For example, I'm using jboss_home is a
fresh build from cvs and jboss_home=/tmp/cvs/jboss/dist.
</p><div class="literallayout"><b><br>
howto-jaas 1055>export jboss_home=/tmp/cvs/jboss/dist<br>
howto-jaas 1056>export CLASSPATH="${jboss_home}/client/jaas.jar"<br>
howto-jaas 1057>CLASSPATH="${CLASSPATH};${jboss_home}/client/ejb.jar"<br>
howto-jaas 1058>CLASSPATH="${CLASSPATH};${jboss_home}/client/jnp-client.jar"<br>
howto-jaas 1059>CLASSPATH="${CLASSPATH};${jboss_home}/client/jboss-client.jar"<br>
howto-jaas 1060>CLASSPATH="${CLASSPATH};${jboss_home}/client/jbosssx-client.jar"<br>
howto-jaas 1061>CLASSPATH="${CLASSPATH};."<br>
howto-jaas 1062>echo $CLASSPATH<br>
/tmp/cvs/jboss/dist/client/jaas.jar;/tmp/cvs/jboss/dist/client/ejb.jar;/tmp/cvs/jboss/dist/client/jnp-client.jar;/tmp/cvs/jboss/dist/client/jboss-client.jar;/tmp/cvs/jboss/dist/client/jbosssx-client.jar;.<br>
</b></div></li><li><p>Next, compile all of the source.
</p><div class="literallayout"><b><br>
howto-jaas 1087>javac -g *.java<br>
howto-jaas 1088>ls<br>
Session.class StatefulSessionBean.java<br>
Session.java StatelessSessionBean.class<br>
SessionClient$AppCallbackHandler.class StatelessSessionBean.java<br>
SessionClient.class auth.conf<br>
SessionClient.java ejb-jar.xml<br>
SessionHome.class jboss.xml<br>
SessionHome.java roles.properties<br>
StatefulSessionBean.class users.properties<br>
</b></div></li></ol></li><li><p>Create the session bean
ejb-jar with the ejb-jar.xml and jboss.xml security
elements</p><p>Next, create the session bean jar as follows:</p><ol><li><div
class="literallayout"><b><br>
howto-jaas 1089>mkdir META-INF<br>
howto-jaas 1090>mv *.xml META-INF<br>
howto-jaas 1091>jar -cf $jboss_home/deploy/ssbean.jar Session.class SessionHome.class StatefulSessionBean.class StatelessSessionBean.class roles.properties users.properties META-INF<br>
howto-jaas 1092>jar -tf $jboss_home/deploy/ssbean.jar<br>
META-INF/<br>
META-INF/MANIFEST.MF<br>
Session.class<br>
SessionHome.class<br>
StatefulSessionBean.class<br>
StatelessSessionBean.class<br>
roles.properties<br>
users.properties<br>
META-INF/ejb-jar.xml<br>
META-INF/jboss.xml<br>
</b></div></li></ol></li><li><p>Deploy the session bean jar.
We already deployed the session bean jar by
jaring the files to the $jboss_home/deploy directory. The deploy directory is
where the JBoss server's autodeploy process looks for ejb jars.
</p></li><li><p>Edit the JBoss server jboss.jcml and auth.conf files.
These files need to be setup as described earlier.</p><ol><li><p>The
$jboss_home/conf/default/jboss.jcml file needs to have the
JaasSecurityManagerService mbean element setup as follows:</p><pre
class="programlisting">
<!-- JAAS security manager and realm mapping -->
<mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
name="Secuty:name=JaasSecurityManager">
<attribute
name="SecurityManagerClassName">org.jboss.security.plugins.JaasSerityManager</attribute>
</mbean>
</pre></li><li><p>Copy the auth.conf that you created from Figure <a
href="ch09s32.html#auth.conf">Figure 9.2.</a> to
$jboss_home/conf/default and overwrite the existing file.</p><div
class="literallayout"><tt><br>
howto-jaas 1103>cp auth.conf $jboss_home/conf/default<br>
cp: overwrite '/tmp/cvs/jboss/dist/conf/default/auth.conf'? y<br>
</tt></div></li></ol></li><li><p>Start the JBoss server.
Go to the $jboss_home/bin directory and use the run.sh or run.bat script as
appropriate for you system to start the JBoss server. You will see a good
deal of ouput on your console. Below is some console output and I have
emphasized the session bean deployment output.
</p><div class="literallayout"><tt><br>
bin 608>run.bat<br>
Using configuration "default"<br>
[Info] Java version: 1.3.0_01,Sun Microsystems Inc.<br>
[Info] Java VM: Java HotSpot(TM) Client VM 1.3.0_01,Sun Microsystems Inc.<br>
[Info] System: Windows 2000 5.0,x86<br>
[Shutdown] Shutdown hook added<br>
[Service Control] Registered with server<br>
[Service Control] Initializing 24 MBeans<br>
...<br>
<i><br>
[Auto deploy] Starting<br>
[Auto deploy] Watching D:\tmp\cvs\jboss\dist\deploy<br>
[Auto deploy] Auto deploy of file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar<br>
[J2EE Deployer Default] Deploy J2EE application: file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar<br>
[J2EE Deployer Default] Create application ssbean.jar<br>
[J2EE Deployer Default] install module ssbean.jar<br>
[Container factory] Deploying:file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar<br>
[Verifier] Verifying file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar/ejb1001.jar<br>
[Container factory] Deploying StatelessSession<br>
[Container factory] lookup securityManager name: java:/jaas/other<br>
[Container factory] JAAS.Created securityMgr=org.jboss.security.plugins.JaasSecurityManager@5f1832<br>
[Container factory] JAAS.setCachePolicy, c=null<br>
[Container factory] JAAS.Added other, org.jboss.security.plugins.JaasSecurityManager@5f1832 to map<br>
[Container factory] JAAS.Created securityMgr=org.jboss.security.plugins.JaasSecurityManager@2d8659<br>
[Container factory] JAAS.setCachePolicy, c=null<br>
[Container factory] JAAS.Added session-roles, org.jboss.security.plugins.JaasSecurityManager@2d8659 to map<br>
[Container factory] Deploying StatefulSession<br>
[Container factory] lookup securityManager name: java:/jaas/other<br>
[Bean Cache] Cache policy scheduler started<br>
[Container factory] Deployed application: file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar<br>
[J2EE Deployer Default] J2EE application: file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar is deployed.<br>
</i><br>
...<br>
[Service Control] Started 24 services<br>
[Default] JBoss PRE-2.1 Started in 0m:10s<br>
</tt></div></li><li><p>Setup client env and test access to the session bean</p><p>
At this point the session bean is deployed and it should only be accessible by
users with a role of 'Echo', and we have one user with a username 'scott'
and a password 'echoman' that has this role. We have another user with a
username 'stark' and a password 'javaman' that should not be able to
acccess the session bean because he does not have the required role. We
need to setup the client env and run the client to test this.
</p><ol><li><p>
We need one final bit of information in order for the client to find the JBoss
server
JNDI name service. Since we are using a no arg InitialContext in the
client, we need a jndi.properties file in our classpath(or we need to specify all
required properities on the command line). For JBoss, the jndi.properties
file should look like the following for the server running on the localhost with
the default name service port: </p><div class="literallayout"><tt><br>
bash 1108>cat jndi.properties<br>
# JNDI initial context properties for jboss app server<br>
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory<br>
java.naming.provider.url=localhost<br>
java.naming.factory.url.pkgs=org.jboss.naming<br>
</tt></div><p>
Create this file in the same directory as your SessionClient.java file since
this directory is on the classpath we setup earlier.</p></li><li><p>Now, run the
client as user scott and specify the location of
the JBoss client side JAAS login configuration file as follows: </p><div
class="literallayout"><tt><br>
--- Client:<br>
howto-jaas 1133>java -Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient scott echoman<br>
Created LoginContext<br>
Found StatelessSessionHome<br>
Created StatelessSession<br>
Bean.echo('Hello') -> Hello<br>
Found StatefulSessionHome<br>
Created StatefulSession<br>
Bean.echo('Hello') -> Hello<br>
<br>
--- Server console:<br>
[JAASSecurity] User 'scott' authenticated.<br>
[JAASSecurity] User 'scott' authenticated.<br>
[StatelessSession] StatelessSessionBean.ejbCreate() called<br>
[StatelessSession] StatelessSessionBean.echo, arg=Hello<br>
[StatelessSession] StatelessSessionBean.echo, callerPrincipal=caller_scott<br>
[StatefulSession] StatelessSessionBean.ejbCreate() called<br>
[StatefulSession] StatelessSessionBean.echo, arg=Hello<br>
[StatefulSession] StatelessSessionBean.echo, callerPrincipal=scott<br>
[StatefulSession] StatelessSessionBean.ejbRemove() called<br>
</tt></div></li><li><p>Ok, so that succeed as desired. Now
we need to make sure that unauthorized
users are actually denied access. This time run as user stark:</p><div
class="literallayout"><tt><br>
--- Client:<br>
howto-jaas 1135>java -Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient stark javaman<br>
Created LoginContext<br>
Found StatelessSessionHome<br>
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:<br>
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:<br>
<br>
java.lang.SecurityException: Illegal access exception<br>
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:<br>
java.lang.SecurityException: Illegal access exception<br>
java.lang.SecurityException: Illegal access exception<br>
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:245)<br>
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:220)<br>
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:122)<br>
at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invokeHome(Unknown Source)<br>
at org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:248)<br>
at $Proxy0.create(Unknown Source)<br>
at SessionClient.main(SessionClient.java:74)<br>
<br>
--- Server console:<br>
[JAASSecurity] User 'stark' authenticated.<br>
[JAASSecurity] User 'stark' authenticated.<br>
[StatelessSession] Illegal access, principal=stark<br>
</tt></div></li><li><p>Alright, seems secure. Let's try user
scott with an invalid password: </p><div class="literallayout"><tt><br>
--- Client:<br>
howto-jaas 1137>java -Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient scott badpass<br>
Created LoginContext<br>
Found StatelessSessionHome<br>
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:<br>
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:<br>
<br>
java.lang.SecurityException: Authentication exception<br>
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:<br>
java.lang.SecurityException: Authentication exception<br>
java.lang.SecurityException: Authentication exception<br>
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:245)<br>
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:220)<br>
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:122)<br>
at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invokeHome(Unknown Source)<br>
at org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:248)<br>
at $Proxy0.create(Unknown Source)<br>
at SessionClient.main(SessionClient.java:74)<br>
<br>
--- Server console:<br>
[JAASSecurity] Bad password.<br>
[StatelessSession] javax.security.auth.login.FailedLoginException: Password Incorrect/Password Required<br>
[StatelessSession] at org.jboss.security.plugins.AbstractServerLoginModule.login(AbstractServerLoginModule.java:141)<br>
[StatelessSession] at org.jboss.security.plugins.samples.JaasServerLoginModule.login(JaasServerLoginModule.java:94)<br>
[StatelessSession] at java.lang.reflect.Method.invoke(Native Method)<br>
[StatelessSession] at javax.security.auth.login.LoginContext.invoke(LoginContext.java:595)<br>
[StatelessSession] at javax.security.auth.login.LoginContext.access$000(LoginContext.java:125)<br>
[StatelessSession] at javax.security.auth.login.LoginContext$3.run(LoginContext.java:531)<br>
[StatelessSession] at java.security.AccessController.doPrivileged(Native Method)<br>
[StatelessSession] at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:528)<br>
[StatelessSession] at javax.security.auth.login.LoginContext.login(LoginContext.java:449)<br>
[StatelessSession] at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:291)<br>
[StatelessSession] at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:260)<br>
[StatelessSession] at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:149)<br>
[StatelessSession] at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:196)<br>
[StatelessSession] at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:131)<br>
[StatelessSession] at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:106)<br>
[StatelessSession] at org.jboss.ejb.StatelessSessionContainer.invokeHome(StatelessSessionContainer.java:253)<br>
[StatelessSession] at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invokeHome(JRMPContainerInvoker.java:358)<br>
[StatelessSession] at java.lang.reflect.Method.invoke(Native Method)<br>
[StatelessSession] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)<br>
[StatelessSession] at sun.rmi.transport.Transport$1.run(Transport.java:142)<br>
[StatelessSession] at java.security.AccessController.doPrivileged(Native Method)<br>
[StatelessSession] at sun.rmi.transport.Transport.serviceCall(Transport.java:139)<br>
[StatelessSession] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)<br>
[StatelessSession] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)<br>
[StatelessSession] at java.lang.Thread.run(Thread.java:484)<br>
[StatelessSession] Authentication exception, principal=scott<br>
</tt></div></li></ol></li></ol></div></div><div
class="section"><a name="N24c9"></a><div class="titlepage"><div><h3 class="title"><a
name="N24c9"></a><span class="title">Wrap Up</span></h3></div></div><p>This has been
an introduction to the steps required to enable security
for EJB containers. Support for more advanced customization of security is
documented in the JBossSX chapter.
</p></div></div><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s27.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch09s50.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s50.html
Index: ch09s50.html
===================================================================
<html><head><title>Using JavaMail in JBoss</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s32.html" rel="previous" title="JAAS Based Security in JBoss"><link
href="ch09s53.html" rel="next" title="How to Run JBoss in JBuilder's
Debugger"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s32.html"><img border="!
0" height="65" src="images/prev.gif" width="76"></a><a href="ch09s53.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N24d2"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N24d2"></a><span class="title">Using JavaMail in JBoss</span></h2></div></div><p>
<span class="author">Michel de Groot</span>
<tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N24e2"></a><div class="titlepage"><div><h3
class="title"><a name="N24e2"></a><span
class="title">Introduction</span></h3></div></div><p>
JBoss has a built-in implementation of the JavaMail API. You can use this
service from inside and outside EJBs. We
describe here how to use the service. </p></div><div class="section"><a
name="N24ea"></a><div class="titlepage"><div><h3 class="title"><a
name="N24ea"></a><span class="title">Installation &
Configuration</span></h3></div></div><div class="orderedlist"><ol type="1"><li><p><a
name="N24f4"></a>Edit conf/<yourconfig>/jboss.jcml and find Mail
Service MBean (almost on the bottom).</p><p>
a) Replace the User and Password attributes values with the user name and
password used to connect to your
mail server. You can find these values in your mail program. The mail
service will use this account to send mails,
so be sure that this mail account works properly (test it with your mail
program for example).</p><p>
b) Replace the ConfigurationFile attribute value with the file containing
the mail settings. Default is
"mail.properties", which is also in the conf/<yourconfig>
directory. This file will be edited in step 2.</p><p>
c) Replace the JNDIName attribute value with the JNDI name for your mail
session. The default is "Mail". This
JNDI name will be used in jboss.xml to identify the resource. This is
explained in more detail in step 4.</p></li><li><p><a name="N2502"></a>Edit the mail
properties file you identified in step 1b. By
default, this is conf/<yourconfig>/mail.properties.</p><p>
Edit the following lines:
<pre class="programlisting">
mail.user = sa005697 // the user to connect with; same as in step 1a
mail.pop3.host = pop3.wolmail.nl // the pop host to store the mail
on
mail.smtp.host = smtp.wolmail.nl // the smtp host to send the mail
to
mail.from = [EMAIL PROTECTED] // the 'from' field that is
filled in by default in e-mails
</pre>
</p><p>
You can find most value in your mail program. You might want to inspect
the JavaMail specification for more
details.</p><p>
The last line, mail.debug, should be set to 'true' for now. This will
provide you with verbose debugging
information. Once you have everything running correctly, you can set it
to false.</p></li><li><p><a name="N2515"></a>Edit the ejb-jar.xml of the EJB that
uses the mail service.
In your EJB, specify a <resource-ref> like this:
<pre class="programlisting">
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Mailer</ejb-name>
<home>some.package.MailerHome</home>
<remote>some.package.Mailer</remote>
<ejb-class>some.package.MailerEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>mail/MyMail</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</session>
</enterprise-beans>
</ejb-jar>
</pre>
</p><p>
This will tell the EJB container that the EJB uses a javax.mail.Session
resource named mail/MyMail and that
authorization is container managed.</p><p>
You can change the name if you like, but be sure to use the same name in
step 6, in the code example. </p></li><li><p><a name="N2525"></a>Edit the jboss.xml
of the EJB that uses the mail service.
If you don't have this file, create it and place it in the
same directory as the ejb-jar.xml of the EJB. This file is JBoss specific
and tells JBoss how to map the mail
resource to the mail service provider in JBoss.
In this file, specify a <resource-manager> like this:
<pre class="programlisting">
<jboss>
<resource-managers>
<resource-manager>
<res-name>mail/MyMail</res-name>
<res-jndi-name>Mail</res-jndi-name>
</resource-manager>
</resource-managers>
</jboss>
</pre>
</p><p>
The name that you specify here is the name that you specified in step 3.
The JNDI name that you specify here is
the name that you specified in step 1c.</p></li><li><p><a name="N2532"></a>Edit
the bin/run.bat file of your JBoss installation.
Include ../lib/ext/mail.jar and ../lib/ext/activation.jar in the
classpath explicitly. This assumes that you start JBoss from the bin
directory. If not, you should modify the paths
to the jars accordingly.</p><p>
TO BE IMPROVED: This step should not be required; both mail.jar and
activation.jar are correctly found during
the ClassPathExtension scan, but somehow their classes cannot be found
later. Maybe something missing in the
manifest.mf files? </p></li><li><p><a name="N253a"></a>Code example
This code example assumes that you are working from inside a JBoss
container. For example, this is the case if
the code is placed in a JBoss managed SessionBean.</p><p>
TO BE IMPROVED: This code example does not use PortableRemoteObject,
because I could not locate it
anywhere in the JBoss jars. The code will work without it on JBoss. It
should be used however to make the
code more portable. I'm also not sure what happens in a distributed JBoss
installation. </p><pre class="programlisting">
import java.util.Date;
import javax.ejb.SessionBean;
import javax.naming.InitialContext;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.InternetAddress;
import javax.mail.Transport;
import javax.mail.Address;
import javax.mail.Message;
//import javax.rmi.PortableRemoteObject;
public class SomeEJB implements SessionBean {
public void ejbCreate() {}
public void ejbPostCreate() {}
public void sendMails() throws java.rmi.RemoteException {
Session session = null;
try {
session = (Session)new
InitialContext().lookup("java:comp/env/mail/MyMail");
//session = (Session)PortableRemoteObject.narrow(
// new
InitialContext().lookup("java:comp/env/mail/MyMail"), Session.class);
} catch (javax.naming.NamingException e) {
e.printStackTrace();
}
try {
MimeMessage m = new MimeMessage(session);
m.setFrom();
Address[] to = new InternetAddress[] {new
InternetAddress("<your_email_adres@<your_provider>.<your_extension>");
m.setRecipients(Message.RecipientType.TO, to);
m.setSubject("JavaMail Test");
m.setSentDate(new Date());
m.setContent("Test from inside EJB Using JBoss",
"text/plain");
Transport.send(m);
} catch (javax.mail.MessagingException e) {
e.printStackTrace();
}
}
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbRemove() {}
public void setSessionContext(javax.ejb.SessionContext ec) {}
}
</pre></li><li><p><a name="N2547"></a>Using the JavaMail service with mail
servers that require
POP authentication before SMTP
You can do this by using: </p><pre class="programlisting">
import javax.mail.Store;
Store s = session.getStore();
s.connect(); // POP authentication
Transport.send(m);
</pre></li></ol></div></div></div><table border="0" cellpadding="0"
cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img height="79"
src="images/gbar.gif" width="432"></td><td align="right" background="images/gbar.gif"
rowspan="2" valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s32.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a><a href="ch09s53.html"><img border="0"
height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s53.html
Index: ch09s53.html
===================================================================
<html><head><title>How to Run JBoss in JBuilder's Debugger</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s50.html" rel="previous" title="Using JavaMail in JBoss"><link
href="ch09s56.html" rel="next" title="EJX/AWT Development HowTo"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch09.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch09s50.html"><img border="0" !
height="65" src="images/prev.gif" width="76"></a><a href="ch09s56.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N2554"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N2554"></a><span class="title">How to Run JBoss in JBuilder's
Debugger</span></h2></div></div><div class="section"><a name="N2558"></a><div
class="titlepage"><div><h3 class="title"><a name="N2558"></a><span
class="title">JBuilder Foundation 3.5</span></h3></div></div><p>
With each of these, replace <JBOSS-HOME> with the location of your JBoss
directory, for example, C:\jboss.</p><div class="orderedlist"><ol type="1"><li><p><a
name="N2565"></a>Launch JBuilder.</p></li><li><p><a name="N2569"></a>Go to
Project|Properties, click the Paths tab, and make sure you're using JDK 1.3 as your
JDK. To have 1.3 available, you
may need to add it or change your default JDK. First install JDK 1.3 (from
Sun) on your PC, then point JBuilder to it by
clicking "new" or "edit" in the Select a JDK dialog.</p></li><li><p><a
name="N256d"></a>On the Paths tab, go to the Required Libraries tab, click "add" and
then "new" to create a new one, and call it "JBoss Server"
(or something similar). Add the following .jar file:
<JBOSS-HOME>\bin\run.jar </p></li><li><p><a name="N2571"></a>Click
OK on the Edit library dialog, then OK on the Select one or more libraries dialog,
which should add the new library to
your project. The library will now be available to other projects as
well.</p></li><li><p><a name="N2575"></a>Go to the Run tab of the Project Properties
dialog. On the Application tab, set the main class to org.jboss.Main. Note that this
is project-specific and will need to be done for each project running JBoss.
</p></li><li><p><a name="N2579"></a>On the Run tab, under "VM Parameters", add the
following (again, for each project):
-Duser.dir=<JBOSS-HOME> </p></li><li><p><a name="N257d"></a>Click
OK and close JBuilder.</p></li><li><p><a name="N2581"></a>Create a copy of your
JBuilder shortcut (in Win98, it should be in C:\WINDOWS\Start Menu\Programs\JBuilder
3.5). Rename
the copy to something appropriate, such as "JBuilder with JBoss working
directory". </p></li><li><p><a name="N2585"></a>Edit the shortcut's properties by
right-clicking and choosing properties. Change the "Start in" folder to
<JBOSS-HOME>\bin\. Click OK. </p></li><li><p><a name="N2589"></a>To run
or debug JBoss within JBuilder, first use the modified shortcut to launch JBuilder,
then open your project as normal and
select Run|Run Project or Run|Debug Project. </p></li><li><p><a
name="N258d"></a>To debug EJBs within this setup, first build and deploy them in
<JBOSS-HOME>\deploy as you would normally. Then set
breakpoints in your EJB code and debug the project using org.jboss.Main as the
main class using the instructions above. </p></li></ol></div><p>
NOTE: When running JBoss within JBuilder, it will launch an empty console window
with "java" as the title. I'm not sure why this is,
but it appears to have some relation to Hypersonic SQL. You will probably need to
close this window manually after stopping JBoss.
</p></div><div class="section"><a name="N2596"></a><div class="titlepage"><div><h3
class="title"><a name="N2596"></a><span class="title">JBuilder
4</span></h3></div></div><p>
Author: Peter Henderson
</p><div class="orderedlist"><ol type="1"><li><p><a name="N25a3"></a>Project
Properties. (Project properties/paths)
Set the working directory to the JBoss bin dir. For example:
C:/jboss_tomcat/jboss-2.0-FINAL/bin</p></li><li><p><a name="N25a7"></a>Set
VM parameters. (Project properties/run)
-classic -Dtomcat.home=C:\jboss_tomcat\tomcat-3.2-b7
-Duser.dir=C:\jboss_tomcat\jboss-2.0-FINAL/bin </p></li><li><p><a name="N25ab"></a>Set
Main class
Set main class to org.jboss.Main </p></li><li><p><a name="N25af"></a>Create a
JBoss Server Library. (Project properties/required libs) </p><p>Add: </p><pre
class="programlisting">
/jboss_tomcat/jboss-2.0-FINAL/bin/run.jar
/jboss_tomcat/jboss-2.0-FINAL/bin
/jboss_tomcat/jboss-2.0-FINAL/conf
/jboss_tomcat/jboss-2.0-FINAL/lib/jaas.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/jboss-jaas.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/jdbc2_0-stdext.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/jmxri.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/xml.jar
/jboss_tomcat/tomcat-3.2-b7/lib/servlet.jar
/jboss_tomcat/tomcat-3.2-b7/lib/jaxp.jar
/jboss_tomcat/tomcat-3.2-b7/lib/webserver.jar
/jboss_tomcat/tomcat-3.2-b7/lib/parser.jar
/jboss_tomcat/tomcat-3.2-b7/lib/jasper.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/activation.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/awt.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/dynaserver.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejb.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejxeditor.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejxejb.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejxjaws.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejxjboss.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/hsql.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/idb.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jboss.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jetty-service.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jms.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jmxtools.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jndi.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jnpserver.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jpl-util-0_5b.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jta-spec1_0_1.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/mail.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/spydermq.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/tomcat-service.jar
/jboss_tomcat/jboss-2.0-FINAL/db
/jboss_tomcat/jboss-2.0-FINAL/log
/jboss_tomcat/jboss-2.0-FINAL/conf/tomcat
</pre><p>
Also the source dir for jboss sources should be set to:
/jboss_tomcat/jboss-2.0-FINAL/src
</p></li><li><p><a name="N25be"></a>Add JBoss Server Library to your project.
</p></li><li><p><a name="N25c2"></a>Rebuild all. </p></li><li><p><a
name="N25c6"></a>Deploy your application.
Copy your jar to the jboss/deploy dir </p></li></ol></div><p>
If all is well, you should be able to set break points etc and single step your
code. </p><p>
Notes
Do NOT include the Sun J2EE SDK jars in your project. </p></div></div><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch09.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch09s50.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch09s56.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s56.html
Index: ch09s56.html
===================================================================
<html><head><title>EJX/AWT Development HowTo</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s53.html" rel="previous" title="How to Run JBoss in JBuilder's
Debugger"><link href="ch09s81.html" rel="next" title="JBossCX
Configuration"></head><body alink="#0000FF" bgcolor="white" link="#0000FF"
text="black" vlink="#840084"><table border="0" cellpadding="0" cellspacing="0"
height="65"><tr height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s53.html"><img border="0" he!
ight="65" src="images/prev.gif" width="76"></a><a href="ch09s81.html"><img border="0"
height="65" src="images/next.gif" width="60"></a></td></tr><tr></tr></table><div
class="section"><a name="N25d3"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N25d3"></a><span class="title">EJX/AWT Development
HowTo</span></h2></div></div><p>Author:
<span class="author">Andreas Shaefer</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N25e3"></a><div class="titlepage"><div><h3
class="title"><a name="N25e3"></a><span
class="title">Introduction</span></h3></div></div><p>
This How To serie is about how to develop EJX plugins with the help of
Rickard's AWT, XML and
BeanContext and NOT about how to use EJX and its plugins (at least for
now)!! </p><div class="orderedlist"><ol type="1"><li><p><a name="N25f0"></a><a
href="ch09s56.html#ejx1">Insights to EJX internals by Simon
Bordet</a></p></li><li><p><a name="N25f7"></a><a href="ch09s56.html#ejx2">Getting
started with EJX</a></p></li><li><p><a name="N25fe"></a><a
href="ch09s56.html#ejx3">GUI Basics</a></p></li></ol></div><p>
Next steps
</p><div class="orderedlist"><ol type="1"><li><p><a name="N260f"></a>How to
use resources (especially XML files) in EJX </p></li><li><p><a
name="N2613"></a>Advanced GUIs </p></li></ol></div></div><div class="section"><a
name="ejx1"></a><div class="titlepage"><div><h3 class="title"><a name="ejx1"></a><span
class="title">EJX Insights</span></h3></div></div><p>EJX (created by Rickard
֢erg and are available at his DreamBean Website: www.dreambean.com) is a
launcher for JavaBean plugins
that are written following the Glasgow specification, in particular the Extensible
Runtime Containment and Services Protocol. This
document is intended for programmers that want to write plugins for EJX, and will
(try to) explain the insights of the bean context
hierarchy of EJX, and also classloader issues regarding this hierarchy.
</p></div><div class="section"><a name="N2623"></a><div class="titlepage"><div><h3
class="title"><a name="N2623"></a><span class="title">The
launcher</span></h3></div></div><p>
com.dreambean.ejx.editor.Main is the launcher for EJX. It does the following:
</p><div class="orderedlist"><ol type="1"><li><p><a name="N2630"></a>creates a new
URLClassLoader, whose parent is the current context classloader </p></li><li><p><a
name="N2634"></a>all files under ../lib and ../lib/ext are added to this
URLClassLoader (PENDING: really all files or only jars) </p></li><li><p><a
name="N2638"></a>the context class loader is set to this URLClassLoader
</p></li><li><p><a name="N263c"></a>the class com.dreambean.ejx.editor.EJX is
instantiated using the new context class loader (ie the URLClassLoader)
</p></li></ol></div><p>
All plugins you would like to show in the EJX framework must be under ../lib or
../lib/ext, so that their classes can be loaded through the
context class loader. If this is not the case, your plugin is not even shown in the
EJX first window, where you can choose, among the
available plugins, which one you want to use.</p><p>
Every EJX plugin is archived in a jar and must have an entry in the manifest file
that reads:</p><p>
EJX-plugin: <factory-class-name></p><p>
where <factory-class-name> is the fully qualified name of the
ResourceManagerFactory implementation that can instantiate the
ResourceManager implementation for that plugin.</p></div><div class="section"><a
name="N264e"></a><div class="titlepage"><div><h3 class="title"><a
name="N264e"></a><span class="title">The bean context
framework</span></h3></div></div><p>
Following the Glasgow specification, JavaBeans can be logically grouped in
containers, called BeanContext. A BeanContext can
contain other nested BeanContext, or directly BeanContextChild JavaBeans. While
normal JavaBeans can be added to BeanContexts,
to obtain the full potentiality of the new framework, they should implement the
BeanContextChild interface. A BeanContextChild is
normally a terminal child of the containment hierarchy, so it cannot have nested
JavaBeans. JavaBeans, being they BeanContext or
BeanContextChild can be added to or removed from a BeanContext, and notification of
these events is delivered to registered
membership listeners.</p><p>
A BeanContext can expose services to its children, services that can easily accessed
by them simply specifying the interface that
represent the wanted service. The interfaces that provides this support are
BeanContextServices and BeanContextServiceProvider.</p><p>
BeanContextServices is a BeanContext with the possibility to be queried for services
that it hosts. BeanContextServiceProvider is the
service hosted by a BeanContextServices. Services can be added or removed from a
BeanContextServices, and notification of these
events is delivered to registered service listeners.</p><p>
Within this framework, JavaBeans can obtain a reference to the BeanContext in which
they are hosted and thus be aware of the
environment in which they're running; plus they can query the BeanContext for
services, if the BeanContext hosting them is a
BeanContextServices. If this BeanContextServices does not have the requested
service, the request goes up in the hierarchy, eventually
finding the BeanContextServices that provides the service.</p></div><div
class="section"><a name="N265f"></a><div class="titlepage"><div><h3 class="title"><a
name="N265f"></a><span class="title">The bean context root and the
services</span></h3></div></div><p>
As you may have guessed, com.dreambean.ejx.editor.EJX is a BeanContextServices
instance, and is the root of the bean context
hierarchy of the application.</p><p>
It hosts 2 services: </p><div class="orderedlist"><ol type="1"><li><p><a
name="N266f"></a>a Preference service, used to store user preferences like screen size
</p></li><li><p><a name="N2673"></a>an XMLManager service, used to allow JavaBeans to
read from / write to XML files.</p></li></ol></div><p>
Direct children EJX are the plugins, that implements the ResourceManager interface.
ResourceManager extends BeanContextChild so
that implementors can be directly plugged in the containment hierarchy, but normally
implementors of the ResourceManager interface
implements BeanContextServices, to provide plugin-specific services to their nested
JavaBeans.</p><p>
PENDING: add a figure / schema of the containment tree with different colors
representing services</p></div><div class="section"><a name="N267f"></a><div
class="titlepage"><div><h3 class="title"><a name="N267f"></a><span class="title">Where
the GUI comes in ?</span></h3></div></div><p>
We saw the bean context hierarchy, but what you can see on the screen is not totally
related to it (though there is a relationship). How
can EJX show the GUI for JavaBeans component seamlessly ?</p><p>
Every JavaBean that wants to display a GUI in EJX must implement either
BeanContextContainerProxy or
BeanContextChildComponentProxy. </p><p>
com.dreambean.ejx.editor.EJX implements BeanContextContainerProxy and its
getContainer() method expose a JDesktopPane of a
JFrame (also held by com.dreambean.ejx.editor.EJX [NOTE: this JFrame is not exposed
(as of 15 Nov 2000), so it is not accessible from
nested JavaBeans if they want play with the menu bar. I have in mind to change this
and indirectly expose the JFrame as a EJX
service]).</p><p>
JDesktopPane is the specialized class that hosts JInternalFrames. Normally plugins
implement the BeanContextChildComponentProxy
interface returning a java.awt.Component (subclass) that can be added to a
JInternalFrame and finally added to the JDesktopPane.</p><p>
The difference between BeanContextChildComponentProxy and BeanContextContainerProxy
is that the former is implemented by
JavaBeans whose enclosing BeanContext is responsible to call getComponent and add
the resulting java.awt.Component to some
existing GUI, while the latter is implemented by JavaBeans whose enclosed JavaBeans
are responsible to call getContainer() and add to
this java.awt.Container GUI components taken from somewhere else. The former says "I
know my children, let's take their GUI
components and add them here", the latter says "I know my parent, let's add this GUI
components to its GUI container".</p></div><div class="section"><a
name="ejx2"></a><div class="titlepage"><div><h3 class="title"><a name="ejx2"></a><span
class="title">Getting strted with EJX</span></h3></div></div><div class="section"><a
name="N2699"></a><div class="titlepage"><div><h4 class="title"><a
name="N2699"></a><span class="title">Introduction</span></h4></div></div><p>
EJX/AWT written by Rickard ֢erg</p><p>
Both packages are created by Rickard ֢erg and are available at his
DreamBean Website: www.dreambean.com.
Both packages are heavily used in jBoss do create/maintain EJB descriptor
and other XML files.
The reason or motivation for me to write this HowTo was that I struggle to
understand EJX and AWT. On the
other hand Rickard was so busy with other stuff that I had to dig throug
myself and to save time for other
members of jBoss I started writing this HowTo. This document is still under
construction and will maybe never
be finished. </p><p> Idea of EJX</p><p>
EJX is a package and runtime environment enabling you to create a plugin to
add new functionality and new GUI
elements. EJX will dynamically lookup for plugins on the predefined package
/lib/ext and load them for you.
Whenever you create a new file or open a given file it will instantiate
your plugin and show as an Frame within
the EJX framework.
EJX uses XML but at the moment this is not quite clear for me but I am
working on it (AS 9/15/00), </p><p>
Idea of AWT</p><p>
AWT (or here called Advanced Window Toolkit and do not mix it up with
java.awt.*) enables you to use an
uniform GUI Environment and to use BeanContext with an easy to write XML
definition file.
I am still at the beginning to understand AWT and EJX but I will upgrade
this document as soon as I have more
information and examples. </p></div><div class="section"><a
name="N26b0"></a><div class="titlepage"><div><h4 class="title"><a
name="N26b0"></a><span class="title">Project</span></h4></div></div><div
class="section"><a name="N26b4"></a><div class="titlepage"><div><h5 class="title"><a
name="N26b4"></a><span class="title">Introduction</span></h5></div></div><p>
Based on the first draft of this document I separated the core EJX stuff from
the EJX examples to make it a little bit more
clear. Afterwards I implemented these changes in the EJX module of jBoss CVS
server. If you now download the EJX
module you can create a slim release of EJX without the examples. If you need
them you can just jump to the examples
directory and build the example from there (one by one) and only the examples
you want or need. </p></div><div class="section"><a name="N26bc"></a><div
class="titlepage"><div><h5 class="title"><a name="N26bc"></a><span
class="title">Structure</span></h5></div></div><p>
To go through this document download the EJX module from the jBoss CVS server.
Attention: Before you start with compiling any examples you have to run the
compilation of the core project first. For this
go to the "ejx/src/build" and start the build.bat file. This compiles the core
project, copies the necessary jar-files to the
right place and creates the necessary ejxeditor.jar file.
Now you are ready for the examples. </p></div><div class="section"><a
name="N26c4"></a><div class="titlepage"><div><h5 class="title"><a
name="N26c4"></a><span class="title">Plain Pane Example</span></h5></div></div><p>
This example can be found under "ejx/examples/plain.pane".
This was my first example and the goal was to creat a Panel within EJX
framework to display just a simple text. I used
this example to find simplest example within EJX.
According to the EJX spec the only necessary thing you have to to is: </p><div
class="orderedlist"><ol type="1"><li><p><a name="N26d1"></a>Create a class extending
the com.dreambean.ejx.FileManagerFactory interface </p></li><li><p><a
name="N26d5"></a>Create a class extending the com.dreambean.ejx.FileManager
interface</p></li><li><p><a name="N26d9"></a>Create an appropriate Manifest file with
looks like this for this example:
Class-Path: awt.jar ejb.jar EJX-plugin:
com.madplanet.plainPane.FileManagerFactoryImpl Name:
com/madplanet/plainPane/ Specification-Title: PlanePane
0.1 Specification-Version: v0.1 Specification-Vendor: MAD
plaNET plc Implementation-Title: ejx-plain-pane
Implementation-Version: build1 Implementation-Vendor: MAD
plaNET plc
</p></li><li><p><a name="N26dd"></a>Compile these two classes
</p></li><li><p><a name="N26e1"></a>Put these two classes and the Manifest file into a
jar-file (name does not matter but I always name
it this way: ejx.<ProjectName>.jar).</p></li><li><p><a
name="N26e5"></a>And last but not least the just created jar-file into the
ejx/dist/lib/ext directory. </p></li></ol></div><p>
Now the only thing left is to start EJX (go to ejx/dist/bin directory and
start EJX with "java -jar ejx.jar"). When the EJX
Frame comes up go to file/new and select "Plain Pane XML" and you will see our
plugin coming up.
Now let's have a closer look to the classes we created in our
plugin.</p></div><div class="section"><a name="N26ee"></a><div
class="titlepage"><div><h5 class="title"><a name="N26ee"></a><span
class="title">FileManagerFactoryImpl</span></h5></div></div><p>
Implements the com.dreambean.ejx.FileManagerFactory and enables the EJX
framework to select the right file for you.
But now let's delf into the code </p><p>
Classes to be imported </p><pre class="programlisting">
import java.io.File;
import javax.swing.filechooser.FileFilter;
import com.dreambean.ejx.FileManager;
import com.dreambean.ejx.FileManagerFactory;
</pre><p>
Class definition (to extend this class from FileFilter is just
convenience because it is needed either
way):</p><pre class="programlisting">
public class FileManagerFactoryImpl extends FileFilter
implements FileManagerFactory </pre><p>
These methods must be implement due FileManagerFactory interface.
The first method creates the
FileManager when a file is selected or in a given directory a new
one can be created. The second
method returns a FileFilter to select a file or directory and the
last is used to get a name for the
Plugin to select the right one. </p><pre class="programlisting">
public FileManager createFileManager() {
return new FileManagerImpl( this );
}
public FileFilter getFileFilter() {
return this;
}
public String toString(){
return "Plain Pane XML";
}
</pre></div><div class="section"><a
name="N270e"></a><div class="titlepage"><div><h5 class="title"><a
name="N270e"></a><span class="title">FileManagerImpl</span></h5></div></div><p>
Implements the com.dreambean.ejx.FileManager and enables the plugin to decide
what GUI element to display. For each
file or directory selected a new instance of this class is created. </p><p>
Classes to be imported </p><pre class="programlisting">
import java.awt.BorderLayout;
import java.awt.Component;
import java.beans.beancontext.BeanContextServicesSupport;
import java.io.File;
import javax.swing.JPanel;
import javax.swing.JLabel;
import com.dreambean.ejx.FileManager;
import com.dreambean.ejx.FileManagerFactory;
</pre><p>
I am only so pitty about what classes are imported to show you at
the header where the used
classes are coming from.
Constructor of the class: </p><pre class="programlisting">
FileManagerImpl( FileManagerFactory pCaller ) {
mFactory = pCaller;
}
</pre><p>
Methods must be overwriten by the class, The important part is the
getComponent() method which
is called by the EJX framework to get the GUI component to be
displayed. </p><pre class="programlisting">
public boolean isChanged() {
return true;
}
public void createNew() {
}
public void load( File file ) throws Exception {
}
public void save( File f ) throws Exception{
}
public File getFile() {
return null;
}
public void setFile( File pFile ) {
}
public FileManagerFactory getFactory() {
return mFactory;
}
public Component getComponent() {
JPanel lPane = new JPanel( new BorderLayout()
);
lPane.add( new JLabel(
"<HTML><BODY><H1>Hello
World</H1>"
+ "<H2>Next
Step</H2></BODY></HTML>" ),
BorderLayout.CENTER );
return lPane;
}
</pre></div><div class="section"><a name="N272e"></a><div
class="titlepage"><div><h5 class="title"><a name="N272e"></a><span
class="title">Simple Component Example</span></h5></div></div><p>
This example can be found under "ejx/examples/simple.component".
This example is an introduction to AWT and how it can be used to define a GUI
by the XML description file, compiled and
display on the Panel in the EJX framework. To shorten the further discussion I
only show the important stuff having
changed or is new. </p><p>
The only thing with AWT you have to consider is that you have to use XMLBeans
to compile the BeanInfo XML
description into a Java class and then to compile it to a java bytecode class.
For that have a look at the build.xml and look
for xmlbeans. </p><p>
According to the AWT spec the only necessary thing you have to to is:</p><div
class="orderedlist"><ol type="1"><li><p><a name="N2741"></a>Create an Bean Info XML
description file like this:
<bean class="com.madplanet.simpleComponent.MainPane"
displayname="Simple Component's Main Pane"
iconcolor16="/images/container.gif"> <property
name="FirstProperty" class="java.lang.String"
displayname="First Property"/> <property
name="SecondProperty" class="java.lang.String"
displayname="Second Property"/>
</p></li><li><p><a name="N2745"></a>Create a GUI component class and
add the GenericCustomizer to it (as parameter you have to
pass the class instance which is referred above (here it is
com.madplanet.singleComponent.MainPane). There are other classes
you can use but at the
moment I have no more informations. </p></li><li><p><a
name="N2749"></a>Compile all the java classes</p></li><li><p><a name="N274d"></a>User
XMLBeans to create the java sourcecode from the XML beaninfo. The newly created java
classes are named like the referred class but with Beaninfo at the
end (same package structure). </p></li><li><p><a name="N2751"></a>Compile the bean
info java sourcecode files. </p></li></ol></div><p>
That's it. </p></div><div class="section"><a name="N275a"></a><div
class="titlepage"><div><h5 class="title"><a name="N275a"></a><span
class="title">FileManagerImpl</span></h5></div></div><p>Like the one before except the
getComponent() method: </p><pre class="programlisting">
public Component getComponent() { // Create the Property Container and
return its GUI component return new MainPane().getComponent();
}
</pre></div><div class="section"><a name="N2767"></a><div
class="titlepage"><div><h5 class="title"><a name="N2767"></a><span
class="title">MainPane</span></h5></div></div><p> This class now creates the GUI
component using AWT to display the properties this class have.</p><p>
Classes to be imported </p><pre class="programlisting">
import java.awt.BorderLayout;
import java.awt.Component;
import java.beans.beancontext.BeanContextSupport;
import
java.beans.beancontext.BeanContextChildComponentProxy;
import javax.swing.JPanel;
import com.dreambean.awt.GenericCustomizer;
</pre><p>
This class has to supclass the BeanContextSupport </p><pre
class="programlisting">
public class MainPane extends BeanContextSupport </pre><p>
There are the properties the Main Pane offer and which can then be
set by GUI component defined
by the Bean Context Attention: All the properties in the BeanInfo
XML file need here a public
getter and setter method with the appropriate type. </p><pre
class="programlisting">
public String getFirstProperty() {
return mFirstProperty;
}
public void setFirstProperty( String pToSet ) {
mFirstProperty = pToSet;
}
public String getSecondProperty() {
return mSecondProperty;
}
public void setSecondProperty( String pToSet ) {
mSecondProperty = pToSet;
}
</pre><p>
This method returns the GUI component which contains the Generic
Customizer need to display
the properties of this instance accordingly to the Bean Info XML
description mentioned above.</p><pre class="programlisting">
public Component getComponent() {
JPanel lPane = new JPanel( new BorderLayout()
);
lPane.add( new GenericCustomizer( this ),
BorderLayout.CENTER );
return lPane;
}
</pre><p>
Eh voilଠthat's it. When you build this example, start EJX and select
Simple Component XML you will see two lines with
the tag "First Property" and a Text Field (and also for Second
Property).</p><p>
That's all for now. In the next step I will delf further into AWT and how you
can use the Bean Info XML description to
describe more advanced application. In addition I will then use the save() and
load() method to load XML files which are
the persistent part of a plugin. </p><p>
I anything is wrong or not correct please contact me at
[EMAIL PROTECTED] Also if you want to know more in
detail or have a request for changes in this HowTo document.
</p></div></div></div><div class="section"><a name="ejx3"></a><div
class="titlepage"><div><h3 class="title"><a name="ejx3"></a><span
class="title">EJX/AWT GUI Basics HowTo</span></h3></div></div><div class="section"><a
name="N27a0"></a><div class="titlepage"><div><h4 class="title"><a
name="N27a0"></a><span class="title">Introduction</span></h4></div></div><p>
In this How To I will discuss the use of the BeanContext und AWT to create
GUIs and GUI components within
EJX but you can also use AWT outside of EJX.Attention: please note that I
always mean Rickard ֢erg's AWT
and not the Java AWT!</p><p>The AWT provides you with the following
opportunities: </p><div class="orderedlist"><ol type="1"><li><p><a
name="N27b0"></a>Customizers for your Beans</p></li><li><p><a
name="N27b4"></a>Property Editors to edit or select properties</p></li></ol></div><p>
This seems to be simple but combining them together with the Java Bean
Support and ordinary Swing coding
leads to advanced GUIs like the actual version of EJX used in jBoss (I am not
taking about the lack of User
guidance but about the abilities of the GUI to display and edit the data).
</p><p>
My biggest problem to understand EJX/AWT was that you have to deal with EJX,
AWT, Java Bean Support,
XML and Swing coding. Therefore I started from the simplest example to
understand each component, its
function and how to use it. In the "Getting-Started" How To I showed how to
create an EJX plugin and then
create a basic Bean GUI. Now I go a step further to dynamically manage GUI
components, use of more BeanInfo
features and to edit properties with the AWT property editors. So let's start
it! </p></div><div class="section"><a name="N27c0"></a><div class="titlepage"><div><h4
class="title"><a name="N27c0"></a><span class="title">
Tabbed Panes and Editors</span></h4></div></div><div class="section"><a
name="N27c4"></a><div class="titlepage"><div><h5 class="title"><a
name="N27c4"></a><span class="title">Goals</span></h5></div></div><p>
From the last example of the first How To create and remove GUI Components
(Tabbed Panes) dynamically and
edit the properties of the data instance with the AWT editors. </p></div><div
class="section"><a name="N27cc"></a><div class="titlepage"><div><h5 class="title"><a
name="N27cc"></a><span class="title">Design</span></h5></div></div><p>
First of all I want correct I mistake in the previous example. In the
MainPane class it is said that getComponent()
is implemented because of BeanContextChildComponentProxy which is not
implemented in the class but it works
because the caller does not relay on this fact. But in this example I fixed
this. The question but still remains why
it should (will maybe be explained later). </p><p>
This example is really not a good example how to use EJX but it shows how to
use EJX/AWT. The idea is to use
a tabbed pane to display different views in our EJX frame. In addition the
user can create and remove the tabbed
pane as long as there is at least one left. And last but not least the user
should be able to select a value through
an editor instead of a plain input field. </p><p>
As we saw in the last example the initial GUI component to show the plugin is
created in the ResourceManager
on the getComponent() call which is called by the BeanContext structure we
use. But instead of create a Panel
which just keeps the GUI of the plugin we create now a viewer of the plugin
to display itself. This makes the
design more flexible because it is now defined in the Viewer instead of the
ResourceManager where it does not
belong. Now the viewer is an inner class because it is so closely related to
its outer component that it makes
sense to be there. </p><p>
The construct following is a little bit ugly and should not be MADE this way
but it is enough for us.
The ResourceManager getComponent() now calls the MainPane's getComponent()
method and this instantiate its
viewer and returns this Viewer as the GUI component to be shown. </p><p>
When the users now hits the create a new Tab or remove this tab the
appropriate method is called (by the
BeanContext) and it will create a new MainPane instance and adds its also
created Viewer instance as a new
Tab to the tabbed pan or remove the actual shown tab from the tabbed pane.
As you can see above the buttons we have a text input field and a drop down
box letting the user select between
two items. Both are AWT editors. </p></div><div class="section"><a
name="N27e0"></a><div class="titlepage"><div><h5 class="title"><a
name="N27e0"></a><span class="title">Implementation</span></h5></div></div><p>
First lets have a look at the changes in the ResourceManager where the
getComponent() just instanciate the
MainPane and returns its GUI component.</p><pre class="programlisting">
public Component getComponent() {
// Create the Property Container and return its GUI component
return new MainPane().getComponent();
}
</pre><p>
Now let's look at the new BeanInfo description of the MainPane: </p><pre
class="programlisting">
<bean class="com.madplanet.tabbedEditor.MainPane"
displayname="Tab Pane and Editor's Main Pane"
iconcolor16="/images/container.gif"> <property
name="FirstProperty" class="java.lang.String"
displayname="First Property"
propertyeditor="com.dreambean.awt.editors.TextEditor"/>
<property name="SecondProperty"
class="java.lang.String" displayname="Second
Property"
propertyeditor="com.madplanet.tabbedEditor.editors.SecondPropertyEditor"/>
<method name="createTab" displayname="Create a new
Tab"> <parameter displayname="Title"/> </method>
<method name="removeTab" displayname="Remove this
Tab"> </method> </bean>
</pre><p>
As you can see there are property editors settings for the first and second
property and the second
property uses its own editors. In addition you have methods listed which
appears as buttons in the
GUI because we use the GenericCustomizer. </p><p>
The new editor is just a simple subclass of the AWT TagsEditor defining what
items it has to show and to what
value the item relate to (you can use any Java Object you like): </p><pre
class="programlisting">
package com.madplanet.tabbedEditor.editors;
import com.dreambean.awt.editors.TagsEditor;
/** * Editor to select the Second Property in a DD - editor */
public class SecondPropertyEditor extends TagsEditor
{ // Constructors
--------------------------------------------------
public SecondPropertyEditor() {
super(new String[] {"First Selection","Second Selection"},
new Object []{"First", "Second"});
}
} </pre><p>
And as "Grande Finale" we come to the heart of the plugin to the MainPane
class. </p><p>
The new viewer class is an inner class to the MainPane and creates a
GUI to display the
instance of its outer class instance. It keeps a list of outer class
instances to find the
index of the tab to be removed. The setObject() creates a new tab
and memorize the given
outer class. The removeTab() looks for the given outer instance and
removes its related
tab (by this index). </p><pre class="programlisting">
public class Viewer extends JTabbedPane implements Customizer
{ // Attributes
---------------------------------------------------
private Vector mDataObjectList = new Vector(); // Customizer
implementation
------------------------------------
public void setObject( Object pDataObject ) {
// Init UI
addTab( "Main", new GenericCustomizer( pDataObject ) );
mDataObjectList.addElement( pDataObject );
}
/** * Removes the given Tab with the given Data Object *
from the
Tabbed Pane * * @param pDataObject Tab with this Data
Object has to be removed if found **/
public void removeTab(Object pDataObject ) {
int lIndex = mDataObjectList.indexOf(
pDataObject );
if( lIndex >= 0 ) {
remove( lIndex );
mDataObjectList.removeElementAt( lIndex );
}
}
} </pre><p>
These are the new methods (already defined in the BeanInfo see
above) which are called if
the appropriate button is pressed. </p><pre class="programlisting">
public void createTab( String pTitle ) throws Exception {
System.out.println("Create new Tab with title: " + pTitle);
MainPane lNewPane = new MainPane();
lNewPane.mCustomizer = mCustomizer;
lNewPane.mCustomizer.setObject(
lNewPane );
}
public void removeTab() {
System.out.println( "Remove this tab");
( (Viewer) mCustomizer ).removeTab(this );
}
</pre></div></div><div class="section"><a
name="N2814"></a><div class="titlepage"><div><h4 class="title"><a
name="N2814"></a><span class="title"> Remarks</span></h4></div></div><p>
This is more ore less EJX and AWT. But it does not end here. The power of EJX
lays in the BeanContext and
how you combine EJX, BeanContext and AWT. You maybe think what's about XML
and we will come to XML
soon but (in my opinion) this is not a core part of EJX and AWT just use it
but just as the name of the EJX base
classes said they manage resources (or earlier just files). Therefore it must
be a way do deal with resources and
especially with XML resources. </p></div></div></div><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch09.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch09s53.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch09s81.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s81.html
Index: ch09s81.html
===================================================================
<html><head><title>JBossCX Configuration</title><link href="styles.css"
rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.30"
name="generator"><link href="index.html" rel="home" title="JBoss 2.0
documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s56.html" rel="previous" title="EJX/AWT Development HowTo"><link
href="ch09s92.html" rel="next" title="External JNDI Configuration and JNDI
Viewing"></head><body alink="#0000FF" bgcolor="white" link="#0000FF" text="black"
vlink="#840084"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/jboss.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s56.html"><img border="!
0" height="65" src="images/prev.gif" width="76"></a><a href="ch09s92.html"><img
border="0" height="65" src="images/next.gif"
width="60"></a></td></tr><tr></tr></table><div class="section"><a
name="N281e"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N281e"></a><span class="title">JBossCX Configuration</span></h2></div></div><p>
Author:
<span class="author">Toby Allsop</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N282e"></a><div class="titlepage"><div><h3
class="title"><a name="N282e"></a><span
class="title">Introduction</span></h3></div></div><p>
This section describes the configuration changes necessary in order to use
a resource adapter conforming to
the J2EE Connector Architecture (JCA) in your application. </p><p>
The JCA specifies how J2EE application components can access resources
other than those explicitly
specified in the J2EE 1.2 specification. It will be part of the J2EE 1.3
specification. You can read more about
the JCA at its <a href="http://java.sun.com/j2ee/connector"
target="_top"><i>official home page</i></a></p><p>
JBossCX is the name of the JBoss module that provides RAR deployment and
connects a resource adapter to
a connection manager to create a connection factory accessible by
application components through JNDI. </p></div><div class="section"><a
name="N2841"></a><div class="titlepage"><div><h3 class="title"><a
name="N2841"></a><span class="title">Contents</span></h3></div></div><div
class="itemizedlist"><ul><li><p><a name="N2847"></a><a
href="ch09s81.html#jca1">Terminology</a></p></li><li><p><a name="N284e"></a><a
href="ch09s81.html#jca2">JBoss Configuration</a></p></li><li><p><a name="N2855"></a><a
href="ch09s81.html#jca3">Example - Black Box Example Adapter from
Sun</a></p></li><li><p><a name="N285c"></a><a href="ch09s81.html#jca4">Implementation
Status</a></p></li></ul></div></div><div class="section"><a name="jca1"></a><div
class="titlepage"><div><h3 class="title"><a name="jca1"></a><span
class="title">Terminology</span></h3></div></div><div class="table"><p><a
name="N286b"></a><b>Table 9.2. Terminology</b></p><table border="1"
summary="Terminology"><thead><tr><th>C!
oncept</th><th>Description</th></tr></thead><tbody><tr><td>Resource</td><td>an
external system that provides some service to application components. Examples include
JDBC
databases and mainframe systems</td></tr><tr><td>Resource adapter
Connector</td><td>an application component that implements access to a
resource</td></tr><tr><td>Resource instance</td><td>a particular configuration of a
resource, e.g. an Oracle database running on machine "foo" at port
"1234"</td></tr><tr><td>Connection factory</td><td>an object,
available through JNDI, that provides access to connections to a particular resource
instance</td></tr><tr><td>Connection manager</td><td>an object that
implements the javax.resource.spi.ConnectionManager interface - provides connection
pooling, transaction association, security and other "quality of
services"</td></tr></tbody></table></div></div><div class="section"><a
name="jca2"></a><div class="titlepage"><div><h3 class="title"><a name="jca2"></a><span
class="title">JBoss Configuration</span></h3></div></div><p>
There are two steps that must be performed to provide access to a
connection factory in JBoss: </p><div class="orderedlist"><ol type="1"><li><p><a
name="N28c1"></a>Configure a connection factory in jboss.jcml </p></li><li><p><a
name="N28c5"></a>Deploy the resource adapter </p></li></ol></div><div
class="section"><a name="N28ca"></a><div class="titlepage"><div><h4 class="title"><a
name="N28ca"></a><span class="title">Connection Factory
Configuration</span></h4></div></div><p>
Connection factories are created by the ConnectionFactoryLoader MBean, so
an <mbean> section must be
added to jboss.jcml for each connection factory that is required. The
format for this entry is as follows.</p><pre class="programlisting">
<mbean code="org.jboss.resource.ConnectionFactoryLoader"
name="JCA:service=ConnectionFactoryLoader,name=name">
<!-- General attributes -->
<attribute name="name">value</attribute>
<!-- Security attributes -->
<attribute name="name">value</attribute>
</mbean>
</pre><p>General Attributes</p><div class="table"><p><a
name="N28d9"></a><b>Table 9.3. General Attributes</b></p><table border="1"
summary="General
Attributes"><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td>FactoryName</td><td>The
name of the connection factory. This is the name under which the
connection factory will be bound in
JNDI</td></tr><tr><td>RARDeployerName</td><td>The name of the MBean that will deploy
the resource adapter that this
connection factory relates
to</td></tr><tr><td>ResourceAdapterName</td><td>The name of the resource adapter for
which this connection factory will
create connections. This is the name
given in the resource adapter's
<display-name> deployment
descriptor element</td></tr><tr><td>Properties</td><td>The properties to set on the
resource adapter to configure it to connect to a
particular resource instance. This is
in java.util.Properties.load format
(essentially one property per line,
name=value)</td></tr><tr><td>ConnectionManagerFactoryName</td><td>The name of the
connection manager factory to use. This is the name given
in a previously defined
ConnectionManagerFactoryLoader MBean.
Currently there are two choices:
MinervaSharedLocalCMFactory and
MinervaXACMFactory. The former should
be used for resource adapters that
support local transactions and the
latter for those that support XA
transactions.</td></tr><tr><td>ConnectionManagerProperties</td><td>The properties (in
java.util.Properties.load format) to set on the
connection manager for this connection
factory. These properties control
things such as connection pooling
parameters. The example connection
factory in jboss.jcml shows the
possible properties for the Minerva
connection
managers</td></tr></tbody></table></div><p>Security Attributes</p><p>TBD - no
interesting options yet</p></div><div class="section"><a name="N2931"></a><div
class="titlepage"><div><h4 class="title"><a name="N2931"></a><span
class="title">Deploying the Resource Adapter</span></h4></div></div><p>
Currently the J2EE deployer does not recognise resource adapters, so it is
not possible to deploy them with the
auto deployer or as part of an EAR. This functionality will be added at a
later date.</p><p>
To deploy a resource adapter, and thus activate any connection factories
configured for it, invoke the
deploy(String) operation on the RARDeployer MBean, passing it a URL
pointing to the RAR file containing the
resource adapter. The RAR deployer can also deploy directories that are
structured like a RAR file.</p><p>
The easiest way to invoke operations on MBeans is using the HTML adapter
that is, by default, accessible on
port 8082, i.e. point a browser at http://localhost:8082 if running the
browser on the machine running JBoss.
Then find the RARDeployer MBean and it should be self explanatory from
there. </p></div></div><div class="section"><a name="jca3"></a><div
class="titlepage"><div><h3 class="title"><a name="jca3"></a><span
class="title">Example - Black Box Example Adapter from Sun</span></h3></div></div><p>
For this example you will need Sun's example resource adapter, available
here. The source code for this
resource adapter is also available - this is useful if writing your own
adapter. </p><p>
This resource adapter accesses a JDBC 2.0 compliant database. The
advantage of this is that you don't need
any weird or wacky resource to access and that you can compare the
behaviour with a straight JDBC
connection pool. </p><p>
In order to make a connection factory from this resource adapter available
to application components, we need
to add the ConnectionFactoryLoader MBean that will create the connection
factory from the resource adapter
when it is deployed. We will create a connection factory called BlackBoxDS
that will appear in JNDI at
java:/BlackBoxDS. Below is the MBean definition that we will use (this is
taken from the default jboss.jcml.</p><pre class="programlisting">
<!-- Example connection factory for the example "Black Box" resource
adapter. This points at the same database as DefaultDS. -->
<mbean code="org.jboss.resource.ConnectionFactoryLoader"
name="JCA:service=ConnectionFactoryLoader,name=BlackBoxDS">
<attribute name="FactoryName">BlackBoxDS</attribute>
<attribute
name="RARDeployerName">JCA:service=RARDeployer</attribute>
<attribute name="ResourceAdapterName">Black Box LocalTx
Adapter</attribute>
<attribute name="Properties">
ConnectionURL=jdbc:HypersonicSQL:hsql://localhost:1476
</attribute>
<attribute
name="ConnectionManagerFactoryName">MinervaSharedLocalCMFactory</attribute>
<!-- See the documentation for the specific connection manager
implementation you are using for the properties you can set
-->
<attribute name="ConnectionManagerProperties">
# Pool type - uncomment to force, otherwise it is the default
#PoolConfiguration=per-factory
# Connection pooling properties - see
# org.opentools.minerva.pool.PoolParameters
MinSize=0
MaxSize=10
Blocking=true
GCEnabled=false
IdleTimeoutEnabled=false
InvalidateOnError=false
TrackLastUsed=false
GCIntervalMillis=120000
GCMinIdleMillis=1200000
IdleTimeoutMillis=1800000
MaxIdleTimeoutPercent=1.0
</attribute>
<!-- Principal mapping configuration -->
<attribute name="PrincipalMappingClass"
>org.jboss.resource.security.ManyToOnePrincipalMapping</attribute>
<attribute name="PrincipalMappingProperties">
userName=sa
password=
</attribute>
</mbean>
</pre><p>
Note that the connection manager we have chosen is the Minerva local
transaction connection manager. It is
important to choose the connection manager that matches the capabilities
of the resource adapter. This choice
should be automated in the future. </p><p>
Once jboss.jcml is set up with the desired connection factory loaders,
start JBoss and bring up the HTML JMX
connector which lives on port 8082 by default. If your browser is running
on the same box as JBoss then you
can just go to http://localhost:8082. Then find the RARDeployer MBean and
invoke the deploy operation,
passing it the URL to the resource adapter you want to deploy. In this
case it is the path to blackbox-tx.rar
which you should save somewhere local. </p><p>
Assuming that the deployment was successful, you should now have a
connection factory bound in JNDI at
java:/BlackBoxDS that you can use just like a normal JDBC DataSource.
</p></div><div class="section"><a name="jca4"></a><div class="titlepage"><div><h3
class="title"><a name="jca4"></a><span class="title">Implementation
Status</span></h3></div></div><p>
Note that this section is likely to lag the latest developments in CVS.
When a stable release including JBossCX
is made then this section should reflect the status of the released
implementation. </p><div class="section"><a name="N2967"></a><div
class="titlepage"><div><h4 class="title"><a name="N2967"></a><span
class="title">Unimplemented Features</span></h4></div></div><div
class="itemizedlist"><ul><li><p><a name="N296d"></a>Automatic connection manager
selection based on resource adapter capabilities. </p></li><li><p><a
name="N2971"></a>Mapping to more than one resource principal per connection
factory.</p></li></ul></div></div><div class="section"><a name="N2977"></a><div
class="titlepage"><div><h4 class="title"><a name="N2977"></a><span
class="title">Limitations</span></h4></div></div><p>
Transaction association doesn't work properly unless the
transaction is started before the connection
is obtained. </p></div></div></div><table border="0"
cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img
height="79" src="images/gbar.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch09.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch09s56.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a><a href="ch09s92.html"><img border="0" height="65"
src="images/next.gif" width="60"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/ch09s92.html
Index: ch09s92.html
===================================================================
<html><head><title>External JNDI Configuration and JNDI Viewing</title><link
href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL
Stylesheets V1.30" name="generator"><link href="index.html" rel="home" title="JBoss
2.0 documentation"><link href="ch09.html" rel="up" title="Chapter 9. Howto"><link
href="ch09s81.html" rel="previous" title="JBossCX Configuration"></head><body
alink="#0000FF" bgcolor="white" link="#0000FF" text="black" vlink="#840084"><table
border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td
rowspan="2"><img height="79" src="images/jboss.gif" width="432"></td><td align="right"
background="images/gbar.gif" rowspan="2" valign="top" width="100%"><a
href="index.html"><img border="0" height="65" src="images/doc.gif" width="63"></a><a
href="ch09.html"><img border="0" height="65" src="images/toc.gif" width="60"></a><a
href="ch09s81.html"><img border="0" height="65" src="images/prev.gif"
width="76"></a></td></tr><tr></tr>!
</table><div class="section"><a name="N2981"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N2981"></a><span class="title">External JNDI
Configuration and JNDI Viewing</span></h2></div></div><p>
Author:
<span class="author">Scott Stark</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N2991"></a><div class="titlepage"><div><h3
class="title"><a name="N2991"></a><span class="title">How To Use the JNDI
ExternalContext and JNDIView MBeans</span></h3></div></div><p>The ExternalContext JNDI
MBean allows one to federate external
JNDI contexts into the JBoss server JNDI namespace. This allows one
to incorporate LDAP servers, Filesystem directories, DNS servers, etc.
even if the JNDI providers root context is not Serializable.
</p><p>
The JNDIView MBean allows one to view the JNDI namespace tree as it exists
in the JBoss server using the JMX agent view interface.
</p></div><div class="section"><a name="N299d"></a><div class="titlepage"><div><h3
class="title"><a name="N299d"></a><span class="title">Preparation of the
ExternalContext MBean</span></h3></div></div><p>
First you have to add the ExternalContext service to the jboss.jcml
in order to load the service. The folloing jboss.jcml fragment shows
the setup for an LDAP server and a local filesystem directory:
<div class="literallayout"><br>
<!-- Bind a remote LDAP server --><br>
<mbean code="org.jboss.naming.ExternalContext" name="DefaultDomain:service=ExternalContext/ldap/dscape" ><br>
<attribute name="JndiName">external/ldap/dscape</attribute><br>
<attribute name="Properties">dscape.ldap</attribute><br>
<attribute name="InitialContext">javax.naming.ldap.InitialLdapContext</attribute><br>
</mbean><br>
<!-- Bind the /Scott filesystem directory --><br>
<mbean code="org.jboss.naming.ExternalContext" name="DefaultDomain:service=ExternalContext/fs/Scott" ><br>
<attribute name="JndiName">external/fs/Scott</attribute><br>
<attribute name="Properties">scott_fs.props</attribute><br>
<attribute name="InitialContext">javax.naming.InitialContext</attribute><br>
</mbean><br>
<br>
</div>
where:
<div class="itemizedlist"><ul><li><a
name="N29ad"></a><p>code="org.jboss.naming.ExternalContext" specifies the class that
impliments the
external context mbean.
</p></li><li><a
name="N29b1"></a><p>name="DefaultDomain:service=ExternalContext/ldap/dscape" assigns
the name of the
mbean. This is using a convention that appends the unique portion of the jndi
name to the JMX name so that multiple external context mbeans are easily
distiguishable in the JMX agent view.
</p></li><li><a name="N29b5"></a><p>JndiName is the name with which the external
context is bound into the JBoss JNDI namespace
</p></li><li><a name="N29b9"></a><p>Properties is URL string to a jndi.properties
style of file for the JNDI provider whose
context is to be created. This can be any url for which there is a handler or a
simple
string in which case it is treated as a resource that can be loaded via the current
thread's context class loader.
</p></li><li><a name="N29bd"></a><p>InitialContext is the class name of the
InitialContext class to create. Should be one
of javax.naming.InitialContext, javax.naming.directory.InitialDirContext, or
javax.naming.ldap.InitialLdapContext. In the case of the InitialLdapContext, a null
Controls array is used.
</p></li></ul></div>
</p><p>
This example is binding an external LDAP context into the JBoss JNDI namespace under
the name "external/ldap/dscape". An example dscape.ldap properties file is:
<div class="literallayout"><br>
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory<br>
java.naming.provider.url=ldap://ldaphost.displayscape.com:389/o=displayscape.com<br>
java.naming.security.principal=cn=Directory Manager<br>
java.naming.security.authentication=simple<br>
java.naming.security.credentials=secret<br>
</div>
With this mbean loaded, you can access the external LDAP context located at
"ldap://ldaphost.displayscape.com:389/o=displayscape.com"
from within the JBoss VM using the following code fragment:
<pre class="programlisting">
InitialContext iniCtx = new InitialContext();
Context ldapCtx = iniCtx.lookup("external/ldap/dscape");
...
</pre>
Using the same code fragment outside of the JBoss server VM will not work
because the ObjectFactory used to handle the Reference to the LDAP context
is designed to only work within a single VM. Future versions of the ExternalContext
mbean will provide support for enabling remote access to the federated context if
desired.
</p></div><div class="section"><a name="N29d3"></a><div class="titlepage"><div><h3
class="title"><a name="N29d3"></a><span class="title">Preparation of the JNDIView
MBean</span></h3></div></div><p>
All that is required to use the JNDIView service is to add it to jboss.jcml
The mbean tag looks like this:
<div class="literallayout"><br>
<mbean code="org.jboss.naming.JNDIView" name="DefaultDomain:service=JNDIView" ><br>
</mbean><br>
<br>
</div>
There are no configurable attributes. This simply loads the mbean into the JBoss
server VM so that it can be used via the JMX MBean View.
</p></div><div class="section"><a name="N29e3"></a><div class="titlepage"><div><h3
class="title"><a name="N29e3"></a><span class="title">Using the JNDIView
MBean</span></h3></div></div><p>
To view the JBoss JNDI namespace using the JNDIView mbean, you connect to the
JMX Agent View using the http interface. The default settings put this at
<a href="http://localhost:8082/" target="_top">http://localhost:8082/</a>. On this
page you will see a section that lists the registered MBeans by domain. It
should look something like this:
<pre class="screen">
<img src="images/agent_view.jpg">
</pre>
</p><p>
This is showing two registered ExternalContext mbeans(ExternalContext/fs/Scott[a
filesystem] and
ExternalContext/ldap/dscape[an ldap server]) mbeans as well as the JNDIView
mbean. Selecting the service=JNDIView link takes you to the JNDIView MBean
View which will have a list of MBean operations section similar to:
<pre class="screen">
<img src="images/jndiview_ops.jpg">
</pre>
</p><p>
Invoking the list operation creates a dump of the JBoss JNDI namespace that
includes the federated external contexts. As an example, this is the dump
with the filesystem and ldap contexts. The following image displays the
start of the global JNDI namespace and includes the external/fs/Scott
local filesystem directory contents.
<pre class="screen">
<img src="images/jndiview_list.jpg">
</pre>
</p></div></div><table border="0" cellpadding="0" cellspacing="0" height="65"><tr
height="65"><td rowspan="2"><img height="79" src="images/gbar.gif"
width="432"></td><td align="right" background="images/gbar.gif" rowspan="2"
valign="top" width="100%"><a href="index.html"><img border="0" height="65"
src="images/doc.gif" width="63"></a><a href="ch09.html"><img border="0" height="65"
src="images/toc.gif" width="60"></a><a href="ch09s81.html"><img border="0" height="65"
src="images/prev.gif" width="76"></a></td></tr><tr></tr></table></body></html>
1.1 newsite/documentation/HTML/jbossdocs.html
Index: jbossdocs.html
===================================================================
<html><head><title>JBoss 2.0 documentation</title><meta content="DocBook XSL
Stylesheets V1.30" name="generator"></head><body bgcolor="white" text="black"
link="#0000FF" vlink="#840084" alink="#0000FF"><div id="Na21" class="book"><div
class="titlepage"><div><h1 class="title"><a name="Na21"></a>JBoss 2.0
documentation</h1></div><div><p class="copyright">Copyright © 2000, 2001 JBoss
Organization</p></div><hr></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="#Na35">Preface</a></dt><dd><dl><dt> <a
href="#Na37">Docbook</a></dt></dl></dd><dt>1. <a href="#Na67">First
steps</a></dt><dd><dl><dt> <a href="#Na78">Introduction</a></dt><dd><dl><dt> <a
href="#Na7c">What this section is about</a></dt><dt> <a href="#Na85">About
JBoss</a></dt><dt> <a href="#Na94">Pre-requisites</a></dt></dl></dd><dt> <a
href="#Naa1">Installing JBoss</a></dt><dt> <a href="#Nae2">Creating the
Bean</a></dt><dt> <a href="#Naf8">EJBs: review</a></dt><dt> <a href="#Nb19">Coding the
cla!
sses</a></dt><dt> <a href="#Nb5a">The deployment descriptor</a></dt><dt> <a
href="#Nbaf">Packaging and deploying the bean</a></dt><dt> <a href="#Nbfb">Coding the
test client</a></dt><dt> <a href="#Nc42">Compiling and running test
client</a></dt></dl></dd><dt>2. <a href="#Nc8f">Basic
configuration</a></dt><dd><dl><dt> <a href="#Nc9f">In a nutshell</a></dt><dd><dl><dt>
<a href="#Nca6">Important Directories</a></dt><dt> <a
href="#Ncae">Executables</a></dt><dt> <a href="#Ncbb">Configuration</a></dt><dt> <a
href="#Ncc3">Libraries</a></dt><dt> <a href="#Nccb">EJBs</a></dt><dt> <a
href="#Ncd3">Client Libraries</a></dt><dt> <a href="#Ncdb">Configuration
Files</a></dt><dt> <a href="#Nd3e">Clients on Remote
Machines</a></dt></dl></dd></dl></dd><dt>3. <a href="#Nd57">JDBC/Database
configuration</a></dt><dd><dl><dt> <a href="#Nd67">Introduction</a></dt><dd><dl><dt>
<a href="#Nd6b">Data Sources</a></dt><dt> <a href="#Nd79">Mappings Available for CMP
Entities</a></dt><dt> <a href="#Nd81">!
Installing JDBC Drivers</a></dt></dl></dd><dt> <a href="#Nda1">Creating DB Connection
Pools</a></dt><dd><dl><dt> <a href="#Ndab">The JDBC 2.0 Optional Package</a></dt><dt>
<a href="#Ndcb">Configuration File Changes</a></dt><dt> <a href="#Nec8">Connection
Pool Configuration Examples and Driver Notes</a></dt><dt> <a href="#N10eb">Changes for
newer versions than 2.0 FINAL</a></dt></dl></dd></dl></dd><dt>4. <a
href="#N1147">Using container-managed persistence</a></dt><dd><dl><dt> <a
href="#N1158">Introduction</a></dt><dd><dl><dt> <a href="#N115c">What this article is
about</a></dt><dt> <a href="#N116a">Pre-requisites</a></dt><dt> <a href="#N1172">JBoss
hints</a></dt><dt> <a href="#N117a">Persistence: review</a></dt><dt> <a
href="#N118b">When to Use CMP or BMP?</a></dt></dl></dd><dt> <a
href="#N1197">Container Managed Persistence - CMP</a></dt><dd><dl><dt> <a
href="#N119b">Determine the persistent classes</a></dt></dl></dd><dt> <a
href="#N11c8">Creating the Beans</a></dt><dt> <a !
href="#N1217">Packaging and deploying the Beans</a></dt><dt> <a href="#N1258">Creating
a test client </a></dt><dt> <a href="#N1289">Discussion: container-managed
persistence</a></dt><dd><dl><dt> <a href="#N1290">Technical overview </a></dt><dt> <a
href="#N129c">Limitations of CMP </a></dt></dl></dd></dl></dd><dt>5. <a
href="#N12f3">Customizing JAWS</a></dt><dd><dl><dt> <a
href="#N1303">Introduction</a></dt><dt> <a href="#N1325">Specifying a
datasource</a></dt><dt> <a href="#N1365">JAWS Options</a></dt><dt> <a
href="#N139a">Telling JAWS about your tables</a></dt><dt> <a href="#N13c1">Declaring
finders</a></dt><dt> <a href="#N13fe">Defining a type mapping</a></dt></dl></dd><dt>6.
<a href="#N1422">Advanced container configuration</a></dt><dd><dl><dt> <a
href="#N1433">What is jboss.xml?</a></dt><dt> <a href="#N1448">Specifying the
deployment name of your beans</a></dt><dt> <a href="#N1486">Declaring an ejb
references</a></dt><dt> <a href="#N14be">Container configuration</a></dt>!
</dl></dd><dt>7. <a href="#N1562">Working with Message Driven
Beans</a></dt><dd><dl><dt> <a href="#N1573">Introduction</a></dt><dt> <a
href="#N157b">Six steps to MDB nirvana in JBoss</a></dt><dt> <a href="#N15ef">Writing
Message Driven Bean</a></dt><dd><dl><dt> <a href="#N160e">Hello World MDB</a></dt><dt>
<a href="#N1655">MDB as a listener</a></dt><dt> <a href="#N16b3">The adapter
pattern</a></dt></dl></dd><dt> <a href="#N16ea">Advanced MDB
configuration</a></dt><dd><dl><dt> <a href="#N16f4">EJB deployment
descriptor</a></dt><dt> <a href="#N1744">JBoss
configuration</a></dt></dl></dd></dl></dd><dt>8. <a href="#N17cd">Container
architecture - design notes</a></dt><dd><dl><dt> <a
href="#N17e6">Introduction</a></dt><dd><dl><dt> <a href="#N17eb">JBoss 1.0 (a.k.a
EJBoss/NextGen)</a></dt><dt> <a href="#N17f7">JBoss 2.0</a></dt></dl></dd><dt> <a
href="#N1810">Client Objects</a></dt><dd><dl><dt> <a href="#N1815">EJBObject and
EJBHome</a></dt><dt> <a href="#N182a">Virtual EJBObject !
- the big picture</a></dt><dt> <a href="#N1844">Two flavours of
implementation</a></dt><dt> <a href="#N1868">Relation to ContainerInvoker</a></dt><dt>
<a href="#N1886">Dynamic proxies</a></dt><dt> <a href="#N188f">EJBObject as a dynamic
proxy</a></dt><dt> <a href="#N18df">Invoke method</a></dt><dt> <a
href="#N18f1">Advantages</a></dt><dt> <a href="#N18fa">Closing the first half of the
circle</a></dt></dl></dd><dt> <a href="#N1919">JMX - foundation of JBoss
infrastructure</a></dt><dd><dl><dt> <a href="#N191e">Introduction</a></dt><dt> <a
href="#N1927">JMX core components</a></dt><dt> <a href="#N1933">JBoss and
JMX</a></dt></dl></dd><dt> <a href="#N1943">ContainerInvoker - Container entry
point</a></dt><dd><dl><dt> <a href="#N1948">Introduction</a></dt><dt> <a
href="#N1957">ContainerInvoker in focus</a></dt></dl></dd><dt> <a
href="#N1a1a">Container</a></dt><dd><dl><dt> <a href="#N1a1f">Concepts</a></dt><dt> <a
href="#N1a2e">Container Factory</a></dt><dt> <a href="#N1a9a">Autom!
atic deployment</a></dt><dt> <a href="#N1ac4">EnterpriseContext</a></dt><dt> <a
href="#N1afa">Container's nuts and bolts</a></dt></dl></dd><dt> <a href="#N1c33">
Transaction support </a></dt><dd><dl><dt> <a href="#N1c38">Background</a></dt><dt> <a
href="#N1c45">JTS and JTA</a></dt><dt> <a href="#N1c61">Core
implementation</a></dt><dt> <a href="#N1c74">TxInterceptor</a></dt></dl></dd><dt> <a
href="#N1c82">Security</a></dt><dd><dl><dt> <a href="#N1c87">Authentication - checking
credentials</a></dt><dt> <a href="#N1cad">Authorization - checking access to
resources</a></dt><dt> <a href="#N1cd8">SecurityInterceptor</a></dt></dl></dd><dt> <a
href="#N1cf1">Tracing the call through container</a></dt></dl></dd><dt>9. <a
href="#N1d10">Howto</a></dt><dd><dl><dt> <a href="#N1d14">Running Tomcat with
JBoss</a></dt><dd><dl><dt> <a href="#N1d18">Goal</a></dt><dt> <a
href="#N1d23">Benefits</a></dt><dt> <a href="#N1d31">Requirements</a></dt><dt> <a
href="#N1d3c">How-to setup jboss for tomcat!
</a></dt><dt> <a href="#N1d9f">How-to build web applications for jboss and
tomcat</a></dt></dl></dd><dt> <a href="#N1df0">Running the Examples from Enterprise
JavaBeans, by Richard Monson-Haefel (Unix) </a></dt><dt> <a href="#N1ea2">JMX
Connector Description and HowTo</a></dt><dd><dl><dt> <a
href="#N1eb3">Introduction</a></dt><dt> <a href="#N1eee">Design of the JMX
Connector</a></dt><dt> <a href="#N1f71">How To use the JMX Connector</a></dt><dt> <a
href="#N2014">ToDo List</a></dt></dl></dd><dt> <a href="#N2041">How To us the Timer
MBean</a></dt><dd><dl><dt> <a href="#N2052">Introduction</a></dt><dt> <a
href="#N205b">Preparation</a></dt></dl></dd><dt> <a href="#N20f3">Deployment on
JBoss</a></dt><dd><dl><dt> <a href="#N2103">Introduction</a></dt><dt> <a
href="#N210f">J2EE Deployer</a></dt><dt> <a href="#N2130">The AutoDeployer as
helper</a></dt><dt> <a href="#N2148">Creating J2EE applications</a></dt></dl></dd><dt>
<a href="#N219c">JAAS Based Security in JBoss</a></dt><dd><dl!
><dt> <a href="#Introduction">Introduction</a></dt><dt> <a href="#jaas1">Security
>Model Overview</a></dt><dt> <a href="#jaas2">How to Associate Security With the
>Container SecurityInterceptor</a></dt><dt> <a href="#jaas3">Using
>JaasSecurityManager</a></dt><dt> <a href="#jaas4">The Session Beans</a></dt><dt> <a
>href="#jaas5">Deploying a Bean with Security</a></dt><dt> <a href="#N24c9">Wrap
>Up</a></dt></dl></dd><dt> <a href="#N24d2">Using JavaMail in
>JBoss</a></dt><dd><dl><dt> <a href="#N24e2">Introduction</a></dt><dt> <a
>href="#N24ea">Installation & Configuration</a></dt></dl></dd><dt> <a
>href="#N2554">How to Run JBoss in JBuilder's Debugger</a></dt><dd><dl><dt> <a
>href="#N2558">JBuilder Foundation 3.5</a></dt><dt> <a href="#N2596">JBuilder
>4</a></dt></dl></dd><dt> <a href="#N25d3">EJX/AWT Development
>HowTo</a></dt><dd><dl><dt> <a href="#N25e3">Introduction</a></dt><dt> <a
>href="#ejx1">EJX Insights</a></dt><dt> <a href="#N2623">The launcher</a></dt><dt> <a
>href="#N264e">T!
he bean context framework</a></dt><dt> <a href="#N265f">The bean context root and the
services</a></dt><dt> <a href="#N267f">Where the GUI comes in ?</a></dt><dt> <a
href="#ejx2">Getting strted with EJX</a></dt><dt> <a href="#ejx3">EJX/AWT GUI Basics
HowTo</a></dt></dl></dd><dt> <a href="#N281e">JBossCX
Configuration</a></dt><dd><dl><dt> <a href="#N282e">Introduction</a></dt><dt> <a
href="#N2841">Contents</a></dt><dt> <a href="#jca1">Terminology</a></dt><dt> <a
href="#jca2">JBoss Configuration</a></dt><dt> <a href="#jca3">Example - Black Box
Example Adapter from Sun</a></dt><dt> <a href="#jca4">Implementation
Status</a></dt></dl></dd><dt> <a href="#N2981">External JNDI Configuration and JNDI
Viewing</a></dt><dd><dl><dt> <a href="#N2991">How To Use the JNDI ExternalContext and
JNDIView MBeans</a></dt><dt> <a href="#N299d">Preparation of the ExternalContext
MBean</a></dt><dt> <a href="#N29d3">Preparation of the JNDIView MBean</a></dt><dt> <a
href="#N29e3">Using the JNDIView MB!
ean</a></dt></dl></dd></dl></dd></dl></div><div class="preface" id="Na35"><div
class="titlepage"><div><h2 class="title"><a
name="Na35"></a>Preface</h2></div></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="#Na37">Docbook</a></dt></dl></div><div
class="section"><a name="Na37"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Na37"></a><span
class="title">Docbook</span></h2></div></div><p>The approach of writing documentation
in HTML was inheretly problem infested. The content was "polluted" with
HTML presentational tags and such impossible to convert to any other view. Another
big issue was L&F
consistency. Despite the explicit instruction of which HTML tags to use, authors
couldn't keep up with all complexities
and issue faced when writing HTML documents. Documents were also hard to shuffle
around in a document book thus
leading to a very big maintance costs</p><p>After some considerate time spent
looking around, we came to the conclusion that Docbook initiative is the most
reasonable way to go. DocBook is a XML/SGML DTD that lets authors in technical
groups concentrate on the organization
and meaning of the documents they write.</p><p>Docbook XML DTD ,which we are using,
has accompanying XSL stylesheets that allow us to define different views of
Docbook-ed XML content i.e., all the presentation issues are solved through XSL
stylesheets. These stylesheets are
very flexible, well maintained, and allow easily customized hooks for specialized
home-brewed styles of views.</p><p>Simply put, you have xml tagged content, detached
from any fomatting issues, chunked into logical pieces, which
are then easily (re)arranged, put together, and in the end XSL stylesheet is applied
against it to create any
kind of presentational view.</p><p>Docbook DTD's are maintained by independent
consortium - <a href="http://www.oasis-open.org" target="_top"><i>OASIS</i></a>.
The principal maintainer of Docbook is <a href="http://www.nwalsh.com"
target="_top"><i>Norman Walsh</i></a> , a member of
XSL working group, Sun Microsystems employee.</p><p>Although Docbook DTD is very
big, 300 + elements, the learning curve is very steep, and most of the time not more
than 50 elements are used. This <a
href="http://www.caldera.de/~eric/crash-course/HTML" target="_top"><i>article</i></a>
is suitable for a first contact with Docbook. A good reference that you might want
to use can be found
<a href="http://www.docbook.org/tdg/html/docbook.html" target="_top"><i>here</i></a>
</p></div></div><div class="chapter" id="Na67"><div class="titlepage"><div><h2
class="title"><a name="Na67"></a>Chapter 1. First steps</h2></div></div><div
class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="#Na78">Introduction</a></dt><dd><dl><dt> <a href="#Na7c">What this section is
about</a></dt><dt> <a href="#Na85">About JBoss</a></dt><dt> <a
href="#Na94">Pre-requisites</a></dt></dl></dd><dt> <a href="#Naa1">Installing
JBoss</a></dt><dt> <a href="#Nae2">Creating the Bean</a></dt><dt> <a
href="#Naf8">EJBs: review</a></dt><dt> <a href="#Nb19">Coding the classes</a></dt><dt>
<a href="#Nb5a">The deployment descriptor</a></dt><dt> <a href="#Nbaf">Packaging and
deploying the bean</a></dt><dt> <a href="#Nbfb">Coding the test client</a></dt><dt> <a
href="#Nc42">Compiling and running test client</a></dt></dl></div><p>Author:
<span class="author">Kevin Boone</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="Na78"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="Na78"></a><span
class="title">Introduction</span></h2></div></div><div class="section"><a
name="Na7c"></a><div class="titlepage"><div><h3 class="title"><a name="Na7c"></a><span
class="title">What this section is about</span></h3></div></div><p>
This section presents a step-by-step tutorial on how to set up `JBoss', the
free Enterprise JavaBean (EJB) server, and create your first
Enterprise JavaBean and client. It doesn't explain what Enterprise JavaBeans
are, or how they are used; there are a number of good
introductory articles on Sun's JavaSoft Web site. Although the description is
based on the use of a Linux server, most of the issues discussed in
this article will also apply to other platforms. If you are using a Windows
platform you will need to pay attention to the directory names, which
will be different from the one's I've assumed.
</p></div><div class="section"><a name="Na85"></a><div class="titlepage"><div><h3
class="title"><a name="Na85"></a><span class="title">About
JBoss</span></h3></div></div><p>
JBoss is an implementation of the EJB 1.1 specification, that is, it is a
server and container for Enterprise JavaBeans. In this it is similar to Sun's
`J2SDK Enterprise Edition' (J2EE), but JBoss is much more single-minded than
J2EE. JBoss provides only an EJB server; it does not include
support for JSP, SSL, and all the other protocols that the Sun product can
handle. This means that it is smaller in memory and in disk space.
JBoss will run very effectively on a machine with 64 megabytes of RAM, and
requires only some megabytes of disk (including source code!). Sun's
J2EE requires a minimum of 128 megabytes of RAM, and 31 megabytes of disk
space. That's not to criticise the Sun product; it is a
heavyweight offering providing a host of services. Because of its small memory
footprint, JBoss starts up about 10 times faster than J2EE.
There is a built-in SQL database server for handling persistent beans, and
this starts up automatically with the server (J2EE ships with the
CloudScape SQL server, which has to be started separately).
</p><p>
One of the nicest features of JBoss is its support for `hot'
deployment. What this means is that deploying a Bean is a simple as copying its
JAR file into the deployment directory. If this is done while the Bean is
already loaded, JBoss automatically unloads it, then loads the new
version. Contrast this with the rigmarole that J2EE makes us go through...
JBoss is distributed under the GNU public licence, which means that
it's free, even for commercial work, and is likely to remain that way. You get
no support, of course.
</p><p>
The main weakness of JBoss is its documentation. There is, essentially,
none. There is a mailing list, and you will almost certainly need
recourse to it at some point. This article hopes to remedy this deficiency, to
a small degree, by describing step-by-step how a simple EJB can
be created, deployed and tested on the JBoss server.
</p></div><div class="section"><a name="Na94"></a><div class="titlepage"><div><h3
class="title"><a name="Na94"></a><span
class="title">Pre-requisites</span></h3></div></div><p>
JBoss is written entirely in Java, and requires a Java system compatible with
JDK 1.3. This is essential, not optional. Trust me on this; I've tried
it with JDK 1.2.2 and the `hot' deployment facility simply doesn't work. Since
it is now possible to get Linux JDKs directly from Sun, there's
little reason not to upgrade if you're using an earlier version. A word of
warning: although Sun provide an RPM distribution as well as the
traditional gzipped tar, the RPM version does not unpack, so don't waste time
downloading the 34 megabytes it requires. Use the tar version
and un-tar it as normal. </p><p>
I will assume that you are basically familiar with EJBs (and roughly know, for
example, what a `home interface' is) and know how to compile Java
classes.
</p></div></div><div class="section"><a name="Naa1"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="Naa1"></a><span
class="title">Installing JBoss</span></h2></div></div><p>Before installing and running
the server, you should check that your JDK
installation is working. (Step-by-step instructions are available.) You will
need the JDK binaries directory in your PATH (this is essential: see below)
not just for the user account which is doing the installation, but also for
the user account that will run the server. If you are running the server as
root, you should check that the JDK binaries are in the PATH even for root
(root and ordinary users normally have different PATH settings). You won't
need to specify a CLASSPATH environment variable if you don't normally have
to.</p><p>The next step will be to download, install and test the JBoss server. At
the time of writing the most recent version of JBoss is 2.0.</p><p>It doesn't matter
very much where you install JBoss; my preference is to
use /usr/local/jboss. If you don't have root access, or would rather not run
untested software as root, jboss will work perfectly well if installed in a
user directory and run as an ordinary user. I will assume in this tutorial
that you are installing in /usr/local/jboss. If you haven't, change the paths
as appropriate.</p><p>JBoss is distributed as a ZIP file. You can download the binary
distribution which contains the latest offical release (which was 2.0
FINAL at the time of writing) or a source snapshot with the latest
version from CVS (called PRE2.1). This documentation mainly is written
for the 2.0
version. You can get all the mentioned packages from http://www.jboss.org .
</p><p><b>Installation of binary package for Windows:</b> Download the binary
package from http://www.jboss.org from the
Download - Binary section. Place it in a temporary directory and use your
favorite unziper to decompress it to the place where you want JBoss
installed. Start the "command line" from "Accessories" menu and change to
the directory to which you just decompressed the binary package. In
the following descriptions you will need to replace /usr/local/jboss/
with the path you selected to install JBoss to (e.g. c:\jboss\ ). Also
note that Windows is not using a colon “:” but a
semicolon “;” to separate
multiple entries in paths (e.g. the CLASSPATH).
</p><p><b>Installation of binary package for Linux:</b> <div
class="literallayout"><b>cd /tmp/<br>
lynx -source http://www.jboss.org/newsite/bin/jBoss-2.0_FINAL.zip > jBoss-2.0_FINAL.zip<br>
su<br>
cd /usr/local/<br>
unzip /tmp/jBoss-2.0_FINAL.zip<br>
mv jBoss-2.0_FINAL jboss<br>
cd jboss<br>
</b></div>
</p><p>Now change to the user as which you want to run the
server. Please make sure, that this user has the JDK binaries in his
command path and that he has write access to the JBoss directory
(needed for log files and deployment).
You are now ready to change to the bin directory, and
run the program like this: </p><div class="literallayout"><b>cd bin<br>
java -jar run.jar</b><br>
</div><p>In a proper installation, the server should start without any error
messages or exceptions being thrown. It will produce several pages of
output on startup.</p></div><div class="section"><a name="Nae2"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="Nae2"></a><span
class="title">Creating the Bean</span></h2></div></div><p>
In this step we will write and compile a simple Enterprise JavaBean. You can
download the source code for this example; according to which unpacker
(WinZIP, unzip, tar) you have available either download
interestEJB.zip or interestEJB.tar.gz from the file section in the
documentation section on www.jboss.org . You will need to
unpack the archive into an empty directory.</p><p>The example -- which is called
`Interest' -- is about as simple as an
EJB can get: it is a `stateless session bean'. Its job is to calculate the
amount of compound interest payable on a sum of money borrowed over a
specified term with a specified interest rate. In fact, there is only one
functional line of code in the whole package.</p><p>If you want to compile the
classes yourself, you'll need to create a
directory hierarchy that reflects the structure of the pacakage. The package
in this example is com.web_tomorrow.interest so you'll need to create the
directory structure:
<div class="literallayout"><br>
com<br>
web_tomorrow<br>
interest<br>
{java source and class files here}<br>
<br>
</div>
If you unpack the interestEJB-archive it will create a subdirectory
called "interest" and the needed structure automatically below it.</p></div><div
class="section"><a name="Naf8"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Naf8"></a><span class="title">EJBs:
review</span></h2></div></div><p> As a reminder, and Enterprise JavaBean has a minimum
of three
classes.The remote interface. This is the class that exposes the methods of
the Bean to the outside world. In the example, the remote interface is the
class com.web_tomorrow.interest.Interest The Bean class. This implements the
methods specified by the remote interface. In this example, the Bean class is
com.web_tomorrow.interest.InterestBean The home interface. This specifies how
a new Bean is created, managed and deleted. As a minimum it should specify at
least one create() method. There should be an ejbCreate() method in the Bean
class for each create() method in the home interface. In this example, the
home interface is com.web_tomorrow.InterestHome </p><p> Of course, a Bean can
include other classes, or even other packages,
but the classes listed above are the minimum. The classes must be packaged
into a JAR archive with a directory structure that reflects the hierarchy of
packages. In the example, the classes are in the package
com.web_tomorrow.interest, so they need to be in the directory
</p><p>./com/web_tomorrow/interest/</p><p>where the `.' represents the current working
directory, wherever that
is. You will also need a directory called META-INF to store the deployment
descriptor (always called ejb-jar.xml) and -- optionally -- another XML file
to tell the server about name mappings. With JBoss, this file must be called
jboss.xml.</p><p>So before writing the classes, we need a directory structure like
this:
<div class="literallayout"><br>
com<br>
web_tomorrow<br>
interest<br>
{java source and class files here}<br>
<br>
META-INF<br>
ejb-jar.xml<br>
jboss.xml (optional)<br>
<br>
</div>
</p><p>If the jar utility is run at the top level of this directory structure,
it will put the files in the right ordering in the archive. We will discuss
the creation of the XML files later.</p><p>Of course, in your own work you will
create a directory hierarchy that
reflect the package hierarchy you need, rather than `com.web_tomorrow.XXXX'
</p></div><div class="section"><a name="Nb19"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="Nb19"></a><span class="title">Coding the
classes</span></h2></div></div><p>We need three classes: the remote interface, the
Bean, and the home
interface. All the .java files will go in the subdirectory
./com/web_tomorrow/interest.
The remote interface in this example is very simple.
</p><div class="figure"><p><a name="Nb21"></a><b>Figure 1.1. Remote interface for
the `interest' EJB</b></p><pre class="programlisting">
package com.web_tomorrow.interest;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
/**
This interface defines the `Remote' interface for the `Interest' EJB. Its
single method is the only method exposed to the outside world. The class
InterestBean implements the method.
*/
public interface Interest extends EJBObject
{
/**
Calulates the compound interest on the sum `principle', with interest rate per
period `rate' over `periods' time periods. This method also prints a message to
standard output; this is picked up by the EJB server and logged. In this way we
can demonstrate that the method is actually being executed on the server,
rather than the client.
*/
public double calculateCompoundInterest(double principle,
double rate, double periods) throws RemoteException;
}
</pre></div><p> The remote interface specifies only one `business method'
calculateCompoundInterest. The home interface is even simpler. </p><div
class="figure"><p><a name="Nb30"></a><b>Figure 1.2. Home interface for the `interest'
EJB</b></p><pre class="programlisting">
package com.web_tomorrow.interest;
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
/**
This interface defines the `home' interface for the `Interest' EJB.
*/
public interface InterestHome extends EJBHome {
/**
Creates an instance of the `InterestBean' class on the server, and returns a
remote reference to an Interest interface on the client.
*/
Interest create()
throws RemoteException, CreateException;
}
</pre></div><p>Finally, here is the Bean class. This is the only one that does any
real
work in this simple example.</p><div class="figure"><p><a name="Nb3f"></a><b>Figure
1.3. Bean class for the `interest' EJB</b></p><pre class="programlisting">
package com.web_tomorrow.interest;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
/**
This class contains the implementation for the `calculateCompoundInterest'
method exposed by this Bean. It includes empty method bodies for the methods
prescribe by the SessionBean interface; these don't need to do anything in this
simple example.
*/
public class InterestBean implements SessionBean {
/**
Calulates the compound interest on the sum `principle', with interest rate
per period `rate' over `periods' time periods. This method also prints a
message to standard output; this is picked up by the EJB server and logged.
In this way we can demonstrate that the method is actually being executed on
the server, rather than the client.
*/
public double calculateCompoundInterest(double principle,
double rate, double periods) {
System.out.println ("Someone called `calculateCompoundInterest!'");
return principle * Math.pow(1+rate, periods) - principle;
}
/**
Empty method body
*/
public InterestBean() {}
/**
Empty method body
*/
public void ejbCreate() {}
/**
Empty method body
*/
public void ejbRemove() {}
/**
Empty method body
*/
public void ejbActivate() {}
/**
Empty method body
*/
public void ejbPassivate() {}
/**
Empty method body
*/
public void setSessionContext(SessionContext sc) {}
}
</pre></div><p>Notice that most of the methods are empty; they have to exist because
they're specified by the SessionBean interface, but they don't need to do
anything in this case.</p><p>If you haven't already done so, you should create these
.java files in
the directory com/web_tomorrow/interest (or unpack the archive with them
in). Then you can compile them using the command
<b>javac -classpath /usr/local/jboss/client/ejb.jar
com/web_tomorrow/interest/*.java</b>
</p><p>
Substituting the correct path to the JBoss class EJB library if you haven't
installed JBoss in /usr/local/jboss. This should create three class files:
InterestBean.class, Interest.class, and InterestHome.class.
With the classes compiled, it's time to create the deployment
descriptor.</p></div><div class="section"><a name="Nb5a"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="Nb5a"></a><span
class="title">The deployment descriptor</span></h2></div></div><p>Now it's time to
create the deployment descriptor. As a reminder, this
file tells the EJB server which classes form the Bean, the home interface and
the remote interface. If there is more than one Bean in the package, it
indicates also how the Beans interact with one another. In this simple
example, there is only one Bean so we won't need to worry about that
part.</p><p>Most commercial EJB servers are supplied with graphical tools for
constructing the deployment descriptor. JBoss does have an XML editor, but
it's just as easy to construct the deployment descriptor manually. Here it
is:</p><div class="figure"><p><a name="Nb65"></a><b>Figure 1.4. Deployment
descriptor for the Interest Bean</b></p><div class="literallayout"> <br>
<?xml version="1.0" encoding="Cp1252"?><br>
<ejb-jar><br>
<description>JBoss test application</description><br>
<display-name>Test</display-name><br>
<enterprise-beans><br>
<session><br>
<ejb-name>Interest</ejb-name><br>
<home>com.web_tomorrow.interest.InterestHome</home><br>
<remote>com.web_tomorrow.interest.Interest</remote><br>
<ejb-class>com.web_tomorrow.interest.InterestBean</ejb-class><br>
<session-type>Stateless</session-type><br>
<transaction-type>Bean</transaction-type><br>
</session><br>
</enterprise-beans><br>
</ejb-jar> <br>
<br>
</div></div><p>The deployment descriptor must be called ejb-jar.xml and it must be
in
the directory ./META-INF. A common mistake is to name this directory
`META_INF' (with an underscore, rather than a dash) or write it lower
case, which won't work.</p><p> In principle what we deploy on the server is an
application, not a
Bean. In this example our application consists of exactly one Bean, so it
comes to the same thing. In the deployment descriptor, the section
<ejb-name>Interest</ejb-name> assigns a name to the Bean. jboss
in its
standard configuration will put the bean's home interface under the ejb-name
moniker if you don't specify anything else. In other words, when your
applications want to access the bean through it's home jboss will put it in
JNDI under the ejb-name. </p><p>In practice client applications are not forced to
use this name.
Typically a developer will not bother with specifying a different name for the
JNDI namespace. However a production installation of a complete application
comprising many beans, will usually use a different name than the one
specified by the developer. Typically it could use `[application name]/[bean
name]', which is what we shall use later.</p><p>Although the deployment descriptor
format of the ejb-jar.xml file is
common to all EJB servers, and precisely defined in a DTD you can get from
SUN, it doesn't specify some advanced stuff. Specifically it does not know how
to map ejb-name to a deployment JNDI such as the one we just talked about. It
also doesn't know how to map resources. The server may also need to be told
how to manage persistence and state. There is, as yet, no standard way of
specifying these things, and every server implementation does it differently.
</p><p>The approach taken by JBoss is it provides a standard behaviour that
works mostly from the ejb-jar.xml file. There is no need for additional
information in most cases. In case of advanced configurations we define the
jboss.xml file that gives all the relevant information to the container, such
as JNDI mapping names, persistence information, database mapping and advanced
container configuration (interceptors and plugins), please refer to the
section on jboss.xml for detailed information of what it can do, we will cover
simple things here. </p><p>The standard behaviour of jboss is capable of working
from ejb-jar.xml
in 95% of cases and needs jboss.xml only if you need to specify specific
deployment information. </p><p>An additional feature of the new metadata is that it
works
"differentially". In clear what this means is that if you wish to override the
name of a bean you need to only specify that part of xml tags in the jboss.xml
file.</p><p>Using the ejb-name from ejb-jar.xml
for most development purposes, as soon as you provide a ejb-jar.xml with the
beans the container will get the ejb-name as the JNDI name as standard
behaviour. This makes your development life easier.</p><p>If you don't provide a
jboss.xml file you will find your bean under the
name "Interest".</p><p>Overriding ejb-name with a real JNDI name in
jboss.xml</p><p>If in deployment you would rather use the "myApp/myBean" naming
pattern
you need to provide the following text in jboss.xml. </p><p>jboss.xml: ()</p><div
class="figure"><p><a name="Nb97"></a><b>Figure 1.5. The JBoss XML descriptor.
(Optional, this file is provided by
the Bean deployer)</b></p><div class="literallayout"> <br>
<jboss><br>
<enterprise-beans><br>
<session><br>
<ejb-name>Interest</ejb-name><br>
<jndi-name>interest/Interest</jndi-name><br>
</session><br>
<secure>false</secure><br>
</enterprise-beans><br>
</jboss><br>
<br>
</div></div><p>All this file says is that the Bean called Interest is assigned the
JNDI
name of interest/Interest.</p><p>The indentation is just there for formatting and
readability, it is non
important.</p><p>So now we've got the deployment descriptor ejb-jar.xml. Again jboss
will
happily run just from that file and bind the object under "Interest" as
standard JNDI name. We also have the optional jboss.xml to provide another
name "interest/Interest" to overwrite the standard behaviour with JNDI. We
also have the classes. It's time to package them together.</p></div><div
class="section"><a name="Nbaf"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="Nbaf"></a><span class="title">Packaging and deploying the
bean</span></h2></div></div><p>Creation of the Bean package involves building a JAR
archive containing
the classes and the XML files. For the example Bean we have been discussing,
this is straightforward; at the top of the directory hierarchy run jar like
this:</p><div class="literallayout"><b><br>
jar cvf interest.jar com/web_tomorrow/interest/Interest.class \<br>
com/web_tomorrow/interest/InterestHome.class \<br>
com/web_tomorrow/interest/InterestBean.class \<br>
META-INF<br>
</b></div><p>If you have `make' on your system, and you have unpacked the source
code
arhive, you can get the same effect simply by executing `make package'. I
strongly recommend using Makefiles or shell scripts to do these operations
because in practice you will be repeating them many times during development
jar builds an archive containing the three classes, and the XML files in the
META-INF directory. If you list the contents of the archive you should see
something like this:</p><div class="literallayout"><tt><br>
0 06-16-00 11:34 META-INF/<br>
72 06-16-00 11:35 META-INF/MANIFEST.MF<br>
248 06-16-00 10:12 com/web_tomorrow/interest/Interest.class<br>
300 06-16-00 10:12 com/web_tomorrow/interest/InterestHome.class<br>
877 06-16-00 10:12 com/web_tomorrow/interest/InterestBean.class<br>
549 06-15-00 18:15 META-INF/ejb-jar.xml<br>
3597 06-15-00 17:20 META-INF/jboss.xml<br>
</tt><br>
</div><p>Note that the directory structure must be exactly like this, or it won't
work. Again a common mistake is to do a META_INF (underscore) or meta-inf
(lower case) instead of
META-INF, be careful with this one.</p><p>To deploy the Bean on the server, all
that's necessary is to copy the
.jar file to the `deploy' directory on the server, e.g.,
<b>cp interest.jar /usr/local/jboss/deploy </b></p><p>You can do this as often as
you like; the server will detect that the
file has changed and automatically re-deploy it. During deployment you should
see the following messages from the server: </p><div class="literallayout"><tt><br>
[Auto deploy] Auto deploy of file:/usr/local/jboss/deploy/interest.jar<br>
[Container factory] Deploying:file:/usr/local/jboss/deploy/interest.jar<br>
[Container factory] Deploying Interest<br>
[Container factory] Started: Interest<br>
[Container factory] Bound Interest to interest/Interest<br>
[Container factory] Deployed application: <br>
file:/usr/local/jboss/deploy/interest.jar <br>
</tt></div><p>If you see a message like this: </p><div class="literallayout"><tt><br>
[Container factory] Deploying:file:/usr/local/jboss/deploy/interest.jar<br>
[Container factory] Deployed application <br>
file:/usr/local/jboss/deploy/interest.jar <br>
</tt><br>
</div><p>then no Beans have been deployed -- the server always reports the Beans
that it detects. This usually means that the deployment descriptor ejb-jar.xml
is badly structured, or missing, or in the wrong directory. Note that the
server doesn't need to have the CLASSPATH set with your classes it is done
automatically from the deploy directory.</p><p>If everything has gone according to
plan, you should now have a Bean
deployed on the server. We will now create a simple test client that runs one
of its methods, just to prove that it's working.</p></div><div class="section"><a
name="Nbfb"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="Nbfb"></a><span class="title">Coding the test
client</span></h2></div></div><p>An EJB on its own is no use; we will need at least a
simple client to
use its services. A user of EJBs may be another EJB, and ordinary JavaBean, a
JSP page, an applet, or a stand-alone application. In this example, for
simplicity, we will code a simple application. This application will create an
object of class Interest, and execute its one method.</p><p>Upon "deployment" of the
bean as we have seen in the previous step, the
server has generated all the stubs and skeletons needed for the distributed
calls. What we are going to cover here is the way you lookup a reference in
JNDI from a client and invoke it. It is pretty straightforward.</p><p>Here is the
test client:</p><div class="figure"><p><a name="Nc09"></a><b>Figure 1.6. Test
client</b></p><pre class="programlisting">
import javax.naming.*;
import com.web_tomorrow.interest.*;
import java.util.Hashtable;
import javax.rmi.PortableRemoteObject;
import com.web_tomorrow.interest.*;
/**
This simple application tests the `Interest' Enterprise JavaBean which is
implemented in the package `com.web_tomorrow.interest'. For this to work, the
Bean must be deployed on an EJB server.
IMPORTANT If you want to test this in a real client-server
configuration, this class goes on the client; the URL of the naming provider
specifed in the class must be changed from `localhost:1099' to the URL of the
naming service on the server
*/
class InterestClient {
/**
This method does all the work. It creates an instance of the Interest EJB on
the EJB server, and calls its `calculateCompoundInterest()' method, then
prints
the result of the calculation.
*/
public static void main(String[] args) {
// Set up the naming provider; this may not always be necessary, depending
// on how your Java system is configured.
System.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
System.setProperty("java.naming.provider.url",
"localhost:1099");
// Enclosing the whole process in a single `try' block is not an ideal way
// to do exception handling, but I don't want to clutter the program up
// with catch blocks
try {
// Get a naming context
InitialContext jndiContext = new InitialContext();
System.out.println("Got context");
// Get a reference to the Interest Bean
// This is in the case you use the jboss.xml to override the JNDI name
Object ref = jndiContext.lookup("interest/Interest");
// If you didn't use the jboss.xml the following will work
// Object ref = jndiContext.lookup("Interest");
System.out.println("Got reference");
// Get a reference from this to the Bean's Home interface
InterestHome home = (InterestHome)
PortableRemoteObject.narrow (ref, InterestHome.class);
// Create an Interest object from the Home interface
Interest interest = home.create();
// call the calculateCompoundInterest() method to do the calculation
System.out.println
("Interest on 1000 units, at 10% per period, compounded over 2 periods
is:");
System.out.println (interest.calculateCompoundInterest (1000, 0.10, 2));
} catch(Exception e) {
System.out.println(e.toString());
}
}
}
</pre></div><p>It's important to understand that in reality this client will be
running
on a different computer to the Bean server. For testing you will probably run
them on the same computer, but it will still be using a network connection. So
the first part of the program indicates how to find the server. </p><p><pre
class="programlisting">System.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
System.setProperty("java.naming.provider.url",
"localhost:1099"); </pre></p><p>There are several other ways to do this, which
you may see described in
other sections. In this case, the server is on the same machine as the client
(`localhost') and the default naming port is `1099' for JBoss (other servers
may use different port numbers). If you run the client and the server on
different machines, you will need to change these settings.</p><p>The comments in
the program should describe how it works; one point that
requires mention is that the recommended way to get a reference to the home
interface on the server is like this: </p><p>
<pre class="programlisting">InterestHome home = (InterestHome)
PortableRemoteObject.narrow (ref, InterestHome.class);
</pre>
which ensures compatibility with different RMI servers (e.g., CORBA). `narrow'
ensures that the object returned in `ref' really can be converted to an object
of class `InterestHome'.</p><p>The test client doesn't need to be in the same
package as the EJB
classes, and in practice it probably won't be. So it needs to import the EJB
classes using their fully-qualified class name, like this: </p><p>
<tt>import com.web_tomorrow.interest.*; </tt>
</p><p>You will also need to pay attention to the CLASSPATH when compiling.
Even though the EJB classes will run on the server, they need to be identified
to the client so that the compiler can do the appropriate type checking. In
the example program I have put the client at the top level of the directory
hierachy, so if the CLASSPATH includes the current directory it will correctly
find the EJB classes which are in the directories beneath it. </p><p><b>javac
-classpath /usr/local/jboss/client/ejb.jar:.
InterestClient.java</b></p><p>This generates InterestClient.class in the current
directory. </p></div><div class="section"><a name="Nc42"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="Nc42"></a><span
class="title">Compiling and running test client</span></h2></div></div><p>We're now
ready to run the test client, but first a word of
explanation.</p><p>In reality the client and the server are likely to be on
different
computers. When you compile the client, the compiler needs to know about the
organization and methods of classes in the Bean so it can do type checking.
When you run the client, the run-time engine needs to know about the Bean
classes, because type-casting is done at run-time. So when the client attempts
to cast the remote reference to a reference to an object of class InterestHome
for example, it needs to know about this class. This means that you will need
the Bean class files on both the client and the server even though they
execute on the server. This is fairly obvious if you think about the logic,
but it causes all sorts of problems for people who are new to RMI programming.
If the client can't find the Bean classes, you will get error messages like
this:</p><div class="literallayout"><br>
<tt>javax.naming.CommunicationException [Root exception is <br>
java.lang.ClassNotFoundException: com.web_tomorrow.interest.InterestHome]<br>
</tt></div><p>A 'communication exception' is the exception that represents any error
that can't readily be ascribed to a definite cause. If you get this message
you need to pay attention to the CLASSPATH on the client. NOTE that the server
doesn't need to have the classpath set, you just need to put it in the deploy
directory and the server will generate a ClassLoader for it.</p><p>If the client
program is at the top of the directory hierarchy, with the
Bean classes below it, then we can run it like this:</p><div
class="literallayout"><b><br>
java -classpath $CLASSPATH:\<br>
/usr/local/jboss/client/ejb.jar:/usr/local/jboss/client/jboss-client.jar \ <br>
InterestClient</b><br>
<br>
</div><p>Once again, this needs to go in a shell script or a Makefile; you won't
want to type it more than once.</p><p>Note the long CLASSPATH; it needs to include
the JBoss client classes
and the EJB classes as well as the standard classpath (if any).
If all is well, the test client produces the following output: </p><div
class="literallayout"><tt><br>
Got context<br>
Got reference<br>
Interest on 1000 units, at 10% per period, compounded over 2 periods is:<br>
210.00000000000023<br>
</tt><br>
</div><p>If it doesn't produce this output but you see a "MalformedURLException"
try installing jboss in another directory that doesn't contain space in it's
path (typically some installations on windows don't like C:\Program Files (the
space).</p><p>Another common problem you can see here is a "class not found
exception"
make sure you include all the jars.</p><p>The Bean should produce an output on the
server as well; this is to show
that the Bean has executed on the server, not the client. Look for something
like this in the server log: </p><p>
<tt>
[Interest] Someone called `calculateCompoundInterest!'
</tt>
</p><p>Well, that's it. We covered coding, compiling and deploying the Bean,
and coding and running a simple test client. If you found this article useful,
drop me a line at [EMAIL PROTECTED]; if there's enough response I may
be persuaded to produce some more sophisticated tutorials.</p></div></div><div
class="chapter" id="Nc8f"><div class="titlepage"><div><h2 class="title"><a
name="Nc8f"></a>Chapter 2. Basic configuration</h2></div></div><div
class="toc"><p><b>Table of Contents</b></p><dl><dt> <a href="#Nc9f">In a
nutshell</a></dt><dd><dl><dt> <a href="#Nca6">Important Directories</a></dt><dt> <a
href="#Ncae">Executables</a></dt><dt> <a href="#Ncbb">Configuration</a></dt><dt> <a
href="#Ncc3">Libraries</a></dt><dt> <a href="#Nccb">EJBs</a></dt><dt> <a
href="#Ncd3">Client Libraries</a></dt><dt> <a href="#Ncdb">Configuration
Files</a></dt><dt> <a href="#Nd3e">Clients on Remote
Machines</a></dt></dl></dd></dl></div><p>Author:
<span class="author">Aaron Mulder</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="Nc9f"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="Nc9f"></a><span class="title">In a
nutshell</span></h2></div></div><p>
JBoss ships preconfigured, so there's nothing you need to do to get it up and
running with the test beans. However, you
will likely need to make minor configuration changes to support your specific
applications. This section gives an
overview of the configuration files and directories. The Advanced Configuration
section gives detailed instructions for
specific configuration changes you may require. The Appendix contains DTDs for the
configuration files, which gives the
exact information.</p><div class="section"><a name="Nca6"></a><div
class="titlepage"><div><h3 class="title"><a name="Nca6"></a><span
class="title">Important Directories</span></h3></div></div><p>
The directory names given here are all relative to the directory you installed JBoss
into.</p></div><div class="section"><a name="Ncae"></a><div class="titlepage"><div><h3
class="title"><a name="Ncae"></a><span
class="title">Executables</span></h3></div></div><p>
Executables are located in the bin directory. Using the Batch (Windows) or Shell
(UNIX) scripts here, you can start the
server or run the test bean client. You can also run the EJX deployment descriptor
editor by double-clicking on it (if
your platform supports that) or issuing the command:
<b>
java -jar ejx.jar
</b>
</p></div><div class="section"><a name="Ncbb"></a><div class="titlepage"><div><h3
class="title"><a name="Ncbb"></a><span
class="title">Configuration</span></h3></div></div><p>
Configuration files are located in the conf directory. These files configure the
server as a whole, so the settings here will
be the same for all EJBs.</p></div><div class="section"><a name="Ncc3"></a><div
class="titlepage"><div><h3 class="title"><a name="Ncc3"></a><span
class="title">Libraries</span></h3></div></div><p>
Java libraries are located in the lib directory. They should use either the ZIP or
JAR format. All libraries in this directory
will automatically be added to the server classpath. Again, this should only be used
for libraries which need to be
available to all EJBs; there are alternatives for libraries that should be available
to individual EJB JARs (see The
Manifest File in the Deploying EJBs in jBoss section).</p></div><div
class="section"><a name="Nccb"></a><div class="titlepage"><div><h3 class="title"><a
name="Nccb"></a><span class="title">EJBs</span></h3></div></div><p>
EJB JARs you want to deploy go in the deploy directory. If the server is running,
they will be deployed automatically. If
you delete a JAR it will be undeployed, and if you update it it will be
redeployed.</p></div><div class="section"><a name="Ncd3"></a><div
class="titlepage"><div><h3 class="title"><a name="Ncd3"></a><span class="title">Client
Libraries</span></h3></div></div><p>
Libraries required for clients are in the client directory. A typical client
requires jboss-client.jar,
jnp-client.jar, ejb.jar, and jta-spec1_0_1.jar. If you client is not running JDK
1.3, it will require
jndi.jar as well.</p></div><div class="section"><a name="Ncdb"></a><div
class="titlepage"><div><h3 class="title"><a name="Ncdb"></a><span
class="title">Configuration Files</span></h3></div></div><p>
There are a number of configuration files for jBoss. The contents of each are give
here, though you should refer to the
Advanced Configuration section and the DTDs section of the Appendix for details on
the specific settings.</p><p>
You may create more than one set of configuration files as long as the base filename
is the same for all files in the set
and the extensions are not changed. For example, you could copy jboss.conf,
jboss.jcml, ... to
myconfig.conf, myconfig.jcml, ... To start jboss with a different set of
configuration files, add the base name
of the configuration file set to the command or script you use to start jBoss (for
example, "run.sh myconfig").</p><div class="table"><p><a name="Nce5"></a><b>Table 2.1.
Configuration files</b></p><table summary="Configuration files"
border="1"><thead><tr><th>File</th><th>Description</th></tr></thead><tbody><tr><td>jboss.conf</td><td>Lists
server components that should be loaded. Each must be a JMX
MBean</td></tr><tr><td>jboss.jcml</td><td>Lists configuration parameters for the
server components loaded in
jboss.conf</td></tr><tr><td>jboss.properties</td><td>Provides parameters to the Java
runtime (the entries here become system
properties)</td></tr><tr><td>jboss.dependencies</td><td>Lists dependencies between the
MBeans loaded in jboss.conf, so they can be loaded and
stopped in the correct
order</td></tr><tr><td>jnp.properties</td><td>Lists properties for the JNDI server
implementation</td></tr><tr><td>jndi.properties</td><td>Lists properties for the JNDI
client implementation. You can achieve the same thing by
hardcoding the properties, passing them on the command line, or
putting this file on the client
classpath. We recommend putting this on the classpath since it is
easiest to use and easiest to
change. You have to hardcode the properties if you want to look up
beans on more than one
server, though.</td></tr><tr><td>server.policy</td><td>The default
security policy for the jBoss server. Currently, this is set to allow all permissions.
In
a future release it will be locked down
more.</td></tr></tbody></table></div></div><div class="section"><a
name="Nd3e"></a><div class="titlepage"><div><h3 class="title"><a name="Nd3e"></a><span
class="title">Clients on Remote Machines</span></h3></div></div><p>
The default configuration assumes client will run on the same machine as the jBoss
server. While often appropriate for
servlet and JSP clients, you need to make minor changes to support remote
clients.</p><div class="orderedlist"><ol type="1"><li><p><a name="Nd4b"></a>Change
jboss.properties. The properties java.rmi.server.useLocalHostName and
java.rmi.server.hostname should either both be commented out, or
useLocalHostName should be
set to true and hostname should be set to the host name of your server (the
name you want your clients to
use, if your server has more than one). </p></li><li><p><a name="Nd4f"></a>Set
the JNDI properties for your clients appropriately. If you choose to put
jndi.properties on the client classpath
(which is recommended), you should change the value for
java.naming.provider.url to the host
name of your server (again, the name you want your clients to use).
</p></li></ol></div></div></div></div><div class="chapter" id="Nd57"><div
class="titlepage"><div><h2 class="title"><a name="Nd57"></a>Chapter 3. JDBC/Database
configuration</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>
<a href="#Nd67">Introduction</a></dt><dd><dl><dt> <a href="#Nd6b">Data
Sources</a></dt><dt> <a href="#Nd79">Mappings Available for CMP Entities</a></dt><dt>
<a href="#Nd81">Installing JDBC Drivers</a></dt></dl></dd><dt> <a
href="#Nda1">Creating DB Connection Pools</a></dt><dd><dl><dt> <a href="#Ndab">The
JDBC 2.0 Optional Package</a></dt><dt> <a href="#Ndcb">Configuration File
Changes</a></dt><dt> <a href="#Nec8">Connection Pool Configuration Examples and Driver
Notes</a></dt><dt> <a href="#N10eb">Changes for newer versions than 2.0
FINAL</a></dt></dl></dd></dl></div><p>Author:
<span class="author">Aaron Mulder</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="Nd67"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="Nd67"></a><span
class="title">Introduction</span></h2></div></div><div class="section"><a
name="Nd6b"></a><div class="titlepage"><div><h3 class="title"><a name="Nd6b"></a><span
class="title">Data Sources</span></h3></div></div><p>
One of the most common requirements is to create one or more data sources for your
EJBs. You must create a data source for CMP entity beans, and it is
the recommended way to interact with a database for BMP entity beans and session
beans.</p><p>
JBoss data sources provide database connection pooling. This means that when your
application closes a connection, it is not really closed, just returned
to the "ready" state. The next time your application requests a database connection,
it may reuse the same connection. This saves you the overhead of
opening new database connections for every request, and since normal web
applications use connections very often but for a very short period of time,
the savings can be significant. However, there are some new issues raised such as
the fact that a database connection that is left unused in the pool for a
long period of time may timeout. The JBoss pools have a number of configuration
parameters to address issues like this.</p><p>
Supported Databases
JBoss supports any database with a JDBC driver. We recommend pure java drivers (type
3 or type 4), and specifically suggest you do not use the
JDBC-ODBC bridge (type 1).</p></div><div class="section"><a name="Nd79"></a><div
class="titlepage"><div><h3 class="title"><a name="Nd79"></a><span
class="title">Mappings Available for CMP Entities</span></h3></div></div><p>
If we have not worked with a database product before we may need to work with you to
generate a type mapping if you plan to use container managed
persistence. The mappings we have tested extensively include PostgreSQL, InstantDB,
Hypersonic SQL, Oracle 7, Oracle 8, Sybase, DB2, and
InterBase. Additional contributed mappings include PointBase, SOLID, mySQL, MS SQL
Server, and DB2/400. If you would like to support CMP for
another DBMS, or have a working mapping to share, please contact the JBoss Mailing
List.
</p></div><div class="section"><a name="Nd81"></a><div class="titlepage"><div><h3
class="title"><a name="Nd81"></a><span class="title">Installing JDBC
Drivers</span></h3></div></div><p>
To install a JDBC driver, it must be distributed as one or more ZIP or JAR files.
You should copy those files to the <tt>lib/ext</tt> directory under your JBoss
installation directory. In addition, you need to change one line in the file
jboss.properties located in the conf directory. Find the property named
jdbc.drivers, and add your product's driver class name to the list of drivers. The
drivers in the list should be separated by commas. Here's an
example line, listing drivers for Oracle and Sybase:
<pre
class="programlisting">jdbc.drivers=oracle.jdbc.driver.OracleDriver,com.sybase.jdbc2.jdbc.SybDriver</pre>
</p><p>
The next time you start JBoss, you should see output like the following listing each
driver that was loaded. If instead you see an error for the driver (also
shown below), make sure that you installed the required ZIPs and/or JARs to the
<tt>lib/ext</tt> directory.
<tt>
[JDBC] Loaded JDBC-driver:oracle.jdbc.driver.OracleDriver
[JDBC] Could not load driver:com.sybase.jdbc2.jdbc.SybDriver
</tt>
</p></div></div><div class="section"><a name="Nda1"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="Nda1"></a><span
class="title">Creating DB Connection Pools</span></h2></div></div><p>
Once your JDBC driver is installed, you can add one or more connection pools that
use it. Any number of EJBs may share one connection pool, but you
may want to create multiple pools for a number of reasons. For example, you may want
a dedicated pool for an application that requires very high reponse
time, while other applications share a pool of limited size.</p><p>
To add a pool, you need to add sections to jboss.conf and jboss.jcml, both of which
can be found in the conf directory.</p><div class="section"><a name="Ndab"></a><div
class="titlepage"><div><h3 class="title"><a name="Ndab"></a><span class="title">The
JDBC 2.0 Optional Package</span></h3></div></div><p>
Before we configure the pool, we need to take a brief detour into specifications.
The JDBC API distributed with JDKs 1.1 through 1.3 defines a transaction
for every connection. It is not possible to have more than one connection in a
transaction, or to use a single connection for more than one transaction at a
time.</p><p>
Though perfectly adequate for normal use, this falls short of the functionality
mandated by the J2EE specification for enterprise applications. In the J2EE
environment, beans are allowed to use multiple data source, which may include
messaging services, legacy systems, and other non-database sources.
Further, all work against all data sources can be committed or rolled back together.
This means that a EJBs must be able to use more than one data source
per transaction, and in particular more than one connection per transaction.</p><p>
Thus was born the JDBC 2.0 Optional Package (the API formerly known as the JDBC 2.0
Standard Extension). This API defines the javax.sql package,
including interfaces such as DataSource, XADataSource, and XAConnection. Some
drivers support this already, though most do not. And some that do
support it do not do a very good job yet (some Oracle implementations, in
particular, neglect important event notifications).</p><p>
You must determine whether your driver supports the JDBC 2.0 Optional Package in
order to configure JBoss appropriately. If it does not, JBoss will
simulate it so that your EJBs will operate appropriately, but there are two
important restrictions:
<div class="orderedlist"><ol type="1"><li><p><a name="Ndc0"></a>If you request
more than one connection from a DataSource in the context of the same transaction,
JBoss will return the same connection every
time. This is so changes made by one bean will be visible to other beans
operating in the same transaction.</p></li><li><p><a name="Ndc4"></a>The connections
cannot determine ahead of time whether it is possible for them to commit, so they
cannot participate fully in the two-phase
commit protocol used to commit multiple data sources. This means that if
there's a problem with one of the data sources, some may commit and
others may rollback. This is why we want all DB vendors to fully support the
JDBC 2.0 Optional Package.</p></li></ol></div>
</p></div><div class="section"><a name="Ndcb"></a><div class="titlepage"><div><h3
class="title"><a name="Ndcb"></a><span class="title">Configuration File
Changes</span></h3></div></div><p>
First, you need to add a section to jboss.conf for each pool. This declares a JMX
service (an MBean) for the the pool. There's a sample below. It
does not matter where in the file you add these lines; the startup order is not
dependent on the order of services in the file. You should make the following
changes to customize your pool:
<div class="itemizedlist"><ul><li><p><a name="Ndd3"></a>In the first line, you
should replace "vendor.jar" with the name of the ZIPs or JARs you added to the
<tt>lib/ext</tt> directory when you configured
the driver</p></li><li><p><a name="Nddc"></a>
Enter the name you want to use for this pool instead of "PoolName" for the
first argument.</p></li><li><p><a name="Nde0"></a>If your driver supports the JDBC 2.0
Optional Package, you should use the class name of the vendor's XADataSource
implementation for the
second argument. Otherwise, use the JBoss class name shown.</p></li></ul></div>
<pre class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar,vendor.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="PoolName">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre>
</p><p>
Second, you must add a section to jboss.jcml for each pool. This declares all the
parameters for the pool, such as the size, username and password
to use, etc. The parameters will be covered in detail next. The block you need to
add is shown below. You only need to add lines for the parameters you
want to override - anything you want to leave as the default you can omit. JBoss
will add all those lines in when it runs, so you can see the default values.
The example below is a simple configuration with only the JDBC URL, user name, and
password. The one thing you need to change besides the
parameter names and values is the pool name in the first line:
<pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=PoolName">
<attribute
name="URL">jdbc:oracle:thin:@serverhostname:1521:ORCL</attribute>
<attribute name="JDBCUser">scott</attribute>
<attribute name="Password">tiger</attribute>
</mbean>
</pre>
</p><div class="section"><a name="Ndf3"></a><div class="titlepage"><div><h4
class="title"><a name="Ndf3"></a><span class="title">Connection Pool
Parameters</span></h4></div></div><p>
Here is the list of possible parameters for each pool's entry in jboss.jcml. Again,
after you run
JBoss once with your new pool, it will add entries for all of these to jboss.jcml,
using the default
values for anything you didn't specify.</p><div class="table"><p><a
name="Ndfa"></a><b>Table 3.1. Connection pool parameters</b></p><table
summary="Connection pool parameters" border="1"><thead><tr><th>Name</th><th>Connection
pool parameters</th><th>default</th></tr></thead><tbody><tr><td>URL</td><td>The JDBC
URL used to connect to the data
source</td><td> </td></tr><tr><td>JDBCUser</td><td>The user name used to connect
to the data source.</td><td> </td></tr><tr><td>Password</td><td>The password used
to connect to the data source.</td><td> </td></tr><tr><td>Properties</td><td>Any
properties required to connect to the data source. This should
be expressed in a String of the form
name=value;name=value;name=value....</td><td> </td></tr><tr><td>MinSize</td><td>The
minimum size of the pool. The pool always starts with one
instance, but if shrinking is enabled the pool will never
fall below
this size. It has no effect if shrinking is not
enabled.</td><td>0</td></tr><tr><td>MaxSize</td><td>The maximum size of the pool. Once
the pool has grown to hold this
number of instances, it will not add any more instances. If
one of the
pooled instances is available when a request comes in, it
will be
returned. If none of the pooled instances are available, the
pool will
either block until an instance is available, or return null
(see the
Blocking parameter). If you set this to zero, the pool size
will be
unlimited.</td><td>0</td></tr><tr><td>Blocking</td><td>Controls the behavior of the
pool when all the connections are in
use. If set to true, then a client that requests a connection
will wait
until one is available. If set to false, then the pool will
return null
immediately (and the client may retry).
Note: If you set blocking to false, your client must be
prepared to
handle null
results!</td><td>true</td></tr><tr><td>LoggingEnabled</td><td>Whether the pool should
record activity to the JBoss log. This
includes events like connections being checked out and
returned. It
is generally only useful for troubleshooting purposes (to
find a
connection leak,
etc.).</td><td>false</td></tr><tr><td>GCEnabled</td><td>Whether the pool should check
for connections that have not been
returned to the pool after a long period of time. This would
catch
things like a client that disconnects suddenly without closing
database connections gracefully, or queries that take an
unexpectedly long time to run. This is not generally useful
in an EJB
environment, though it may be for stateful session beans that
keep a
DB connection as part of their state. This is in contrast to
the idle
timeout, which closes connection that have been idle in the
pool.</td><td>false</td></tr><tr><td>GCMinIdleTime</td><td>If garbage collection is
enabled, the amount of time (in milliseconds)
that must pass before a connection in use is garbage
collected -
forcibly returned to the pool.</td><td>1200000
(20m)</td></tr><tr><td>GCInterval</td><td>How often garbage collection and shrinking
should run (in
milliseconds), if they are enabled.</td><td>120000
(2m)</td></tr><tr><td>IdleTimeoutEnabled</td><td>Whether the pool should close idle
connections. This prevents the
pool from keeping a large number of connections open
indefinitely
after a spike in activity. Any connection that has been
unused in the
pool for longer than this amount of time will be closed. If
you do not
want the pool to shrink so rapidly, you can set the
MaxIdleTimeoutPercent and then some connections will be
recreated to replace the closed ones. This is in contrast to
garbage
collection, which returns connections to the pool that have
been
checked out of the pool but not returned for a long period of
time.</td><td>false</td></tr><tr><td>MaxIdleTimeoutPercent</td><td>Sets the idle
timeout percent as a fraction between 0 and 1. If a
number of connections are determined to be idle, they will
all be
closed and removed from the pool. However, if the ratio of
objects
released to objects in the pool is greater than this
fraction, some
new objects will be created to replace the closed objects.
This
prevents the pool size from decreasing too rapidly. Set to 0
to
decrease the pool size by a maximum of 1 object per test, or
1 to
never replace objects that have exceeded the idle timeout.
The pool
will always replace enough closed connections to stay at the
minimum
size.</td><td>1.0</td></tr><tr><td>IdleTimeout</td><td>Set the idle timeout for unused
connections. If a connection has
been unused in the pool for this amount of time, it will be
released
the next time garbage collection and shrinking are run (see
GCInterval).</td><td>1800000
(30m)</td></tr><tr><td>TimestampUsed</td><td>Sets whether object clients can update
the last used time. If so, the
last used time will be updated for significant actions
(executing a
query, navigating on a ResultSet, etc.). If not, the last
used time will
only be updated when the object is given to a client and
returned to
the pool. This time is important if shrinking or garbage
collection are
enabled (particularly the
latter).</td><td>false</td></tr></tbody></table></div></div></div><div
class="section"><a name="Nec8"></a><div class="titlepage"><div><h3 class="title"><a
name="Nec8"></a><span class="title">Connection Pool Configuration Examples and Driver
Notes</span></h3></div></div><p>
Here are some sample database pool configuration file exerpts for a variety of
database products. Note that your configuration may differ slightly if you're
using a different version, different JDBC driver, etc. The parameters you are most
likely to need to change are in bold.</p><div class="itemizedlist"><ul><li><p><a
name="Ned1"></a>Oracle 8i with native JDBC 2 Optional Package XADataSource</p><div
class="itemizedlist"><ul><li><a name="Ned7"></a><div
class="literallayout">Driver Notes <br>
Extreme Float or Double values will cause SQLExceptions <br>
The Oracle XADataSource requires the Oracle Xid implementation. Other vendor's XADataSource implementation may or may<br>
not be able to interoperate.</div></li><li><p><a
name="Nedf"></a>lib/ext: classes12.zip</p></li><li><p><a
name="Nee3"></a>jboss.properties</p><pre class="programlisting">
jboss.xa.xidclass=oracle.jdbc.xa.OracleXid
</pre></li><li><p><a name="Need"></a>jboss.conf</p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="OracleDB">
<ARG TYPE="java.lang.String"
VALUE="oracle.jdbc.xa.client.OracleXADataSource">
</MLET>
</pre></li><li><p><a name="Nef7"></a>jboss.jcml</p><pre
class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=OracleDB">
<attribute
name="URL">jdbc:oracle:thin:@host.domain.com:1521:instance</attribute>
<attribute name="JDBCUser">scott</attribute>
<attribute name="Password">tiger</attribute>
</mbean>
</pre></li><li><p><a name="Nf01"></a>CMP Type Mapping Names (for jaws.xml): Oracle8
</p></li></ul></div></li><li><p><a name="Nf07"></a>Oracle 7.x,8.x,8i with JDBC 1/2
Wrapper
This configuration is reported to be outdated. It is still here for reference
for older versions.</p><div class="itemizedlist"><ul><li><a name="Nf0d"></a><div
class="literallayout">Driver Notes <br>
For CMP Entity Beans, Oracle 7 only allows 1 serialized Java Object per bean (column type LONG RAW). Oracle 8 does not have<br>
this limitation (column type BLOB). <br>
Extreme Float or Double values will cause SQLExceptions </div></li><li><p><a
name="Nf15"></a>lib/ext: classes12.zip</p></li><li><p><a
name="Nf19"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=oracle.jdbc.driver.OracleDriver
</pre></li><li><p><a name="Nf23"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="OracleDB">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="Nf2d"></a>jboss.jcml</p><pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=OracleDB">
<attribute
name="URL">jdbc:oracle:thin:@host.domain.com:1521:instance</attribute>
<attribute name="JDBCUser">scott</attribute>
<attribute name="Password">tiger</attribute>
</mbean>
</pre></li><li><p><a name="Nf37"></a>CMP Type Mapping Names (for jaws.xml): Oracle7
and Oracle8 </p></li></ul></div></li><li><p><a name="Nf3d"></a>Hypersonic</p><div
class="itemizedlist"><ul><li><p><a name="Nf43"></a>lib/ext: hsql.jar</p></li><li><p><a
name="Nf47"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=org.hsql.jdbcDriver
</pre></li><li><p><a name="Nf51"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="Hypersonic">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="Nf5b"></a>jboss.jcml</p><pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=Hypersonic">
<attribute name="URL">jdbc:HypersonicSQL:hsql://localhost</attribute>
<attribute name="JDBCUser">sa</attribute>
</mbean>
</pre></li><li><p><a name="Nf65"></a>CMP Type Mapping Names (for jaws.xml):
Hypersonic SQL </p></li></ul></div></li><li><p><a name="Nf6b"></a>DB2 7.1</p><div
class="itemizedlist"><ul><li><a name="Nf71"></a><div
class="literallayout">Driver Notes <br>
DB2 does not support variables of type "byte", so with CMP entities they will be serialized. We recommend that you use short or int<br>
variables to avoid this. <br>
For CMP entities, serialized objects are stored as type BLOB(n), where n is 2000 by default. If you plan to serialize objects larger<br>
than 2000 bytes, you will need to alter the mapping or create the table manually. <br>
Extreme Float or Double values will cause SQLExceptions and may corrupt the driver so that further actions fail. <br>
The "net" driver (type 4) is preferred over the "app" driver (type 2), though only the "app" driver has a native XADataSource<br>
implementation. To use the "net" driver, you must run the "db2jstrt [port]" tool on your DB server. </div></li><li><p><a
name="Nf79"></a>lib/ext: db2java.zip</p></li><li><p><a
name="Nf7d"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=COM.ibm.db2.jdbc.net.DB2Driver
</pre></li><li><p><a name="Nf87"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="DB2">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="Nf91"></a>jboss.jcml</p><pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=DB2">
<attribute
name="URL">jdbc:db2://host.domain.com:port/database</attribute>
<attribute name="JDBCUser">username</attribute>
<attribute name="Password">password</attribute>
</mbean>
</pre></li><li><p><a name="Nf9b"></a>CMP Type Mapping Names (for jaws.xml):DB2
</p></li></ul></div></li><li><p><a name="Nfa1"></a>DB2/400</p><div
class="itemizedlist"><ul><li><p><a name="Nfa7"></a>lib/ext: jt400.jar
</p></li><li><p><a name="Nfab"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=com.ibm.as400.access.AS400JDBCDriver
</pre></li><li><p><a name="Nfb5"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="AS400">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="Nfbf"></a>jboss.jcml</p><pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=AS400">
<attribute name="URL">jdbc:as400://hostname</attribute>
<attribute name="JDBCUser">user</attribute>
<attribute name="Password">pw</attribute>
</mbean>
</pre></li><li><p><a name="Nfc9"></a>CMP Type Mapping Names (for jaws.xml):DB2/400
</p></li></ul></div></li><li><p><a name="Nfcf"></a>Sybase Adaptive Server Anywhere
6.x, Adaptive Server Enterprise 11.9.x, 12.x </p><div class="itemizedlist"><ul><li><a
name="Nfd5"></a><div class="literallayout">Driver Notes <br>
You must install jConnect 5.2, including the stored procedures which are distributed with the jConnect package. There are<br>
directions for this in the Installation Instructions chapter of the jConnect for JDBC Installation Guide. <br>
JAWS cannot create a table automatically for CMP Entity beans (the server rejects DDL within a transaction) <br>
The jConnect 5.2 JDBC driver does not support variables of type byte or short, so they will be serialized (column type must be<br>
varbinary or image). We recommend you use int variables instead to avoid this. </div></li><li><p><a
name="Nfdd"></a>lib/ext:jconn2.jar</p></li><li><p><a
name="Nfe1"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=com.sybase.jdbc2.jdbc.SybDriver
</pre></li><li><p><a name="Nfeb"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="SybaseDB">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="Nff5"></a>jboss.jcml</p><pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=SybaseDB">
<attribute
name="URL">jdbc:sybase:Tds:host.domain.com:4100/database</attribute>
<attribute name="Password">password</attribute>
<attribute name="JDBCUser">username</attribute>
</mbean>
</pre></li><li><p><a name="Nfff"></a>CMP Type Mapping Names (for
jaws.xml):Sybase</p></li></ul></div></li><li><p><a name="N1005"></a>PostgreSQL 7.x
</p><div class="itemizedlist"><ul><li><a name="N100b"></a><div
class="literallayout">Driver Notes <br>
Extreme Java "long" values will cause SQLExceptions and may corrupt the driver so that further actions fail. </div></li><li><p><a
name="N1013"></a>lib/ext:jdbc7.0-1.2.jar</p></li><li><p><a
name="N1017"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=org.postgresql.Driver
</pre></li><li><p><a name="N1021"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="PostgresDB">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="N102b"></a>jboss.jcml</p><pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=PostgresDB">
<attribute
name="URL">jdbc:postgresql://host.domain.com/database</attribute>
<attribute name="JDBCUser">postgres</attribute>
<attribute name="Password">foo</attribute>
</mbean>
</pre><p>Note: You must include a user name and password. They can be bogus if your
PostgreSQL installation is configured to "trust" the machine
you're coming from, but you can't leave them out.</p></li><li><p><a
name="N1038"></a>CMP Type Mapping Names (for jaws.xml):PostgreSQL
</p></li></ul></div></li><li><p><a name="N103e"></a>Interbase 6.x </p><div
class="itemizedlist"><ul><li><a name="N1044"></a><div
class="literallayout">Driver Notes <br>
For CMP entity beans, serialized Java Objects are limited to 2000 bytes by default in automatically generated tables. You may<br>
increase this limit by changing the mapping or creating the table manually. <br>
The interclient JDBC driver seems to have trouble checking whether a table exists, so until that is resolved you can't have JAWS<br>
create the table anyway. </div></li><li><p><a
name="N104c"></a>lib/ext:interclient-core.jar</p></li><li><p><a
name="N1050"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=interbase.interclient.Driver
</pre></li><li><p><a name="N105a"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="InterBaseDB">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="N1064"></a>jboss.jcml</p><pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=InterBaseDB">
<attribute
name="URL">jdbc:interbase://host.domain.com/path/to/database.gdb</attribute>
<attribute name="JDBCUser">sysdba</attribute>
<attribute name="Password">changeme</attribute>
</mbean>
</pre></li><li><p><a name="N106e"></a>CMP Type Mapping Names (for
jaws.xml):InterBase</p></li></ul></div></li><li><p><a name="N1074"></a>mySQL
3.23.24-beta </p><div class="itemizedlist"><ul><li><a name="N107a"></a><div
class="literallayout">Notes:<br>
mySQL does not support transactions before version 3.23.15 (experimental support). Check the consequences for your configuration. <br>
get mm.mysql-2.0.2-bin.jar from http://www.worldserver.com/mm.mysql/<br>
copy the jar to <tt>lib/ext/</tt> </div></li><li><p><a
name="N1087"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=org.gjt.mm.mysql.Driver
</pre></li><li><p><a name="N1091"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="mySQL">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="N109b"></a>jboss.jcml</p><pre
class="programlisting">
At least adjust URL, JDBCUser and Password in the following:
<mbean name="DefaultDomain:service=XADataSource,name=mySQL">
<attribute name="Properties"></attribute>
<attribute name="URL">jdbc:mysql://host/databasename</attribute>
<attribute name="GCMinIdleTime">1200000</attribute>
<attribute name="JDBCUser">EnterDatabaseUserHere</attribute>
<attribute name="MaxSize">10</attribute>
<attribute name="Password">EnterDatabasePasswordHere</attribute>
<attribute name="GCEnabled">false</attribute>
<attribute name="InvalidateOnError">false</attribute>
<attribute name="TimestampUsed">false</attribute>
<attribute name="Blocking">true</attribute>
<attribute name="GCInterval">120000</attribute>
<attribute name="IdleTimeout">1800000</attribute>
<attribute name="IdleTimeoutEnabled">false</attribute>
<attribute name="LoggingEnabled">false</attribute>
<attribute name="MaxIdleTimeoutPercent">1.0</attribute>
<attribute name="MinSize">0</attribute>
</mbean>
</pre></li><li><p><a name="N10a5"></a>CMP Type Mapping Names (for
jaws.xml):mySQL</p></li></ul></div></li><li><p><a name="N10ab"></a>Microsoft Jet
Engine/Access 97</p><div class="itemizedlist"><ul><li><a name="N10b1"></a><div
class="literallayout">Driver Notes <br>
This example uses Sun's Jdbc-Odbc bridge. This type 1 JDBC driver is very convenient if you start working with JBoss-Jet<br>
Engine. It can be slow under heavy loads and should be replaced in high-load production environments. Also, the driver supports<br>
only JDBC 1, so JDBC 2.0 types like CLOB cannot be used. <br>
The ODBC data source can be created using Control Panel - ODBC Data Sources. <br>
You can let Access and JBoss use the datasource at the same time. To do this, start JBoss first, then start Access. Access will<br>
open the datasource in Shared Mode. You can now use Access 97 as editor, viewer, bulk importer/exporter and query builder<br>
while JBoss can be stopped and started concurrently. </div></li><li><p><a
name="N10b9"></a>lib/ext:Sun JRE's rt.jar if your not running on a Sun virtual
machine, otherwise none </p></li><li><p><a name="N10be"></a>jboss.properties</p><pre
class="programlisting">jdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriver
</pre></li><li><p><a name="N10c8"></a> jboss.conf </p><pre
class="programlisting">
<MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="JetEngineDB">
<ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl">
</MLET>
</pre></li><li><p><a name="N10d2"></a>jboss.jcml</p><pre class="programlisting">
<mbean name="DefaultDomain:service=XADataSource,name=JetEngineDB">
<attribute name="URL">jdbc:odbc:ODBC datasource name</attribute>
<attribute name="JDBCUser"></attribute>
<attribute name="Password"></attribute>
</mbean>
</pre></li><li><p><a name="N10dc"></a> Note: a default Jet Engine data
source has no user and password, therefor the JDBCUser and Password attributes are
empty. If you need
a user or a password, see the other examples. </p><p>You can download
this mapping here (if using JdbcOdbc bridge driver) or here (if using JDBC 2.0
compliant driver). Add the contents to
your jaws.xml in the type-mappings section. </p></li><li><p><a
name="N10e3"></a>CMP Type Mapping Names (for jaws.xml):MS Jet Engine
</p></li></ul></div></li></ul></div></div><div class="section"><a
name="N10eb"></a><div class="titlepage"><div><h3 class="title"><a
name="N10eb"></a><span class="title">Changes for newer versions than 2.0
FINAL</span></h3></div></div><p>Author:
<span class="author">Tobias Frech</span>
</p><p>
If your are using a newer version of JBoss than 2.0 FINAL then
all you need to configure is the file jboss.jcml in your configuration
directory (probably this is conf/default/). The following points describe
where the information provided for the former different files now should be inserted
into <i>jboss.jcml</i>:
</p><div class="itemizedlist"><ul><li><a
name="N1100"></a><p><b>jboss.properties:</b> In the
<tt><mbean code="org.jboss.jdbc.JdbcProvider"...>
</tt> add the
additional driver entry to the comma separated list inside the
<tt><attribute name="Drivers"></tt> tag.</p></li><li><a
name="N1114"></a><p><b>jboss.conf:</b> This information is no longer
needed.</p></li><li><a name="N111e"></a><p><b>jboss.jcml:</b> Find the entry
<pre class="programlisting">
<mbean code="org.jboss.jdbc.XADataSourceLoader"
name="DefaultDomain:service=XADataSource,name=DefaultDS">
...
</mbean>
</pre>
Either you want to change the default Datasource, then change the
contents of this entry directly, or you want to add a new
datasource. For the second
case create a copy of the whole entry after
the already existing one.
Now change the two occurences of the “DefaultDS”
string (in “name=...”
and attribute “PoolName”) to the name you want
to specify for your new datasource.
Also adjust at least the following entries according to your
configuration and to the data given in the example:
<pre class="programlisting">
<attribute
name="URL">jdbc:url/with/your/database/name/like/in/example</attribute>
<attribute name="JDBCUser">DatabaseUserNameHere</attribute>
<attribute name="Password">DatabasePasswordHere</attribute>
</pre>
</p></li></ul></div><p>
All other information contained in the examples like which driver jar
to copy to <tt>lib/ext/</tt> and using which type mapping in your beans
jaws.xml should still be valid.
</p></div></div></div><div class="chapter" id="N1147"><div
class="titlepage"><div><h2 class="title"><a name="N1147"></a>Chapter 4. Using
container-managed persistence</h2></div></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="#N1158">Introduction</a></dt><dd><dl><dt> <a
href="#N115c">What this article is about</a></dt><dt> <a
href="#N116a">Pre-requisites</a></dt><dt> <a href="#N1172">JBoss hints</a></dt><dt> <a
href="#N117a">Persistence: review</a></dt><dt> <a href="#N118b">When to Use CMP or
BMP?</a></dt></dl></dd><dt> <a href="#N1197">Container Managed Persistence -
CMP</a></dt><dd><dl><dt> <a href="#N119b">Determine the persistent
classes</a></dt></dl></dd><dt> <a href="#N11c8">Creating the Beans</a></dt><dt> <a
href="#N1217">Packaging and deploying the Beans</a></dt><dt> <a href="#N1258">Creating
a test client </a></dt><dt> <a href="#N1289">Discussion: container-managed
persistence</a></dt><dd><dl><dt> <a href="#N1290">Technical overview </a></dt!
><dt> <a href="#N129c">Limitations of CMP </a></dt></dl></dd></dl></div><p>Author:
<span class="author">Kevin Boone</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N1158"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1158"></a><span
class="title">Introduction</span></h2></div></div><div class="section"><a
name="N115c"></a><div class="titlepage"><div><h3 class="title"><a
name="N115c"></a><span class="title">What this article is
about</span></h3></div></div><p>
This article presensts a step-by-step example of creating, deploying and
testing an Entity JavaBean that uses
`container-managed persistence' with the JBoss EJB server. This
example is very simple, and is a variation of
the old favourite `music CD' case study. I have chosen this example
because the application is likely to be
familiar to most people without much explanation. In short, the `CD'
EJB models a music CD. Applications
will want to add and delete CDs to a collection, and search the collection
for specific CDs. There is also a
`CDCollection' EJB that lists and searches collections of CDs.</p><p>
The full source code to accompany this article can be found here (in
gzipped tar format). This archive
contains the Java source code, JavaDoc documentation, and a text file of test
data (CDs.txt) to initialize the
database.</p><p>
Although I will occasionally make reference to Linux, this is only because
that's what I use for EJB
development; most of the material in this article will work with any Unix
version, and even with Windows NT
if the directory structure is adjusted accordingly.</p></div><div class="section"><a
name="N116a"></a><div class="titlepage"><div><h3 class="title"><a
name="N116a"></a><span class="title">Pre-requisites</span></h3></div></div><p>
You will need a fully-functioning JBoss installation to follow this tutorial,
which must have a working
database connection. I will assume that you are basically familiar with EJBs
and know how to structure and
compile JavaBeans as Java packages. Also I will assume you know the basic
structure of a deployment
descriptor, and the run-time descriptor that JBoss uses (jboss.xml). I will
assume that you know how to
package and deploy EJBs using JBoss. If you don't know about these things, you
might want to look at my
introductory article on JBoss first.</p></div><div class="section"><a
name="N1172"></a><div class="titlepage"><div><h3 class="title"><a
name="N1172"></a><span class="title">JBoss hints</span></h3></div></div><p>JBoss is
written entirely in Java, as is the `Hypersonic' database with
which it is supplied. Searching a database
requires lots of repetitive operations, and an interpreting Java system will
be extremely slow if the database is
large. If you are using the Sun JDK, you will need to ensure that it is
configured to use the `Hotspot' virtual
machine, to achieve anything close to acceptable performance. For the purposes
of study, you could get along
by ensuring that the database size is kept small, but with even a hundred
objects you will find it too slow to use.
Some Linux systems are reluctant to use the `Hotspot' JVM, but they can
normally be coerced to.</p></div><div class="section"><a name="N117a"></a><div
class="titlepage"><div><h3 class="title"><a name="N117a"></a><span
class="title">Persistence: review</span></h3></div></div><p>
There are, in essence, two kinds of Enterprise JavaBean: session and entity.
Entity EJBs contain information
that is persistent across different client-Bean interactions, while session
EJBs don't. For example, a class
called `Customer' that represents the customers of a particular service will
contain persistent information
(about the customer). A class called `CustomerFinder', say, that finds
Customer instances that match certain
criteria is likely to be a session EJB, because it does not require
information that is maintained between
different client-server interactions.</p><p>
Session EJBs can be further divided into `stateless' and `stateful'. A
stateful session EJB has a state that is
persistent between invocations of its methods. A stateless EJB does not even
have to retain its state between
method invocations. The stateless session EJB is therefore the type of EJB
that exhibits the least persistence.</p><p>
The entity EJBs contain information that persists even when no clients
are using any of the Bean's
services; the information should persist even if the server is restarted.
There is a high degree of
correspondence between instances of an entity EJB and rows of a database
table. In practice, all EJB servers
implement entity instances as table rows. This correspondence is so strong
that the notion of a `primary key'
is relevant to an entity EJB. Of course, a primary key is a database concept,
not an object-orientation concept
at all.</p><p>
The persistence of an entity EJB may be managed by the Bean itself, or
by the server (technically by the
`container'). The latter technique is called `Container-managed persistence',
and is the subject of the rest of
this article.</p></div><div class="section"><a name="N118b"></a><div
class="titlepage"><div><h3 class="title"><a name="N118b"></a><span class="title">When
to Use CMP or BMP?</span></h3></div></div><p>
Unlike what many folks believe, the choice of going BMP or CMP is not really
one of "trade-off". If you have
already schemas deployed you may find that the complexity of the schemas
requires you to go with BMP or use
a BMP generating tool such as "cocobase". These techniques are what we call
"fake CMP" where the work of
accessing the database is left to the generated classes. </p><p>
The breed of CMP that has most value is the "real CMP" or a CMP where you let
the container manage the
persistent representation of your beans entirerly. This might not work right
now for you if your object are
complex but should work in most simple cases. EJB2.0 also goes the extra
length to make the persistent
engines powerful and fast with management of dependencies and relationships.
We believe that one day you
will rely on the engines to manage the schemas, just like you rely on a
compiler to optimize assembly code.</p></div></div><div class="section"><a
name="N1197"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1197"></a><span class="title">Container Managed Persistence -
CMP</span></h2></div></div><div class="section"><a name="N119b"></a><div
class="titlepage"><div><h3 class="title"><a name="N119b"></a><span
class="title">Determine the persistent classes</span></h3></div></div><p>
In this simple example we will use two Enterprise JavaBeans. The first, called
`CD' models a music CD.
It contains attributes (instance variables) that store the title ID code and
various other
properties of a music CD. The second is called `CDCollection', and models a
collection of such CDs.
This bean acts as a simple interface between the client and the CD Bean;
technically we could
manage without it but it does make certain operations easy to follow. The
CDCollection Bean
will have the following methods deleteAll(), addCd(), findInAnyField() and
findAll().
</p><p>
<div class="itemizedlist"><ul><li><p><a name="N11a7"></a>
addCd() - Adds a single CD specified by values of its
attributes</p></li><li><p><a name="N11ab"></a>
deleteAll() - Delete all CDs </p></li><li><p><a
name="N11af"></a>findInAnyField() - Returns an array of CD instances which have
the specified text string in any of their
attributes</p></li><li><p><a name="N11b3"></a>
findAll() - Returns an array of all CD instances in the system
</p></li></ul></div>
</p><p>
All these methods could be implemented by direct manipulation of the home
interface of the CD Bean,
but it is slightly more elegant to do it this way.
</p><p>
Because the CDCollection Bean only interacts with the CD Beans during requests
from clients, it
appears to have no persistent information. So it is a session Bean. Moreover,
since each method
is completely self-contained, it is a stateless session bean.
</p><p>
The CD Bean, however, will be an entity EJB because some of its information is
persistent.
For example, the ID, artist, title, type and notes about the recording will
all be persistent.
Of course the CD Bean may have other instance variables, but they won't
necessarily be persistent.
For example, some will hold temporary data, and others will be derived from
the persistent attributes.
</p><p>
In this example, I will assume that the persistent fields are all Java
`String' values representing
the ID, title, artist, type and notes. You could, of course, add other
information you feel to be
important.
</p></div></div><div class="section"><a name="N11c8"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N11c8"></a><span
class="title">Creating the Beans</span></h2></div></div><p>
The entity bean representing the CD is very easy to code, as it doesn't have
to do a great deal.
All the issues of persistence will be taken care of by the server. I will
present the full code
for this Bean below; the code for the CDCollection Bean will not be discussed
further because it
is not interesting in the context of container-managed persistence. Remember
that the full source code is available to download as an archive named
“cdEJB.zip”. You can get it from the files area in the
documentation section on www.jboss.org.
</p><p>
CD.java: remote interface for the `CD' Bean
</p><p>
<pre class="programlisting">
package com.web_tomorrow.cd;
import java.rmi.RemoteException;
import javax.ejb.*;
/**
This interface defines the remote interface to the `CD' EJB
*/
public interface CD extends EJBObject
{
/**
Get CD title
*/
public abstract String getTitle() throws RemoteException;
/**
Set CD title
*/
public abstract void setTitle(String title) throws RemoteException;
/**
Set CD ID code
*/
public abstract String getId() throws RemoteException;
/**
Get CD ID code
*/
public abstract void setId(String id) throws RemoteException;
/**
Get artist
*/
public abstract String getArtist() throws RemoteException;
/**
Set artist
*/
public abstract void setArtist(String artist) throws RemoteException;
/**
Get type (rock, classical, chamber music, etc)
*/
public abstract String getType() throws RemoteException;
/**
Set type
*/
public abstract void setType(String type) throws RemoteException;
/**
Get notes (comments, not musical notes!)
*/
public abstract String getNotes() throws RemoteException;
/**
Set notes
*/
public abstract void setNotes(String type) throws RemoteException;
}
</pre>
</p><p>
The remote interface specifies methods to get and set the attributes of the
object.
That's all it needs to do in this example. Note that, as with any Java Bean,
the
names of these methods must follow the standard convention; that is, if an
attribute
is called `String X' then the `get' and `set' methods must be defined as
follows:
</p><pre class="programlisting">
String getX();
void setX(String);
</pre><p>
Note also that JBoss requires that these methods are declared as `abstract'
when using CMP.
It does not matter for session Beans, and some EJB server aren't fussy (e.g.,
Sun J2EE), but
with CMP in JBoss you need to say `abstract'. Failure to do so will result in
the following
error message during deployment:
</p><div class="literallayout"><br>
<tt><br>
[Container factory] org.jboss.ejb.DeploymentException: Could not find matching<br>
method for public abstract java.lang.String somepackage.getSomeField()<br>
throws java.rmi.RemoteException, Cause:java.lang.NoSuchMethodException:<br>
getSomeField()<br>
</tt><br>
</div><p>
CDHome.java: home interface for the `CD' Bean
</p><pre class="programlisting">
package com.web_tomorrow.cd;
import java.rmi.RemoteException;
import javax.ejb.*;
import java.util.Collection;
/**
This interface defines the home interface for the `CD' EJB
*/
public interface CDHome extends EJBHome
{
/**
Create a new CD instance
*/
public CD create(String id) throws RemoteException, CreateException;
/**
Find the CD with the specified ID. This method is not implemeted by the Bean,
but by the container
*/
public CD findByPrimaryKey (String id) throws RemoteException,
FinderException;
/**
Finds the CD whose `type' attribute matches that specified. This method is
implemented by the container
*/
public Collection findByType (String type) throws RemoteException,
FinderException;
/**
Get all CD instances. This method is
implemented by the container
*/
public Collection findAll() throws RemoteException, FinderException;
}
</pre><p>
The important thing to note about this interface is that it specifies methods
that
don't need to be implemented. In this case, findByPrimaryKey(), findByType()
and findAll()
are all examples of `finder' methods. The EJB specification requires that the
server be able
to provide finder methods for all the persistent attributes in the object. So,
for example,
if your class has an attribute `X', then the server will provide a `findByX'
method to search
on that field. Note that with JBoss the search is `exact'; that is, it won't
accept wild-card
characters or an incorrect mixture of upper- and lower-case letters. The
findByPrimaryKey()
searches on the primary key field; we will discuss how the primary key is
specified later.
</p><p>
CDBean.java: implementation of the `CD' Bean
</p><p>
<pre class="programlisting">
package com.web_tomorrow.cd;
import java.rmi.RemoteException;
import javax.ejb.*;
/**
This class contains the implementation for the methods specified in the home
and remote interfaces for the `CD' EJB
*/
public class CDBean implements EntityBean
{
transient private EntityContext ctx;
public String id;
public String title;
public String artist;
public String type;
public String notes;
/**
Create an instance of a CD. Note that this method returns null because the real
creation is managed by the EJB container.
*/
public String ejbCreate (String _id)
{
id = _id;
return null;
}
/**
Called when the object has been instantiated; does nothing in this example
*/
public void ejbPostCreate(String id) { }
public String getTitle() { return title; }
public void setTitle(String _title) { title = _title; }
public String getId() { return id; }
public void setId(String _id) { id = _id; }
public String getArtist() { return artist; }
public void setArtist(String _artist) { artist = _artist; }
public String getType() { return type; }
public void setType(String _type) { type = _type; }
public String getNotes() { return notes; }
public void setNotes(String _notes) { notes = _notes; }
public void setEntityContext(EntityContext ctx) { this.ctx = ctx; }
public void unsetEntityContext() { ctx = null; }
public void ejbActivate() { }
public void ejbPassivate() { }
public void ejbLoad() { }
public void ejbStore() { }
public void ejbRemove() { }
}
</pre>
</p><p>
The CDBean class provides implementations of the methods that aren't provided
automatically
by the EJB container. Note that the ejbCreate method returns `null', meaning
that the
container should take care of initializing the instance in the server's
process space.
Because the CD Bean is essentially passive -- a data repository -- it only has
a few methods.
These classes (and the CDCollection classes) can be compiled in the usual way;
don't forget
to include the path to the JBoss EJB class library in your classpath, e.g.,
</p><p>
<b>
javac -classpath /usr/local/jboss/client/ejb.jar:. ....
</b>
</p></div><div class="section"><a name="N1217"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N1217"></a><span
class="title">Packaging and deploying the Beans</span></h2></div></div><p>
Deploying an entity bean requires providing some extra information, in
addition to that required
for a session bean. This information is provided in the deployment descriptor
ejb-jar.xml
</p><pre class="programlisting">
<enterprise-beans>
<entity>
<description>Models a music CD</description>
<ejb-name>CDBean</ejb-name>
<home>com.web_tomorrow.cd.CDHome</home>
<remote>com.web_tomorrow.cd.CD</remote>
<ejb-class>com.web_tomorrow.cd.CDBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-field><field-name>id</field-name></cmp-field>
<cmp-field><field-name>title</field-name></cmp-field>
<cmp-field><field-name>artist</field-name></cmp-field>
<cmp-field><field-name>type</field-name></cmp-field>
<cmp-field><field-name>notes</field-name></cmp-field>
<primkey-field>id</primkey-field>
</entity>
<!-- more beans here -->
</enterprise-beans>
</pre><p>
The listing above shows the section of ejb-jar.xml that is relevant to the CD
Bean. It has the
usual information about the classes that consitute the Bean, but it also
specifies the type
and name of the primary key, and the fields that are persistent. Note that in
this case the
`id' field gets listed twice: once as a persistent field and then again as the
primary key field.
It might be thought that specifying a field as a primary key would
automatically make it persistent,
but it doesn't. Leaving out thecmp-field definition for the primary key
results in this error
message at deployment time:
</p><p>
<tt>
[JAWS] Initializing JAWS plugin for CDBean
[Container factory] java.lang.NoSuchFieldException: CASE_INSENSITIVE_ORDER
</tt>
</p><p>
The deployment descriptor for the CDCollection class does not require any
persistence information,
but it does require an ejb-ref section; this indicates that the CDCollection
Bean refers to CD Bean
instances. The ejb-ref section lists the type of the CD Bean, and all its
classes.
</p><pre class="programlisting">
<session>
<description>Models a music CD collection</description>
<ejb-name>CDCollectionBean</ejb-name>
<home>com.web_tomorrow.cd.CDCollectionHome</home>
<remote>com.web_tomorrow.cd.CDCollection</remote>
<ejb-class>com.web_tomorrow.cd.CDCollectionBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-ref>
<ejb-ref-name>ejb/CD</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>com.web_tomorrow.cd.CDHome</home>
<remote>com.web_tomorrow.cd.CD</remote>
<ejb-link>com.web_tomorrow.cd.CDBean</ejb-link>
</ejb-ref>
</session>
</pre><p>
In the JBoss run-time configuration file `jboss.xml' we should specify the
JNDI names of the
Beans, like this:
</p><pre class="programlisting">
<entity>
<ejb-name>CDBean</ejb-name>
<jndi-name>cd/CD</jndi-name>
</entity>
<session>
<ejb-name>CDCollectionBean</ejb-name>
<jndi-name>cd/CDCollection</jndi-name>
</session>
</pre><p>
This says the `CDBean' has the JNDI name `cd/CD' and `CDCollectionBean' has
the JNDI name `cd/CDCollection'.
Note that the method of specifying these JNDI names depends on the server.
</p><p>
When packaging these Beans, don't forget to include the files ejb-jar.xml and
jboss.jar in the
directory META-INF.During deployment (simply copy the packaged beans to the
`deploy' subdirectory
of the JBoss directory) you should see a message like the following:
</p><div class="literallayout"><br>
<tt><br>
<br>
[Container factory] Deploying:file:/usr/lib/jboss/deploy/cd.jar<br>
[Container factory] Deploying CDBean<br>
[Container factory] Deploying CDCollectionBean<br>
[JAWS] Initializing JAWS plugin for CDBean<br>
[JAWS] Remove:DELETE FROM CDBean WHERE id=?<br>
[JAWS] Drop:DROP TABLE CDBean<br>
[JAWS] Create table:CREATE TABLE CDBean (notes VARCHAR(256),title<br>
VARCHAR(256),artist VARCHAR(256),id VARCHAR(256),type VARCHAR(256))<br>
[JAWS] Insert:INSERT INTO CDBean (notes,title,artist,id,type) VALUES<br>
(?,?,?,?,?)<br>
[JAWS] Select:SELECT notes,title,artist,id,type FROM CDBean WHERE id=?<br>
[JAWS] Table CDBean exists<br>
[Container factory] Started: CDBean<br>
[Container factory] Bind ejb/CD to com.web_tomorrow.cd.CDBean<br>
[Container factory] Started: CDCollectionBean<br>
[Container factory] Bound CDBean to cd/CD<br>
[Container factory] Bound CDCollectionBean to cd/CDCollection<br>
[Container factory] Deployed application: file:/usr/lib/jboss/deploy/cd.jar<br>
</tt><br>
</div><p>
`JAWS' is the JBoss interface to the database engine. During deployment JAWS
has
deleted any existing table called `CDBean', then created a new CDBean table
with
the specified column layout. How does it know to use VARCHAR(256) for each
field?
It doesn't: it's guessing because we haven't provided any other information.
During deployment, JAWS looks for a file called `jaws.xml'; if this file
exists
it is read to configure the names and geometry of the database tables.
VARCHAR(256) is the default for String attributes. The default table name is
the
same as that of the Bean class, which is why we have ended up with a table
called
`CDBean'. This also can be over-ridden in jaws.xml. In practice, the JAWS
defaults
are adequate for most applications. However, there may be speed advantages to
using fixed-length fields (e.g., CHAR(XX) rather than variable-length ones if
at
all possible.
</p><p>
Note that it can be very difficult to change the number or names of columns
in the table once there is data in it. JBoss gets very confused by this, as
you
would expect. When a CMP Bean is re-deployed, JAWS tries to write into its
table
all the data it had in its last deployment. If the table has different columns
it probably won't be able to do that. This means that it is important to get
the
persistent fields thoroughly correct before starting to put real data into the
application.
</p></div><div class="section"><a name="N1258"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1258"></a><span class="title">Creating a
test client </span></h2></div></div><p>
Client for EJBs may be any Java program or applet; in this simple example I
will describe
a very simple client program that can be run from the command line. It simply
dumps the
attributes of all the CD Beans to standard output. The source code also
provides clients
for searching and uploading to the database, all operating at the command line.
</p><p>
The client does not interact directly with CD instances, it uses the
CDCollection bean
as a mediator. CDCollection is a stateless session bean. In this example, the
client
calls the `findAll' method to get references to all the CD objects currently
in the
system. To run this client, you will first need to get some CD objects
created. You
can use the `Upload' client for this, to create CD instances from a text file.
</p><p>
To avoid the necessity to specify the URL of the Bean server in the client
source code,
this client reads the required information from a properties file called
`cd.properties'.
The file should contain the URL and driver for the naming service, like this:
</p><p>
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
</p><p>
Of course, if your server and client are on different computers, you will need
to
change `localhost' to the real location of the server.
</p><p>
Here is the full listing of the `List' client.
</p><pre class="programlisting">
package com.web_tomorrow.cd;
import javax.naming.*;
import java.util.Hashtable;
import javax.rmi.PortableRemoteObject;
import java.util.Properties;
import java.io.FileInputStream;
/**
This is a simple client for the `CD' EJB; it lists (to standard output) all
the `CD' instances in
the system. The `main' method allows this class to be run from the command
line.
*/
class List
{
public static void main(String[] args)
{
// Get information about the Bean server from the properties file
Properties props = new Properties();
Properties sysProps = System.getProperties();
try
{
props.load (new FileInputStream ("cd.properties"));
sysProps.putAll(props);
}
catch (Exception e)
{
System.err.println ("Can't read `cd.proprties'");
System.exit (-1);
}
System.setProperties (sysProps);
// Enclosing the whole process in a single `try' block is not an ideal way
// to do exception handling, but I don't want to clutter the program up
// with catch blocks
try
{
// Get a naming context
InitialContext jndiContext = new InitialContext();
// Get a reference to a CD Bean
Object ref = jndiContext.lookup("cd/CDCollection");
// Get a reference from this to the Bean's Home interface
CDCollectionHome home = (CDCollectionHome)
PortableRemoteObject.narrow (ref, CDCollectionHome.class);
CDCollection cdCollection = home.create();
CD[] cds = cdCollection.findAll();
for (int i = 0; i < cds.length; i++)
{
System.out.println (cds[i].getId() + "\t" + cds[i].getTitle() + "\t" +
cds[i].getArtist() + "\t" + cds[i].getType());
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
}
</pre><p>
To run this client you will need to specify in the CLASSPATH the location the
JBoss client libraries, so the command line will be like this:
</p><p>
<b>
java -classpath
$CLASSPATH:/usr/lib/jboss/lib/ext/ejb.jar:/usr/lib/jboss/client/jboss-client.jar
\
com.web_tomorrow.cd.List;
</b>
</p><p>
If all is well, you will get a list of CDs.So we've created an entity EJB, and
a client
program that uses it.You'll agree, I hope, that it isn't that much more
complicated than
creating a session EJB. The additional steps required are:
</p><p>
The ejb-jar.xml file needs to indicate that the object is persistent, and list
the persistent fields.
It also needs to specify the name and class of the primary key field.
</p><p>
If the default column names and types aren't what you need, create a file
jaws.xml to specify them.
</p></div><div class="section"><a name="N1289"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1289"></a><span class="title">Discussion:
container-managed persistence</span></h2></div></div><p>
If you followed the tutorial on container-managed persistence with JBoss,
you will have seen that creating persistent, distributed objects is not
really any more difficult than creating transient ones. The EJB container does
most of the hard work; all the programmer needs to do is to tell it
which fields are persistent. However, it isn't quite as simple as that, and
naive use of CMP can lead to very inefficient programs. To see why,
it's necessary to understand at least in outline how the EJB server deals with
container-managed persistence.
</p><div class="section"><a name="N1290"></a><div class="titlepage"><div><h3
class="title"><a name="N1290"></a><span class="title">Technical overview
</span></h3></div></div><p>
In the EJB field there is a very strong correspondence between `rows of a
database table', and `instances of an object'. It is clear that the EJB
developers had this notion in mind from the very beginning. While the
specification doesn't stipulate that persistence is provided by database
tables, in practice it always is. Moreover, it is tacitly assumed that the
communication between the Beans and the database will be by means of
SQL statements. What does this imply for container-managed persistence?
</p><p>
When an persistent object is instantiated, the EJB container must
generate SQL code that will write a row in the table. When the object is
deleted, it must generate SQL to remove it. This isn't much of a problem. When
one object asks for a reference to another, the container must
find (or create) that object's row in the table, read the columns, instantiate
the object in the JVM, and write the data from the table into its
instance variables. Because this process can be quite slow, the EJB server may
choose to defer it. That is, when one object gets a reference to
an object that is container-managed, the latter object may be uninitialized.
Initialization from the database table takes place later, perhaps
when one of the methods is called. This late initialization reduces
inefficiencies arising from initializing objects that are never read, but has
its own problems, as we shall see. </p></div><div class="section"><a
name="N129c"></a><div class="titlepage"><div><h3 class="title"><a
name="N129c"></a><span class="title">Limitations of CMP </span></h3></div></div><div
class="section"><a name="N12a0"></a><div class="titlepage"><div><h4 class="title"><a
name="N12a0"></a><span class="title">Efficiency limitations </span></h4></div></div><p>
The main limitation is that the EJB container will probably not be able to
generate database access statements with the efficiency of a human
programmer. Consider this example: suppose I have an database table containing
details of my music CD collection. I want to search ithe
collection for any one which has the text `Chopin' (case insensitive) in
either the `title' or `notes' column. In SQL I could write a statement like
this:
<pre class="programlisting">
SELECT FROM CD WHERE title LIKE "%chopin%" OR notes LIKE "%chopin%";
</pre>
</p><p>
The % character is an SQL wild-card and takes care of finding the required
string somewhere inside the field; the `LIKE' operator is
case-insensitive by default. How could we achieve this with a
container-managed EJB? If `CD' is an EJB, the container-supplied method
`findAll()' in its home interface will get all the current instances of `CD'.
In practice it will do this by executing a statement like
<pre class="programlisting">
SELECT FROM CD;
</pre>
</p><p>
and then instantiating CD for each row found. At some point it will probably
store the primary key from each row of the database into the
appropriate attribute of each CD instance. Then the program must examine the
objects one at a time, checking whether they meet the required
criteria (i.e., the word `Chopin' in the appropriate attributes). As the
program iterates throuugh the objects, the server must cause their
attributes to be read from the table; it won't have done this until now
because it would try to conserve memory. So for each object examined
the server will generate SQL code like this:
<pre class="programlisting">
SELECT FROM CD WHERE ID=xxxx;
</pre>
</p><p>
Suppose there are 200 CDs known to the system. Rather than executing one SQL
statement to get a list of all matching CDs, the CMP scheme
has executed over 200 SQL statements to achieve the same effect. We can't
improve the situation by using a call to findByTitle then
findByNotes() because these methods only provide exact string matches. </p><p>
Another efficiency limitation comes from the way the database table is updated
when attributes change. There are two main ways to
achieve this. The server could execute an instruction like this:
<pre class="programlisting">
UPDATE CD SET artist="Bloggs" WHERE ID="200";
</pre>
</p><p>
for example. This is efficient, but requires the that `Artist' field really be
called `artist'. This makes it difficult to change the names of columns in
the table. Alternatively the server could do a SELECT to get the current
column values, delete the whole row, then insert a row with modified
values. This allows a number of values to change at once and, because all
values are written, it doesn't matter what the columns are called.
This is the approach that JBoss uses. The problem is that if a class has ten
persistent attributes, and they are altered one after the other, in the
worst case this results in ten row deletions and ten row insertions. </p></div><div
class="section"><a name="N12cb"></a><div class="titlepage"><div><h4 class="title"><a
name="N12cb"></a><span class="title">Limitations of late initialization
</span></h4></div></div><p>
Suppose we want to find whether a CD with a specific ID exists on the system.
With CMP this corresponds to finding whether there is a row in
the database table with the corresponding value of the `id' column. The code
in Java might look like this:
<pre class="programlisting">
// Get a reference to a CD Bean
Object ref = jndiContext.lookup("cd/CD");
// Get a reference from this to the Bean's Home interface
CDHome home = (CDHome)
PortableRemoteObject.narrow (ref, CDHome.class);
// Find the matching CD
CD cd = home.findByPrimaryKey("xxx");
</pre>
</p><p>
What will happen if `XXX' is not the ID of a CD that exists? There would seem
to be two sensible approaches. Either `findByPrimaryKey'
could throw an exception, or perhaps it could return a null reference. In
either case the client could easily tell whether the object exists. In
practice, the EJB server may do neither of these things. It may well return a
reference to a CD bean instance, which appears to be a perfectly
valid object. However, none of the object's attributes will be initialized;
initialization won't happen until the object is really required. This is done
to improve efficiency; there is, after all, no need to initialize the object
unless it will be needed. However, if the program continues to execute on
the basis that `cd' refers to a valid object, an exception will be thrown
later when the program tries to interact with it. This may not be a
problem; if the ID had been generated from some earlier database access then
we may be sure it really exists, and any failure to find it in the
database represents a serious failure. However, if the data has come from the
user, it is reasonable to expect some errors of typing or memory.
Things can be made more predictable by always reading one of the attributes of
an object after getting a reference to it, like this:
<pre class="programlisting">
CD cd = home.findByPrimaryKey("xxx");
String dummy = cd.getId();
</pre>
</p><p>
If there is no CD whose ID field is `XXX' then this will throw a
java.rmi.NoSuchObjectException. This gets around the problem
of late initialization, but at the cost of an additional SQL access.</p></div><div
class="section"><a name="N12e4"></a><div class="titlepage"><div><h4 class="title"><a
name="N12e4"></a><span class="title">Suitability of container-managed persistence
</span></h4></div></div><p>
In many applications of object-oriented programming we have had to accept that
some things that are philosophically objects are in reality
implemented as something else. The `something else' may be a row of a database
table, or a line of a text file, or whatever; at some point we
had to code the interface between the object-oriented system and the
`something elses'. Entity JavaBeans goes some way towards
eliminating this problem; things that are philosophically object can be
modelled as objects, with methods and persistence. But this comes at a
cost. It's worth asking whether the `CD' EJB in the tutorial example really is
an object in a meaningful sense. It has attributes, but it doesn't do
very much. We don't really gain all that much by making it an object; it could
have remained a database row, and been manipulated through the
`CDCollection' class. Of course this isn't as elegant, but elegance can come
at a high price. </p><p>In summary then, container-managed persistence is
straightforward to
implement using JBoss (or any other EJB server, for that matter)
but needs to be used quite carefully if serious inefficiencies are to be
avoided.</p></div></div></div></div><div class="chapter" id="N12f3"><div
class="titlepage"><div><h2 class="title"><a name="N12f3"></a>Chapter 5. Customizing
JAWS</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="#N1303">Introduction</a></dt><dt> <a href="#N1325">Specifying a
datasource</a></dt><dt> <a href="#N1365">JAWS Options</a></dt><dt> <a
href="#N139a">Telling JAWS about your tables</a></dt><dt> <a href="#N13c1">Declaring
finders</a></dt><dt> <a href="#N13fe">Defining a type
mapping</a></dt></dl></div><p>Author:
<span class="author">Sebastien Alborini</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N1303"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1303"></a><span
class="title">Introduction</span></h2></div></div><p>JAWS is the O/R mapper used by
JBoss to manage CMP entity beans. JAWS
can be configured by putting a jaws.xml file in the
META-INF directory of your application. JAWS will read this file while
deploying your beans. Here is what you can do with jaws.xml:</p><div
class="itemizedlist"><ul><li><p><a name="N130c"></a>
Specify a datasource and the type-mappings to use with it
</p></li><li><p><a name="N1310"></a>
Set a bunch of options concerning jaws behavior
</p></li><li><p><a name="N1314"></a>
Specify how JAWS should build/use your tables
</p></li><li><p><a name="N1318"></a>
Define finders to access you entity beans
</p></li><li><p><a name="N131c"></a>
Define a type mapping
</p></li></ul></div><p>
If you want to know everything about jaws.xml, see the Jaws.xml DTD. The
general structure of the jaws.xml can be found here. All parts of
this file are optional: you only provide what you need!</p></div><div
class="section"><a name="N1325"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1325"></a><span class="title">Specifying a
datasource</span></h2></div></div><p>
A datasource is, mainly, a database plus a driver plus a connection pool. By
default, jboss uses the Hypersonic datasource. To add another
datasource, you have to declare it as a JMX MLet: see the manual.</p><p>
The second ARG of this MLet is the JNDI name of the datasource, i.e. the name
you have to use to access it. To tell JAWS to use this
datasource, simply add in your jaws.xml file a <datasource> tag
with the JNDI name in it.</p><p>
According to the type of the database, you probably also want to specify a
type mapping for this datasource. A type mapping tells JAWS
which jdbc types, which sql types to use for the storage of your cmp fields.
You just have to add a <type-mapping> tag with the name of the
type mapping in it. Type mappings for the most common databases are already
defined in jboss in a file called standardjaws.xml. Their
names are listed here:</p><div class="itemizedlist"><ul><li><p><a name="N1334"></a>
Hypersonic SQL
</p></li><li><p><a name="N1338"></a>
InstantDB
</p></li><li><p><a name="N133c"></a>
Oracle
</p></li><li><p><a name="N1340"></a>
PointBase
</p></li><li><p><a name="N1344"></a>
PostgreSQL
</p></li><li><p><a name="N1348"></a>
SOLID
</p></li><li><p><a name="N134c"></a>
mySQL
</p></li><li><p><a name="N1350"></a>
DB2/400
</p></li><li><p><a name="N1354"></a>
MS SQLSERVER
</p></li></ul></div><p>
For instance, if you want to use the Postgres Database that you have deployed
in jboss.conf under the name MyPostgresPool, this is how
your jaws.xml file should look like:</p><pre class="programlisting">
<jaws>
<datasource>MyPostgresPool</datasource>
<type-mapping>PostgreSQL</type-mapping>
...
</jaws>
</pre><p>
If none of the predefined type mappings satisfies your needs, you can define
your own type-mapping.
</p></div><div class="section"><a name="N1365"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1365"></a><span class="title">JAWS
Options</span></h2></div></div><p>
Here are the options you can set in JAWS:</p><div class="itemizedlist"><ul><li><p><a
name="N136e"></a>
create-table: this tells JAWS whether it has to try and create the
table for your beans at deployment time. It is turned on by
default. If the table already exists, JAWS will tell it to you, and
proceed.
</p></li><li><p><a name="N1372"></a>
remove-table: this tells JAWS whether it has to remove (drop) the table
of your bean at undeployment time. It is turned off by
default. You may want to turn it on to clean the database. Note that if
you change a cmp-field in a bean, you will probably have to
drop the table and create it again, since the schema will have changed.
</p></li><li><p><a name="N1376"></a>
tuned-updates: when this option is turned on (default) JAWS will only
update in the database the fields of your bean that have
actually changed.
</p></li><li><p><a name="N137a"></a>
read-only: tells whether JAWS will allow client application to modify
the state of your beans. Default is false. If true, JAWS will
perform no INSERT/UPDATE.
</p></li><li><p><a name="N137e"></a>
time-out: this option is only used when read-only is true. In this
case, JAWS will not refresh the state of your beans from the
database more than once every time-out milliseconds.
</p></li></ul></div><p>
Each of these options can be set either generally (it will affect JAWS for
your whole application) or on a per bean basis, or both of these.
JAWS will always read the defaults first, then override them with the
bean-specific configuration.
</p><p>
General settings: to set an option generally, you have to declare it in a
<default-entity> tag in jaws.xml. Here is the section as jaws
uses
it internally: you may want to override all or part of it:
</p><pre class="programlisting">
<jaws>
<default-entity>
<create-table>true</create-table>
<remove-table>false</remove-table>
<tuned-updates>true</tuned-updates>
<read-only>false</read-only>
<time-out>300</time-out>
</default-entity>
...
<jaws>
</pre><p>
Settings for a bean: to set an option for a particular bean, do it in the
corresponding <entity> section. For example, if you want JAWS to
drop the table for your CustomerBean only, your xml file will contain:
</p><pre class="programlisting">
<jaws>
...
<enterprise-beans>
<entity>
<ejb-name>CustomerBean</ejb-name>
<remove-table>true</remove-table>
</entity>
</enterprise-beans>
...
<jaws>
</pre><p>
Note that the <ejb-name> tag must match the one declared in
ejb-jar.xml.
</p></div><div class="section"><a name="N139a"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N139a"></a><span class="title">Telling JAWS
about your tables</span></h2></div></div><p>
JAWS will use one different table for each of your CMP entity beans. The table
for one entity bean will contain one column for each of the
CMP fields of this entity.</p><p>
By default, JAWS will create the tables for you. The name of the table will be
the ejb-name of the bean, and the name of the columns will be
the name of the CMP fields. The jdbc type and the sql type will be the ones
given by the type-mapping. (see how the jdbc and sql type work
in the type mappings section)
</p><p>
However, you may want to override this behavior and tell JAWS which
names/types to use. For example, you may want JAWS to use an
already existing table. To do this, you must set these parameters in the
<enterprise-beans> section of you jaws.xml file.
</p><p>
Example 1: you create an entity bean that will represent a customer. You
already have the table in your database, it was created using the
following SQL statement:
</p><p>CREATE TABLE CUSTOMER (NAME VARCHAR(20),
ADDRESS VARCHAR(100), PHONE VARCHAR(20));</p><p>This is how the your xml file will
look like:</p><pre class="programlisting">
<jaws>
<enterprise-beans>
<entity>
<ejb-name>CustomerBean</ejb-name>
<table-name>CUSTOMER</table-name>
<create-table>false</create-table>
<cmp-field>
<field-name>customerName</field-name>
<column-name>NAME</column-name>
</cmp-field>
<cmp-field>
<field-name>address</field-name>
<column-name>ADDRESS</column-name>
</cmp-field>
<cmp-field>
<field-name>phoneNumber</field-name>
<column-name>PHONE</column-name>
</cmp-field>
</entity>
</enterprise-beans>
...
</jaws>
</pre><p>
Example 2: your bank account bean has a String field to hold the VISA card
number. You don't want to use the default mapping for a String
(VARCHAR(256)) since a VISA Card number is not that long. Your xml file will
look like this:</p><pre class="programlisting">
<jaws>
<enterprise-beans>
<entity>
<ejb-name>Account</ejb-name>
<cmp-field>
<field-name>cardNumber</field-name>
<column-name>VISA</column-name>
<jdbc-type>VARCHAR</jdbc-type>
<sql-type>VARCHAR(16)</sql-type>
</cmp-field>
...
</entity>
</enterprise-beans>
...
</jaws>
</pre><p>Note that the contents of the <ejb-name> tag and of all the
<field-name> tags must match the ones declared in
ejb-jar.xml.</p></div><div class="section"><a name="N13c1"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N13c1"></a><span
class="title">Declaring finders</span></h2></div></div><p>.
The finders to access your beans are all declared in the home interface. JAWS
automatically generates the following finders for you:
</p><div class="itemizedlist"><ul><li><p><a name="N13ca"></a>
findAll() will return a Collection of all the beans available
</p></li><li><p><a name="N13ce"></a>
findByPrimaryKey(YourPK pk) will return a single bean with the
corresponding primary key (the primary key class is defined in
ejb-jar.xml)
</p></li><li><p><a name="N13d2"></a>
for each of the cmp-fields of your bean, findByXX(YY fieldValue), where
XX is the name of the cmp-field (NOT case-sensitive)
and YY its class, will return a Collection of all the beans with the
right value in this field.
</p></li></ul></div><p>
Note that these finders are only generated if you declare them in your home
interface.
</p><p>
JAWS then allows you to define customized finders. These finders must also be
declared in the home interface of your bean. You must then
provide additional information in jaws.xml about the query to be used for this
finder. This is done in a <finder> section in the section for
your entity bean. You have to specify the name of the finder (the same as in
the home interface), the WHERE part of the query, and the
ORDER part.
</p><p>
Example: you want to select classes with a mininum number of students. Your
Class bean has the following structure:
</p><pre class="programlisting">
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>ClassBean</ejb-name>
...
<prim-key-class>java.lang.String</prim-key-class>
...
<cmp-field>
<field-name>classId</field-name>
</cmp-field>
<cmp-field>
<field-name>teacherName</field-name>
</cmp-field>
<cmp-field>
<field-name>studentCount</field-name>
</cmp-field>
<primkey-field>classId</primkey-field>
...
</entity>
</enterprise-beans>
...
</ejb-jar>
</pre><p>
You want to define a method in ClassHome:
</p><pre class="programlisting">
public Collection findBigClasses(int minStudentCount, String teacher)
throws FinderException;
</pre><p>
Your jaws.xml file will contain the following:
</p><pre class="programlisting">
<jaws>
<enterprise-beans>
<entity>
<ejb-name>ClassBean</ejb-name>
<finder>
<name>findBigClasses</name>
<query>studentCount > {0} AND teacherName = {1}</query>
<order>studentCount DESC</order>
</finder>
</entity>
</enterprise-beans>
...
</jaws>
</pre><p>
Then a call to findBigClasses(100, "Jones") will generate
</p><pre class="programlisting">
SELECT classId FROM ClassBean
WHERE studentCount > 100 AND teacherName = Jones
ORDER BY studentCount DESC;
</pre></div><div class="section"><a name="N13fe"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N13fe"></a><span class="title">Defining a
type mapping</span></h2></div></div><p>
A type mapping tells JAWS how to map java objects to a specific database. For
example, some databases have a boolean type, and other
don't, so you have to map a java.lang.Boolean to a CHAR(5).</p><p>
Many type mappings are already defined in standardjaws.xml. If you want to
define a new one, I advise you to modify one of these: copy it
and paste it to the <type-mappings> section of your jaws.xml
file.</p><p>
A type mapping is constituted of several mappings, one for each java Class
that you need to map. If your class is not found in the mappings,
JAWS will use the mapping for java.lang.Object.</p><p>
A mapping comes in 3 parts:
</p><div class="itemizedlist"><ul><li><p><a name="N1410"></a>
the <java-type> is the name of the java class you want to
map.
</p></li><li><p><a name="N1414"></a>
the <jdbc-type> is the jdbc type to use. Its value must be
one of the fields of java.sql.Types (e.g. BIT, CHAR...). This jdbc type will
be used by JAWS to determine which method to call on PreparedStatement
and ResultSet for INSERT / UPDATE / SELECT
queries.
</p></li><li><p><a name="N1418"></a>
the <sql-type> is the actual type in the database. This
value will only be used when JAWS creates your table.
</p></li></ul></div><p>
If the type mapping we provide for a particular database is faulty and you
find you have to modify it, please consider sharing your changes:
post the modified mapping on the JAWS mailing list.
</p></div></div><div class="chapter" id="N1422"><div class="titlepage"><div><h2
class="title"><a name="N1422"></a>Chapter 6. Advanced container
configuration</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>
<a href="#N1433">What is jboss.xml?</a></dt><dt> <a href="#N1448">Specifying the
deployment name of your beans</a></dt><dt> <a href="#N1486">Declaring an ejb
references</a></dt><dt> <a href="#N14be">Container
configuration</a></dt></dl></div><p>Author:
<span class="author">Sebastien Alborini</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N1433"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1433"></a><span class="title">What is
jboss.xml?</span></h2></div></div><p>
To deploy your beans, you have to specify (nearly) everything about them in a
file called ejb-jar.xml.
This file will be stored in the META-INF directory in your ejb-jar file. The
content and syntax of
this file in specified in the ejb1.1 specification (16.5 Deployment descriptor
DTD, pp 244-259).
</p><p>
An important point is that the specification does not allow you to add
vendor-specific configuration
in this file. While the ejb-jar.xml is sufficient for most applications, there
may be cases where
you want to add JBoss-specific information in your deployment descriptor. This
can be done by
providing a jboss.xml in the META-INF directory.
</p><p>
Note that this file is almost NEVER required by JBoss: JBoss will always
provide a standard behaviour
when no jboss.xml file is found. JBoss does that by first processing a
standardjboss.xml file which
contains the standard configuration.
</p><p>
This is what you CAN do in your jboss.xml file:
</p><p>
Specifying a particular jndi name for deployment. See the jndi howto
Declare external ejb references. See the ejb-ref howto
Declare resource managers. See the resource manager howto (TBD).
Customize the container configuration for your beans. See the container
configuration howto.
Get all the skinny in gorry details: jboss.xml DTD
</p></div><div class="section"><a name="N1448"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1448"></a><span class="title">Specifying
the deployment name of your beans</span></h2></div></div><p>
You have coded your beans. You now want to deploy them and be
able to access them from your clients.
</p><p>
Standard behaviour of jboss
</p><p>
The simplest way to deploy your bean is to use the ejb-jar.xml file to give it
the same name you
call it in the client. This is done in the <ejb-name> tag for the
bean. In this case you DON'T
need a jboss.xml file. Your ejb-jar.xml file will look like this (this is
covered in the beginners trails):
</p><p>
ejb-jar.xml:
</p><pre class="programlisting">
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>MyBeanName</ejb-name>
<home>MyBeanHome</home>
<remote>MyBean</remote>
<ejb-class>MyBeanEJB</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
...
</ejb-jar>
</pre><p>
And your bean will be available under the "MyBeanName" in JNDI.
In your client code, your call will look like this:
</p><pre class="programlisting">
public class Client {
...
public static void main(String arg[]) {
...
//No need to use the "narrow" operation, a cast will work in jboss
MyBeanHome home = (MyBeanHome) new InitialContext().lookup("MyBeanName");
...
}
}
</pre><p>
Here the "MyBeanName" refers to the name of your bean in the jndi namespace.
JBoss does not currently allow
you to use the java:comp/env namespace to call your beans from your clients.
</p><p>
If you want to give a jndi deployment name different than the ejb-name
</p><p>
You may want to deploy your bean under another jndi name. (for example, you
may want to deploy the same
bean under different names with different configurations). In this case, you
must specify the jndi name
in a jboss.xml file. This file must be in the META-INF directory, along with
ejb-jar.xml. Your files
will look like this (note that the <ejb-name>tags in the two xml
files must match):
</p><p>
jboss.xml:
</p><pre class="programlisting">
<jboss>
<enterprise-beans>
<session>
<ejb-name>MyBeanName</ejb-name>
<jndi-name>somePath/otherName</jndi-name>
</session>
</enterprise-beans>
</jboss>
</pre><p>
(you don't need to specify the rest of the jboss.xml file, only this
information is sufficient in the
new metadata, this is what we call "differential" jboss.xml).
</p><p>
Your bean is then available in JNDI under somePath/otherName
</p><p>
In your client code, your call will look like this:
</p><pre class="programlisting">
public class Client {
...
public static void main(String arg[]) {
...
//No need to use the "narrow" operation, a cast will work in jboss
MyBeanHome home = (MyBeanHome) new
InitialContext().lookup("somePath/otherName");
...
}
}
</pre></div><div class="section"><a name="N1486"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1486"></a><span class="title">Declaring an
ejb references</span></h2></div></div><p>
An ejb reference (see ejb1.1 specification, 14.3, p207) is when a bean A wants
to call methods on a bean B.
We are talking about intra-bean calls also called B2B calls. This is not for
clients (that is covered in
the beginner trails) this is for bean calls all on the server. Most of these
calls are done inside the
server VM.
</p><p>
This call will look like this: (beans running on the server must use the
java:comp/env namespace).
</p><pre class="programlisting">
public class ABean implements EntityBean {
...
public void BusinessMethod(...) {
...
BHome home = (BHome)ctx.lookup("java:comp/env/ejb/myBean");
B bean = home.create(pk);
...
}
}
</pre><p>
To be allowed this call, the bean A must declare it in the its deployment
descriptor. This is done by an <ejb-ref>
tag in the bean section of the ejb-jar.xml file. 2 cases may occur:
</p><p>
Internal ejb reference: the bean B is in the same application unit as the bean
A. This means that the beans are
physically packaged in the same jar. In this case, you must provide the
<ejb-link> tag, and its value must
match the <ejb-name> of bean B. You don't have to provide anything
in the jboss.xml file. Your ejb-jar.xml
file will look like this:
</p><pre class="programlisting">
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Bean A</ejb-name>
<home>AHome</home>
<remote>A</remote>
<ejb-class>ABean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
<ejb-ref>
<ejb-ref-name>ejb/myBean</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>BHome</home>
<remote>B</remote>
<ejb-link>Bean B</ejb-link>
</ejb-ref>
</session>
<entity>
<ejb-name>Bean B</ejb-name>
<home>BHome</home>
<remote>B</remote>
<ejb-class>BBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>myPK</prim-key-class>
<reentrant>True</reentrant>
</entity>
</enterprise-beans>
...
</ejb-jar>
</pre><p>
External ejb reference: the bean B comes from another application unit, it may
even be deployed on another server.
This means that the beans live in different jars on different systems. In this
case, you cannot rely on the
standard <ejb-link> tag in ejb-jar.xml since there the beans are
not covered in the same file. Instead, you must
provide the full jndi name of the bean B in jboss.xml. This is necessary to
map the names from different ejb-jar.xml
files since the 2 beans are defined in different application units. A full
name is of the form:
</p><p>
protocol://host:1234/name/in/other/server
Note that the <ejb-ref-name> tags in the 2 xml files must match.
</p><p>
ejb-jar.xml:
</p><pre class="programlisting">
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Bean A</ejb-name>
<home>AHome</home>
<remote>A</remote>
<ejb-class>ABean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
<ejb-ref>
<ejb-ref-name>ejb/myBean</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>BHome</home>
<remote>B</remote>
</ejb-ref>
</session>
</enterprise-beans>
...
</ejb-jar>
</pre><p>
jboss.xml:
</p><pre class="programlisting">
<jboss>
<enterprise-beans>
<session>
<ejb-name>Bean A</ejb-name>
<ejb-ref>
<ejb-ref-name>ejb/myBean</ejb-ref-name>
<jndi-name>t3://otherserver/application/beanB</jndi-name>
</ejb-ref>
</session>
<enterprise-beans>
</jboss>
</pre><p>
If bean B is deployed in another application, but on the same jboss server,
the jndi-name you provide must be
the name under which bean B is deployed (see the jndi_howto)
</p><p>
IMPORTANT NOTE: this will tell jboss where to look for bean B. You also have
to tell jboss what bean B is:
in case of an external ejb-reference, be sure to include bean B's home and
remote interface in bean A's ejb-jar.
</p></div><div class="section"><a name="N14be"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N14be"></a><span class="title">Container
configuration</span></h2></div></div><p>
When you deploy an application, JBoss creates a container for each of your
beans. This container will be used
only for this particular bean. It must be configured according to the type of
the bean (CMP Entity Bean, Stateful
Session Bean, etc.). Different standard configurations are stored in the
standardjboss.xml file. You may provide
additional custom configurations in the jboss.xml file for your application.
</p><p>
Standard Configurations
</p><p>
JBoss currently provides a standard configuration for each type of bean. These
configurations are stored in the
standardjboss.xml file. There are currently 8 standard configurations. If you
don't provide anything else (as we
advise you to do, at least at the beginning), JBoss will automatically choose
the right standard configuration for
your container. The available configurations are the following:
</p><p>
Standard CMP EntityBean
Standard BMP EntityBean
Standard Stateless SessionBean
Standard Stateful SessionBean
jdk1.2.2 CMP EntityBean
jdk1.2.2 BMP EntityBean
jdk1.2.2 Stateless SessionBean
jdk1.2.2 Stateful SessionBean
</p><p>
The first four ones are used if you run JBoss with a jdk1.3 JVM. The four last
ones are used if you run JBoss with
a jdk1.2.2 JVM.
</p><p>
How do I configure my bean for jdk1.2.2 clients ?
If you run JBoss on a jdk1.3 JVM, but your clients use jdk1.2.2, the standard
configuration won't work (the protocols
are not backward compatible). In this case, you have to force JBoss to use the
corresponding jdk1.2.2 configuration.
You do that by providing a jboss.xml file. This file must be in the META-INF
directory of your jar file, along with
ejb-jar.xml. In the section for your bean, simply add a
<configuration-name> tag. Your xml files will look like
this (note that the <ejb-name> tags in the 2 xml files must match)
ejb-jar.xml:
</p><pre class="programlisting">
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Bean A</ejb-name>
<home>AHome</home>
<remote>A</remote>
<ejb-class>ABean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
</ejb-ref>
</session>
</enterprise-beans>
...
</ejb-jar>
</pre><p>
jboss.xml:
</p><pre class="programlisting">
<jboss>
<enterprise-beans>
<session>
<ejb-name>Bean A</ejb-name>
<configuration-name>jdk1.2.2 Stateful
SessionBean<configuration-name>
</session>
<enterprise-beans>
</jboss>
</pre><p>
How do I specify my own custom configuration ?
You may want to provide your own advanced configuration. For example, you may
want to increase the size of your pool,
or use a different instance cache. To do this, you must define your
configuration in jboss.xml in the
<container-configurations> tag. Then you have to use your new
configuration in the bean section of your jboss.xml file.
For example, if you want to log calls to your bean, your file will look like
this :
</p><pre class="programlisting">
<jboss>
<enterprise-beans>
<session>
<ejb-name>Bean A</ejb-name>
<configuration-name>Logging Configuration<configuration-name>
</session>
<enterprise-beans>
...
<container-configurations>
<container-configuration>
<container-name>Logging Configuration</container-name>
<call-logging>true</call-logging>
<container-invoker>org.jboss.ejb.plugins.jrmp13.server.JRMPContainerInvoker</container-invoker>
<instance-cache>org.jboss.ejb.plugins.StatefulSessionInstanceCache</instance-cache>
<persistence-manager>org.jboss.ejb.plugins.StatefulSessionFilePersistenceManager</persistence-manager>
<transaction-manager>org.jboss.tm.TxManager</transaction-manager>
<container-invoker-conf>
<Optimized>False</Optimized>
</container-invoker-conf>
</container-configuration>
</container-configurations>
...
</jboss>
</pre><p>
How do I specify advanced cache configuration ?
</p><p>
JBoss currently provides the possibility to choose the cache configuration for
each container configuration. You may want
to define your own cache settings, and to do so you must specify them in
jboss.xml under the <instance-cache> tag and
subtags. Currently 2 cache algorithms have been implemented: a no passivation
cache algorithm (so that all the bean are
kept in memory, unless the bean is an entity bean and you specified for it
commit option C), and a least recently used (LRU)
cache algorithm (so that bean less frequently used are passivated to save
server resources).
</p><p>
Let's see how to configure both caches. The examples below are about entity
beans, but the cache settings applies as well
for stateful session beans.For the no passivation cache, jboss.xml will look
like this:
</p><pre class="programlisting">
<jboss>
<enterprise-beans>
<entity>
<ejb-name>Bean A</ejb-name>
<configuration-name>No Passivation
Configuration<configuration-name>
</entity>
<enterprise-beans>
...
<container-configurations>
<container-configuration>
<container-name>No Passivation Configuration</container-name>
...
<instance-cache>org.jboss.ejb.plugins.EntitySessionInstanceCache</instance-cache>
<container-cache-conf>
<cache-policy>org.jboss.ejb.plugins.NoPassivationCachePolicy</cache-policy>
</container-cache-conf>
...
</container-configuration>
</container-configurations>
...
</jboss>
</pre><p>
No further settings are available for the no passivation cache.
For the LRU cache, jboss.xml will look like this:
</p><pre class="programlisting">
<jboss>
<enterprise-beans>
<entity>
<ejb-name>Bean A</ejb-name>
<configuration-name>LRU Configuration<configuration-name>
</entity>
<enterprise-beans>
...
<container-configurations>
<container-configuration>
<container-name>LRU Configuration</container-name>
...
<instance-cache>org.jboss.ejb.plugins.EntitySessionInstanceCache</instance-cache>
<container-cache-conf>
<cache-policy>org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicy</cache-policy>
<cache-policy-conf>
<min-capacity>5</min-capacity>
<max-capacity>200</max-capacity>
<overager-period>300</overager-period>
<max-bean-age>600</max-bean-age>
<resizer-period>400</resizer-period>
<max-cache-miss-period>60</max-cache-miss-period>
<min-cache-miss-period>1</min-cache-miss-period>
<cache-load-factor>0.75</cache-load-factor>
</cache-policy-conf>
</container-cache-conf>
...
</container-configuration>
</container-configurations>
...
</jboss>
</pre><div class="itemizedlist"><ul><li><p><a
name="N1502"></a><cache-policy-conf> and its subtags are optional, so you
can specify none, few or all of them.
<min-capacity> specifies the minimum capacity of the cache. The
cache can be empty, but will have room for at least
5 beans (in the above case); this value cannot be less than 2; the resizer
(see below) will shrink the cache capacity
down to but not less than this value.
</p></li><li><p><a name="N1508"></a><max-capacity> specifies the maximum
capacity of the
cache. The cache can be empty, but will have room for at most 200
beans (in the above case); this value cannot be less than the minimum
capacity; the resizer (see below) will enlarge the
cache capacity up to but not more than this value.
</p></li><li><p><a name="N150e"></a><overager-period> specifies the period of
the overager,
that is a periodic task that runs (in the above case) every 300
seconds. Purpose of this periodic task is to see if in the cache there are
very old beans, and to passivate them.
The age at which a bean is considered too old is also configurable (see
below). While the period of this task is 300 seconds, the first run happens at
a random time between 0 and 300 seconds.
To disable the overager set the period to 0.
</p></li><li><p><a name="N1514"></a><max-bean-age> specifies the max age a
bean can have
before being passivated by the overager (in this case 600 seconds).
The tag <resizer-period> specifies the period of the resizer, that
is a periodic task that runs (in the above case) every
400 seconds. Purpose of this periodic task is to shrink / enlarge the cache
capacity upon 3 other parameters (see below).
While the period of this task is 400 seconds, the first run happens at a
random time between 0 and 400 seconds.
To disable the resizer set the period to 0.
</p></li><li><p><a
name="N151a"></a><max-cache-miss-period>,<min-cache-miss-period>
and <cache-load-factor> control the resizer in this way: the
number of
cache misses is internally recorded. When the resizer runs, it sees what is
the cache miss rate from the last time it ran.
If there is more than (in the above case) one cache miss every 1 second
(min-cache-miss-period) then the resizer tries to
enlarge the cache; if there is less than (in this case) one cache miss every
60 seconds (max-cache-miss-period) then the
resizer tries to shrink the cache. How much is the cache enlarged / shrinked ?
Here is where the load-factor comes in the
picture. When the resizer shrinks, it tries to shrink the cache so that (in
this case) the ratio number of beans / cache
capacity is 0.75; when the resizer enlarges, it tries to enlarge the cache by
a factor 1 / 0.75 == 1.333 (in the above case) plus a correction calculated
from the cache miss rate (so that the more cache miss rate you have, the more
the cache is enlarged, starting from at least 1.333; so if you really have a
lot of cache misses, the resizer may decide to enlarge the cache of a factor
2.0 instead of 1.333 - if there is room for that).
</p></li></ul></div><p>
What can be configured ?
</p><p>
These are the different things you can customize in a
<container-configuration> tag in jboss.xml. See the jboss.xml DTD
for
more details:
</p><div class="itemizedlist"><ul><li><p><a name="N1529"></a><call-logging>
this tag must have a boolean value: true
or false. It tells the container if calls to this bean must be
logged or not. It is set to false in standard configurations.
</p></li><li><p><a name="N152f"></a><container-invoker> the container invoker.
</p></li><li><p><a name="N1535"></a><instance-pool> the instance pool is a set
(a "pool") of
free (ie not currently associated to a context) instances of the
bean. When an instance of the bean is no longer used, it is thrown back to the
pool. This is not used for Stateful Session
Beans, since the instances are not reusable.
</p></li><li><p><a name="N153b"></a><instance-cache> the cache contains the
instances of a
bean which are currently associated to a context. If it grows too
big, the cache may decide to passivate some of the instances. This is not used
for Stateless Session Beans, since these
are directly reusable after a call.
</p></li><li><p><a name="N1541"></a><persistence-manager> the persistence
manager is in
charge of storing permanent information in the instance of a bean.
For BMP Entities, it will merely transmit orders to the bean; for Stateful
Sessions and CMP Entities, it has to save the
state of the bean. This is not used for Stateless Session Beans, since they
don't have a state to save.
</p></li><li><p><a name="N1547"></a><container-invoker-conf> configuration of
the container
invoker.
</p></li><li><p><a name="N154d"></a><container-cache-conf> configuration of
the cache. For
example, you may specify the time interval between passivations.
</p></li><li><p><a name="N1553"></a><container-pool-conf> configuration of the
pool. Mainly,
the size of the pool.
</p></li><li><p><a name="N1559"></a><commit-option> must be A, B or C. See the
ejb
specification for more details.
</p></li></ul></div></div></div><div class="chapter" id="N1562"><div
class="titlepage"><div><h2 class="title"><a name="N1562"></a>Chapter 7. Working with
Message Driven Beans</h2></div></div><div class="toc"><p><b>Table of
Contents</b></p><dl><dt> <a href="#N1573">Introduction</a></dt><dt> <a
href="#N157b">Six steps to MDB nirvana in JBoss</a></dt><dt> <a href="#N15ef">Writing
Message Driven Bean</a></dt><dd><dl><dt> <a href="#N160e">Hello World MDB</a></dt><dt>
<a href="#N1655">MDB as a listener</a></dt><dt> <a href="#N16b3">The adapter
pattern</a></dt></dl></dd><dt> <a href="#N16ea">Advanced MDB
configuration</a></dt><dd><dl><dt> <a href="#N16f4">EJB deployment
descriptor</a></dt><dt> <a href="#N1744">JBoss
configuration</a></dt></dl></dd></dl></div><p>Author:
<span class="author">Peter Antman</span>
<tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N1573"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N1573"></a><span
class="title">Introduction</span></h2></div></div><p>This chapter describes how to use
Message Driven Beans with JBoss. Message Driven Beans are a new bean type added in the
EJB 2.0 specification. They are therefore still somewhat unknown and under utilized.
Hopefully this documentation will lessen that a bit, since JBoss has full support for
Message Driven Beans.</p></div><div class="section"><a name="N157b"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N157b"></a><span
class="title">Six steps to MDB nirvana in JBoss</span></h2></div></div><p>If you don't
need to do any special configuration and already know how to code a message driven
bean (MDB), here are 6 easy step to get it up and working with JBoss. (The easiest
way to get up and working with Message Driven Beans in JBoss is the check out the jbos!
stest from cvs and look into the mdb test.)</p><div class="orderedlist"><ol
type="1"><li><p><a name="N1588"></a>
Check out the latest JBoss from cvs and compile.
</p></li><li><p><a name="N158e"></a>
Write the source code for a Message Driven Bean.
</p></li><li><p><a name="N1594"></a>Write the ejb-jar.xml
descriptor.</p><p>Here is an example for a bean listening on a queue with bean managed
transactions :</p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar>
<!--
PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd"
-->
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>QueueBean</ejb-name>
<ejb-class>org.jboss.test.mdb.bean.QueueBean</ejb-class>
<message-selector></message-selector>
<transaction-type>Bean</transaction-type>
<acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
<message-driven-destination>
<destination-type>javax.jms.Queue</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
</ejb-jar>
</pre><p>
And here are one for a durable topic with container managed
transactions:</p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar>
<message-driven>
<ejb-name>DurableTopicBean</ejb-name>
<ejb-class>org.jboss.test.mdb.bean.TopicBean</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>Durable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>DurableTopicBean</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
</pre></li><li><p><a name="N15aa"></a>
Write the jboss.xml deployment descriptor (this MUST always be done with MDB in
jboss), but for a MDB without special need the container configuration need not be
filled in. </p><p>The destination-jndi-name element points to the queue.</p><p> Here
are the one for the queue bean:</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>QueueBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>queue/testQueue</destination-jndi-name>
</message-driven>
</enterprise-beans>
</jboss>
</pre><p> And here for the durable topic:</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>DurableTopicBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>topic/testDurableTopic</destination-jndi-name>
<mdb-user>john</mdb-user>
<mdb-passwd>needle</mdb-passwd>
<mdb-client-id>DurableSubscriberExample</mdb-client-id>
</message-driven>
</jboss>
</pre></li><li><p><a name="N15c3"></a>
Edit jbossmq.xml in conf/default and ad the queue or topic
</p><p>Eg:</p><pre class="programlisting">
<Queue>
<Name>testQueue</Name>
</Queue>
</pre><p> For the queue, and </p><pre class="programlisting">
<Topic>
<Name>testDurableTopic</Name>
</Topic>
</pre><p>plus</p><pre class="programlisting">
<User>
<Name>john</Name>
<Password>needle</Password>
<Id>DurableSubscriberExample</Id>
<DurableSubscription>
<Name>DurableSubscriberExample</Name>
<TopicName>testDurableTopic</TopicName>
</DurableSubscription>
</User>
</pre><p>for the durable topic.</p></li><li><p><a name="N15e4"></a>
Deploy the bean, for example by packing it in a jar and copy it into the jboss
deploy directory.</p></li></ol></div><p>Start sending messages to your
bean</p></div><div class="section"><a name="N15ef"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N15ef"></a><span class="title">Writing
Message Driven Bean</span></h2></div></div><p>Message Driven Beans are a new part of
EJB 2.0. The reason these beast where added is that there was no way in EJB 1.1 to
handle asynchronous invocation. The primary reason behind this is that an EJB bean may
never be invoke from other objects other than through its remote interface. Therefore
a bean could never set itself up as a listener for asynchronous invocation.</p><p>With
MDB this lack is filled. An MDB is a bean without a remote interface, where the
container sets itself up as a listener for asynchronous invocation and handles the
invocation of the concrete bean, which follows all the usual roles for EJ!
B beans.</p><p>Message Driven Beans are primarily focused on JMS. An MDB is either a
topic or a queue subscriber. One nice feature with MDB is that one gets multithreaded
subscribers (even for Topics) without having to care about the subtle difficulties to
write multithreaded code and to write multithreaded JMS message consumers.</p><p>What
should you use your beans to then? Basically you would use MDB any time you are about
to create a JMS subscriber. Typical conditions for doing this is:</p><div
class="itemizedlist"><ul><li><a name="N1601"></a>
Decouple an invoker from the invoked code.
</li><li><a name="N1604"></a>
Make it possible for multiple parties to get you messages.
</li><li><a name="N1607"></a>
Get asynchronous behavior, i.e. start long running code without the need to wait for
the call to return.
</li></ul></div><p>Here we will write some typical MDB.</p><div class="section"><a
name="N160e"></a><div class="titlepage"><div><h3 class="title"><a
name="N160e"></a><span class="title">Hello World MDB</span></h3></div></div><p>An MDB
follows a typical EJB contract. It must implement the following two
interfaces:</p><div class="itemizedlist"><ul><li><a name="N1617"></a>
javax.ejb.MessageDrivenBean
</li><li><a name="N161a"></a>
javax.jms.MessageListener
</li></ul></div><p>An MDB must therefore typically contain the following four
methods:</p><pre class="programlisting">
public void setMessageDrivenContext(MessageDrivenContext ctx);
public void ejbCreate();
public void ejbRemove();
public void onMessage(Message message);
</pre><p>The full program listing of a simple Hello World bean could look like
this:</p><pre class="programlisting">
package test.bean;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.ejb.EJBException;
import javax.jms.MessageListener;
import javax.jms.Message;
public class MDB implements MessageDrivenBean, MessageListener{
private MessageDrivenContext ctx = null;
public MDB() {
}
public void setMessageDrivenContext(MessageDrivenContext ctx)
throws EJBException {
this.ctx = ctx;
}
public void ejbCreate() {}
public void ejbRemove() {ctx=null;}
public void onMessage(Message message) {
System.err.println("Bean got message" + message.toString() );
}
}
</pre><p>To deploy this into JBoss we will have to write two deployment descriptors.
One standard ejb-jar and one that is JBoss specific. We will chose to make this bean a
Topic subscriber. Since we do not do anything we could typically chose to use
container managed transaction with NotRequired (although this would in most cases not
be the best thing to do)</p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar>
<message-driven>
<ejb-name>MDB</ejb-name>
<ejb-class>test.bean.MDB</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>DurableTopicBean</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>NotRequired</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
</pre><p>We also need to write a small deployment descriptor that is specific for
JBoss. The full version of this is quite big, and with it it is possible to configure
the MDB container quite a bit. For most users this is not necessary, and the may use
the standard configuration. The most important part of the descriptor is the
specification of the destination. We chose the testTopic since it is always available
in JBoss.</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>MDB</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>test/testTopic</destination-jndi-name>
</message-driven>
</enterprise-beans>
</jboss>
</pre><p>Then you will have to pack these into a jar. Here is one way to do
it:</p><pre class="programlisting">
mkdir dist
mkdir dist/META-INF
mkdir dist/test
cp MDB.class dist/test
cp MDB-jar.xml dist/META-INF/ejb-jar.xml
cp MDB-jboss.xml dist/META-INF/jboss.xml
cd dist
java jar -cvf mdb.jar .
</pre><p>Copy the bean into the deploy directory of JBoss.</p><p>To send stuff to
your bean you need a JMS publisher. This is standard JMS programming, but here is one
way to do it:</p><pre class="programlisting">
import javax.naming.*;
import javax.jms.*;
public class Main {
public static void main(String arg[]) {
try {
// Get access to JNDI
Context context = new InitialContext();
// Lookup the managed connection factory for a topic
TopicConnectionFactory topicFactory =
(TopicConnectionFactory)context.lookup(TOPIC_FACTORY);
// Create a connection to the JMS provider
TopicConnection topicConnection = topicFactory.createTopicConnection();
// Creat a topic session
TopicSession session = topicConnection.createTopicSession(
// No transaction
false,
// Auto ack
Session.AUTO_ACKNOWLEDGE);
// Lookup the destination you want to publish to
Topic topic = (Topic)context.lookup("topic/testTopic");
// Create a publisher
TopicPublisher pub = session.createPublisher(topic);
// Create a message
TextMessage message = session.createTextMessage();
message.setText("Hello World!");
// Publish the message
pub.publish(topic, message);
// Close the stuff
session.close();
topicConnection.close();
catch (Exception e) {
e.printStackTrace();
}
}
}
</pre><p>
You will typically have to include the following jars in your classpath:
jbossmq.client.jar, jms.jar, jnp-client.jar and jta-spec1_0_1.jar.
</p></div><div class="section"><a name="N1655"></a><div class="titlepage"><div><h3
class="title"><a name="N1655"></a><span class="title">MDB as a
listener</span></h3></div></div><p>We will here look at an example that does something
more real. One nice way to use MDB is to have them act/emulate the listener pattern.
The normal way with listeners is to have them register them self on the object
emitting events. This is not possible with MDB, since the bean them self may only do
some work when the receive an even (a message). Set up of MDB as a listener will
therefore have to be done outside of the MDB. This could be as simple as defining a
topic or queue and hardwire into the event generator to publish it's events/messages
to that destination. It's also possible to create a more generic framework for message
driven callback, something I have done with JMS and JMX. But that is for another
document. Lets instead look on the MDB side.</p><p>One way to partition the logic in
EJ!
B is to have one bean that does the real work (contains the logic), this could be a
stateless session bean or an entity bean, and one bean acting as a listener. Lets
write a working, but simplified version of this patter. We start with a very simple
stateless session bean, with just one method: doWork. To make it easy we let it take a
String as its mission. This is straight forward. First we need a home
interface:</p><pre class="programlisting">
package msgbean.interfaces;
import java.rmi.RemoteException;
import javax.ejb.*;
public interface WorkerHome extends EJBHome {
public Worker create() throws RemoteException, CreateException;
} // WorkerHome
</pre><p>We also need a remote interface</p><pre class="programlisting">
package msgbean.interfaces;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface Worker extends EJBObject {
public void doWork(String work) throws RemoteException;
} // Worker
</pre><p>And finally we need the bean class:</p><pre class="programlisting">
package msgbean.server;
import javax.ejb.*;
import java.rmi.RemoteException;
import javax.naming.*;
public class WorkerBean implements SessionBean {
private SessionContext ctx;
public WorkerBean() {
}
public void setSessionContext(javax.ejb.SessionContext ctx) throws
RemoteException { this.ctx = ctx; }
public void unsetSessionContext() throws RemoteException { this.ctx = null; }
public void ejbActivate() throws RemoteException {}
public void ejbPassivate() throws RemoteException {}
public void ejbRemove() throws RemoteException {}
public void ejbCreate() throws CreateException {}
public void doWork(String work) {
System.out.println("WorkerBean doing work: " + work);
}
} // WorkerBean
</pre><p>We will write the deployment descriptor for the bean later, since we will
pack it with the listener.</p><p>The next step is to write the listener bean. Here we
will ad basically one thing: the ability to lookup the Worker bean and invoke it. We
look up the bean through a an JNDI reference defined via ejb-ref. This might be done
in ejbCreate().</p><pre class="programlisting">
Context initCtx = new InitialContext();
workerHome = (WorkerHome)initCtx.lookup("java:comp/env/ejb/worker");
</pre><p>In the onMessage() method we get what we need out of the message. Here we
could have sent an object of some kind, known to the listener. For simplicity we here
chose to send a TextMessage and send the content of the message to the worker.</p><pre
class="programlisting">
Worker worker = workerHome.create();
if (message instanceof TextMessage) {
TextMessage m = (TextMessage)message;
worker.doWork(m.getText());
}
</pre><p>Here is the complete listing of the class:</p><pre class="programlisting">
package msgbean.server;
import javax.ejb.*;
import javax.naming.*;
import javax.jms.*;
import msgbean.interfaces.WorkerHome;
import msgbean.interfaces.Worker;
public class ListenerBean implements MessageDrivenBean, MessageListener{
private MessageDrivenContext ctx = null;
private WorkerHome workerHome = null;
public ListenerBean() {
}
public void setMessageDrivenContext(MessageDrivenContext ctx)
throws EJBException {
this.ctx = ctx;
}
public void ejbCreate() throws CreateException {
try {
Context initCtx = new InitialContext();
workerHome = (WorkerHome)initCtx.lookup("java:comp/env/ejb/worker");
}catch(Exception ex) {
throw new CreateException("Could not get worker: " + ex);
}
}
public void ejbRemove() {ctx=null;}
public void onMessage(Message message) {
try {
Worker worker = workerHome.create();
// Get the message, here we could have an ObjectMessage containg
// an object of a known class. We use Text here for simplicity
if (message instanceof TextMessage) {
TextMessage m = (TextMessage)message;
worker.doWork(m.getText());
}
}catch(Exception ex) {
throw new EJBException("Could not call worker " + ex);
}
}
}
</pre><p>To deploy this into JBoss we need to write two deployment descriptors, one
standard ejb, and one for JBoss. Lets begin with the standard one. For ease of use we
include both beans into one jar. For the Message Driven Bean we have to decide if its
a topic or not, and what kind of transactions it should run under. In this case we
chose a topic and container managed transaction. We also have to specify an ejb-ref so
that the listener can lookup the home of the WorkerBean:</p><pre
class="programlisting">
<message-driven>
<ejb-name>ListenerBean</ejb-name>
<ejb-class>msgbean.server.ListenerBean</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<ejb-ref>
<description>The Workers home</description>
<ejb-ref-name>ejb/worker</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<ejb-link>WorkerBean</ejb-link>
<home>msgbean.interfaces.WorkerHome</home>
<remote>msgbean.interfaces.Worker</remote>
</ejb-ref>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</pre><p>We also have to ad an entry for the Worker bean:</p><pre
class="programlisting">
<session>
<description>Worker bean</description>
<display-name>Worker</display-name>
<ejb-name>WorkerBean</ejb-name>
<home>msgbean.interfaces.WorkerHome</home>
<remote>msgbean.interfaces.Worker</remote>
<ejb-class>msgbean.server.WorkerBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</pre><p>Here is the complete deployment descriptor, including defintions of the
transaction type.</p><pre class="programlisting">
<!DOCTYPE ejb-jar>
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>ListenerBean</ejb-name>
<ejb-class>msgbean.server.ListenerBean</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<ejb-ref>
<description>The Workers home</description>
<ejb-ref-name>ejb/worker</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<ejb-link>WorkerBean</ejb-link>
<home>msgbean.interfaces.WorkerHome</home>
<remote>msgbean.interfaces.Worker</remote>
</ejb-ref>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
<session>
<description>Worker bean</description>
<display-name>Worker</display-name>
<ejb-name>WorkerBean</ejb-name>
<home>msgbean.interfaces.WorkerHome</home>
<remote>msgbean.interfaces.Worker</remote>
<ejb-class>msgbean.server.WorkerBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>ListenerBean</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>WorkerBean</ejb-name>
<method-intf>Remote</method-intf>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
</pre><p>We also need to write a jboss.xml deployment descriptor. This is needed
because it the destination JNDI name must be defined somewhere. Here we can not use on
a default.</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>ListenerBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>topic/testTopic</destination-jndi-name>
</message-driven>
<secure>false</secure>
</enterprise-beans>
</jboss>
</pre><p>We then have to compile the beans. You will have to add several jar-files
to your class-path to have success with this. Among the most important, and special
for MDB, is that you will need ejb2.0 from lib/ext to be able to compile. You also
need to pack them into a jar-file. Do this as described above. Deploy by copying the
jar-file to deploy. You may use the example publisher above to publish messages to the
bean.</p></div><div class="section"><a name="N16b3"></a><div
class="titlepage"><div><h3 class="title"><a name="N16b3"></a><span class="title">The
adapter pattern</span></h3></div></div><p>Another way to use MDB is as an adapter, for
example between different messaging systems. This is rewarding, especially if you have
an J2EE Connector resource adapter for the other system, since you then will get a
very effective, multithreaded and pooled system, without any advanced programing.
Since I have written such a resource adapter for the messaging server XmlBlaste!
r we will here look at one way to adapt between JMS and <a
href="http://www.xmlblaster.org" target="_top"><i>XmlBlaster</i></a>.</p><p>The
adapter uses an MDB to subscribe to a topic. It then republish it to an XmlBlaster
server through the XmlBlasterK2 J2EE Connector adapter.The code is pretty straight
forward. A J2EE Connector resource adapter must be deployed into the JBoss server. It
is then referenced from within the bean the same way you would reference a JDBC
resource. You would look it up this way:</p><pre class="programlisting">
factory = (BlasterConnectionFactory)new InitialContext ().lookup
("java:comp/env/xmlBlaster");
</pre><p>And use it this way:</p><pre class="programlisting">
con = factory.getConnection();
// Construct Blaster Headers
String key ="<key oid=\"" + message.getJMSMessageID() +"\"
contentMime=\"text/xml\"></key>";
String qos = "<qos></qos>";
con.publish( new MessageUnit(key,msg.getBytes(),qos));
</pre><p>The complete bean is pretty straight forward (almost the same code could be
used to write directly to a database for example):</p><pre class="programlisting">
package javaclients.j2ee.k2;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.ejb.EJBException;
import javax.jms.MessageListener;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.JMSException;
import javax.resource.ResourceException;
import org.xmlBlaster.j2ee.k2.client.*;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.engine.helper.MessageUnit;
public class JmsAdapter implements MessageDrivenBean, MessageListener{
private MessageDrivenContext ctx = null;
private BlasterConnectionFactory factory = null;
public JmsAdapter() {
}
public void setMessageDrivenContext(MessageDrivenContext ctx)
throws EJBException {
this.ctx = ctx;
try {
factory = (BlasterConnectionFactory)new InitialContext ().lookup
("java:comp/env/xmlBlaster");
} catch (NamingException ex) {
throw new EJBException ("XmlBlaster not found: "+ex.getMessage ());
}catch(Throwable th) {
System.err.println("Throwable: " +th);
th.printStackTrace();
throw new EJBException("Throwable in setContext: " +th);
}
}
public void ejbCreate() {}
public void ejbRemove() {ctx=null;}
public void onMessage(Message message) {
BlasterConnection con = null;
try {
// Get message to handle
System.err.println("Got message: " + message);
if (message instanceof TextMessage) {
String msg = ((TextMessage)message).getText();
// Get connection
con = factory.getConnection();
// Construct Blaster Headers - howto hanlde key here?
String key ="<key oid=\"" + message.getJMSMessageID() +"\"
contentMime=\"text/xml\"></key>";
String qos = "<qos></qos>";
con.publish( new MessageUnit(key,msg.getBytes(),qos));
} else {
System.err.println("Got message type I cant handle");
}
}catch(ResourceException re) {
System.err.println("Resource ex: " +re);
re.printStackTrace();
} catch(XmlBlasterException be) {
System.err.println("Blaster ex: " +be);
be.printStackTrace();
}catch(JMSException je) {
System.err.println("JMSException ex: " +je);
je.printStackTrace();
}catch(Throwable th) {
System.err.println("Throwable: " +th);
th.printStackTrace();
}finally {
try {
if (con != null)
con.close ();
}
catch (Exception ex) {}
}
}
} // MessageBeanImpl
</pre><p>The deployment descriptors for this bean follows the normal way to write
them, except that you will have to add entries for the resource-ref. Here is the ejb
deployment descriptor:</p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar>
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>JmsAdapter</ejb-name>
<ejb-class>javaclients.j2ee.k2.JmsAdapter</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>xmlBlaster</res-ref-name>
<res-type>org.xmlBlaster.j2ee.k2.client.BlasterConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>JmsAdapter</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
</pre><p>And here is the jboss.xml descriptor:</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<resource-managers>
<resource-manager>
<res-name>xmlBlaster</res-name>
<res-jndi-name>java:/XmlBlasterDS</res-jndi-name>
</resource-manager>
</resource-managers>
<enterprise-beans>
<message-driven>
<ejb-name>JmsAdapter</ejb-name>
<configuration-name>Standrad Message Driven
Bean</configuration-name>
<destination-jndi-name>topic/testTopic</destination-jndi-name>
<resource-ref>
<res-ref-name>xmlBlaster</res-ref-name>
<resource-name>xmlBlaster</resource-name>
</resource-ref>
</message-driven>
<secure>false</secure>
</enterprise-beans>
</jboss>
</pre></div></div><div class="section"><a name="N16ea"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N16ea"></a><span
class="title">Advanced MDB configuration</span></h2></div></div><p>The MDB
implementation for JBoss have been written such that a user should not have to know a
lot about the internals of JBoss. A part from the feew necessary lines in jboss.xml
nothing else than standard knowledge of Message Driven Beans should
suffice.</p><p>Following the design of JBoss, the MDB implementation is also extremely
configurable, if one want to tune or totally change the default configuration and
implementation! Here follows some short notes on howto configure MDB for JBoss</p><div
class="section"><a name="N16f4"></a><div class="titlepage"><div><h3 class="title"><a
name="N16f4"></a><span class="title">EJB deployment
descriptor</span></h3></div></div><p>All MDB:s are quite configurable, apart from them
being deployed in JBoss. Here are the basic !
choices that can be made:</p><div class="itemizedlist"><ul><li><p><a
name="N16fd"></a>A bean may be either a javax.jms.Topic or a javax.jms.Queue bean,
which is decided in the stanza "destination-type", eg.</p><pre class="programlisting">
<message-driven-destination>
<destination-type>javax.jms.Queue</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</pre></li><li><p><a name="N1708"></a>If a bean is a Topic it may be either
NonDurable or Durable, wich is described in the stanza
"subscription-durability".</p><pre class="programlisting">
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>Durable</subscription-durability>
</message-driven-destination>
</pre></li><li><p><a name="N1713"></a>A bean may be have transaction either as bean
managed or container managed, which is described in the stanza "transaction-type",
eg.</p><pre class="programlisting">
<transaction-type>Container</transaction-type>
</pre></li><li><p><a name="N171e"></a>A bean managed bean may have an acknowledge
type of either AUTO_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE. This is currently not
supported in JBoss since the container always are receiving messages under a
transaction. But it is described in the stanza "acknowledge-mode".</p><pre
class="programlisting">
<transaction-type>Bean</transaction-type>
<acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
</pre></li><li><p><a name="N1729"></a>A container managed bean may either specify
transactions as Required or NotSupported, which is done in the container-transaction
transaction part.</p><pre class="programlisting">
</container-transaction>
<container-transaction>
<method>
<ejb-name>DurableTopicBean</ejb-name>
<method-name>*</method-name>
</method>
<!-- May also be NotSupported -->
<trans-attribute>Required</trans-attribute>
</container-transaction>
</pre></li><li><p><a name="N1734"></a>An MDB may also specify a selector which
follows the JMS syntax for a selector. Which is specified in the stanza
"message-selector".</p><pre class="programlisting">
<message-selector>JMSType='activityCompletion'</message-selector>
</pre></li></ul></div><p>In a message-driven stanza one may also have the normal
stuff that may be in a ejb deployment descriptor, such as "ejb-ref" and
"resource-ref".</p></div><div class="section"><a name="N1744"></a><div
class="titlepage"><div><h3 class="title"><a name="N1744"></a><span class="title">JBoss
configuration</span></h3></div></div><p>The meat of the configuration options are in
the jboss.xml deployment descriptor. This may be divided into two part. The necessary
one that configures a particular bean. And the optional one (that will be taken from
standardjboss.xml if not found and which configures the container. We will describe
both here, but the container configuration will be broken into several parts since it
involves stuff outside the jboss.xml file.</p><p>In the bean part one always have to
specify the JNDI for the JMS destination. In JBossMQ this always begins with either
"topic/" or "queue/" followed by the name of the destination.</p><pre class="prog!
ramlisting">
<destination-jndi-name>queue/testObjectMessage</destination-jndi-name>
</pre><p>You also have to tell the beans name and the name of the container
configuration. To use the one in standardjboss.xml you should give the name "Standard
Message Driven Bean".</p><pre class="programlisting">
<message-driven>
<ejb-name>QueueBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>queue/testQueue</destination-jndi-name>
</message-driven>
</pre><p>It is also possible to use a name and a password to log in to JBossMQ.
These may be used by them self. If you have specified a Durable Topic they are however
required. Then one also have to specify a client-id. All these stuff are configurable
in conf/default/jbossmq.xml. Using one of the default in that file we could have a
deployment descriptor looking like this:</p><pre class="programlisting">
<message-driven>
<ejb-name>DurableTopicBean</ejb-name>
<configuration-name>Standard Message Driven
Bean</configuration-name>
<destination-jndi-name>topic/testDurableTopic</destination-jndi-name>
<mdb-user>john</mdb-user>
<mdb-passwd>needle</mdb-passwd>
<mdb-client-id>DurableSubscriberExample</mdb-client-id>
</message-driven>
</pre><p>The container stuff for MDB are in standardjboss.xml. It is however
possible to override this configuration by including it in the jboss.xml deployment
descriptor. I will first give you the complete look if doing like this, and then go
through the individual entries.</p><pre class="programlisting">
<?xml version="1.0" encoding="Cp1252"?>
<jboss>
<enterprise-beans>
<message-driven>
<ejb-name>ObjectMessageBean</ejb-name>
<configuration-name>My Config</configuration-name>
<destination-jndi-name>queue/testObjectMessage</destination-jndi-name>
</message-driven>
<secure>false</secure>
</enterprise-beans>
<container-configurations>
<container-configuration>
<container-name>My Config</container-name>
<call-logging>false</call-logging>
<container-invoker>org.jboss.ejb.plugins.jms.JMSContainerInvoker</container-invoker>
<container-interceptors>
<interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor>
<interceptor>org.jboss.ejb.plugins.SecurityInterceptor</interceptor>
<!-- CMT -->
<interceptor
transaction="Container">org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
<interceptor transaction="Container"
metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
<interceptor
transaction="Container">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor</interceptor>
<!-- BMT -->
<interceptor
transaction="Bean">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor</interceptor>
<interceptor
transaction="Bean">org.jboss.ejb.plugins.MessageDrivenTxInterceptorBMT</interceptor>
<interceptor transaction="Bean"
metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor</interceptor>
</container-interceptors>
<instance-pool>org.jboss.ejb.plugins.MessageDrivenInstancePool</instance-pool>
<instance-cache></instance-cache>
<persistence-manager></persistence-manager>
<transaction-manager>org.jboss.tm.TxManager</transaction-manager>
<container-invoker-conf>
<JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
<ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
<MaximumSize>15</MaximumSize>
<MaxMessages>1</MaxMessages>
<Optimized>True</Optimized>
</container-invoker-conf>
<container-pool-conf>
<MaximumSize>100</MaximumSize>
<MinimumSize>10</MinimumSize>
</container-pool-conf>
</container-configuration>
</container-configurations>
<resource-managers />
</container-configurations>
</pre><p>Here we go through some ways to configure the MDB container</p><div
class="section"><a name="N176e"></a><div class="titlepage"><div><h4 class="title"><a
name="N176e"></a><span class="title">Container invoker</span></h4></div></div><p>The
container invoker is what sends messages into the container system. It is this that is
responsible for handling everything that has to do with JMS. The rest of the MDB
container parts are basically agnostic to what kind of message system that the
container invoker uses. It is therefore possible to write a new container invoker for
other types of message system. Currently there are one limitation to this. The bean
class still has to implement the MessageListener interface and the invoker therefore
have to adopt to this interface. This will be made pluggable in a later release of
MDB. </p></div><div class="section"><a name="N1776"></a><div
class="titlepage"><div><h4 class="title"><a name="N1776"></a><span
class="title">Container int!
erceptor</span></h4></div></div><p>The container interceptor are an integral part of
the container system and each does something particular to fulfill the EJB container
contract. All of them are pluggable, meaning that it is possible to write new
implementations of the and plug them in for a bean with a particular need. This should
be considered a very advanced task.</p></div><div class="section"><a
name="N177e"></a><div class="titlepage"><div><h4 class="title"><a
name="N177e"></a><span class="title">Container invoker
configuration</span></h4></div></div><p>This is probably the most interesting part to
understand. Lets look at it in smaller pieces. First it defines a
"JMSProviderAdapterJNDI":</p><pre class="programlisting">
<JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
</pre><p>There should be a JNDI name to a JMX bean where one might lookup a provider
adapter class. This class is then used by the invoker to find the names of the
connection factories, all IntitialContext lookups are done through this class, to make
it possible to get access to a JMS provider outside of JBoss.</p><p>The name is by
default bound to the JbossMQProvider in jboss.jcml</p><pre class="programlisting">
<mbean code="org.jboss.jms.jndi.JMSProviderLoader"
name=":service=JMSProviderLoader,name=JBossMQProvider">
<attribute name="ProviderName">DefaultJMSProvider</attribute>
<attribute
name="ProviderAdapterClass">org.jboss.jms.jndi.JBossMQProvider</attribute>
</mbean>
</pre><p>It is however possible to add more JMSProviders to the jboss.jcml and use
them in the container configuration. On possible reason to do this is if one want to
listen to a queue or topic in another JBoss server. The one could define another
provider and configure its context. Say we have a JBoss server on a machine
remote.com. We might then ad this to jboss.jcml:</p><pre class="programlisting">
<mbean code="org.jboss.jms.jndi.JMSProviderLoader"
name=":service=JMSProviderLoader,name=RemoteJMSProvider">
<attribute name="ProviderName">RemoteJMSProvider</attribute>
<attribute
name="ProviderAdapterClass">org.jboss.jms.jndi.JBossMQProvider</attribute>
<attribute name="ProviderUrl">remote.com:1099</attribute>
</mbean>
</pre><p>Note how we added a "ProviderUrl" attribute. In jboss.xml we would write
this in the JMSProviderAdapterJNDI element:</p><pre class="programlisting">
<JMSProviderAdapterJNDI>RemoteJMSProvider</JMSProviderAdapterJNDI>
</pre><p>OBSERVE. I have this working for non transacted connections. It has not
bean fully verified to work with the current JBossMQProvider.</p><p>Another way to use
this configuration option is to integrate another JMS provider into JBoss. This was
actually how MDB was first implemented in JBoss through the OpenJMS implementation. To
do this one have to implement the interface org.jboss.jms.jndi.JMSProviderAdapter. Be
aware though that if the JMS provider does not support the full JMS ASF (chapter 8 in
the JMS spec) you will have to write a full implementation of both the ProvuderAdapter
and the ServerSession stuff.</p><p>Next we have the "ServerSessionPoolFactoryJNDI"
element</p><pre class="programlisting">
<ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
</pre><p>This also points to a class loaded through jboss.jcml. It is the entry
point to the ServerSessionPool. If one needs to write a provider specific pool or do
some customization of the existing one, it would be possible to load that for a
particular bean. The existing one is defined this way in jboss.jcml:</p><pre
class="programlisting">
<mbean code="org.jboss.jms.asf.ServerSessionPoolLoader"
name=":service=ServerSessionPoolMBean,name=StdJMSPool">
<attribute name="PoolName">StdJMSPool</attribute>
<attribute
name="PoolFactoryClass">org.jboss.jms.asf.StdServerSessionPoolFactory</attribute>
</mbean>
</pre><p>The first implementation of MDB for JBoss was based on another
ServerSessionPoolFactory, specially written for OpenJMS. This is currently not
verified to work. What do work is the pluggability of ServerSessionPool
factories.</p><p>The last two entries looks like this:</p><pre class="programlisting">
<MaximumSize>15</MaximumSize>
<MaxMessages>1</MaxMessages>
</pre><p>The first of these - "MaximumSize" - defines how large the pool will be,
i.e how many session it will have ready to serve incoming messages. The second one is
used to configure the maximum number of messages a session is allowed to handle at
once. I have never tweaked that one, and do not know if JBossMQ actually support that
option. It might enhance performance if used.</p></div></div></div></div><div
class="chapter" id="N17cd"><div class="titlepage"><div><h2 class="title"><a
name="N17cd"></a>Chapter 8. Container architecture - design notes</h2></div></div><div
class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="#N17e6">Introduction</a></dt><dd><dl><dt> <a href="#N17eb">JBoss 1.0 (a.k.a
EJBoss/NextGen)</a></dt><dt> <a href="#N17f7">JBoss 2.0</a></dt></dl></dd><dt> <a
href="#N1810">Client Objects</a></dt><dd><dl><dt> <a href="#N1815">EJBObject and
EJBHome</a></dt><dt> <a href="#N182a">Virtual EJBObject - the big picture</a></dt><dt>
<a href="#N1844">Two f!
lavours of implementation</a></dt><dt> <a href="#N1868">Relation to
ContainerInvoker</a></dt><dt> <a href="#N1886">Dynamic proxies</a></dt><dt> <a
href="#N188f">EJBObject as a dynamic proxy</a></dt><dt> <a href="#N18df">Invoke
method</a></dt><dt> <a href="#N18f1">Advantages</a></dt><dt> <a href="#N18fa">Closing
the first half of the circle</a></dt></dl></dd><dt> <a href="#N1919">JMX - foundation
of JBoss infrastructure</a></dt><dd><dl><dt> <a
href="#N191e">Introduction</a></dt><dt> <a href="#N1927">JMX core
components</a></dt><dt> <a href="#N1933">JBoss and JMX</a></dt></dl></dd><dt> <a
href="#N1943">ContainerInvoker - Container entry point</a></dt><dd><dl><dt> <a
href="#N1948">Introduction</a></dt><dt> <a href="#N1957">ContainerInvoker in
focus</a></dt></dl></dd><dt> <a href="#N1a1a">Container</a></dt><dd><dl><dt> <a
href="#N1a1f">Concepts</a></dt><dt> <a href="#N1a2e">Container Factory</a></dt><dt> <a
href="#N1a9a">Automatic deployment</a></dt><dt> <a href="#N1ac4">Enterpr!
iseContext</a></dt><dt> <a href="#N1afa">Container's nuts and
bolts</a></dt></dl></dd><dt> <a href="#N1c33"> Transaction support
</a></dt><dd><dl><dt> <a href="#N1c38">Background</a></dt><dt> <a href="#N1c45">JTS
and JTA</a></dt><dt> <a href="#N1c61">Core implementation</a></dt><dt> <a
href="#N1c74">TxInterceptor</a></dt></dl></dd><dt> <a
href="#N1c82">Security</a></dt><dd><dl><dt> <a href="#N1c87">Authentication - checking
credentials</a></dt><dt> <a href="#N1cad">Authorization - checking access to
resources</a></dt><dt> <a href="#N1cd8">SecurityInterceptor</a></dt></dl></dd><dt> <a
href="#N1cf1">Tracing the call through container</a></dt></dl></div><p>Author:
<span class="author">Vladimir Blagojevic</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
<span class="author">Rickard Oberg</span>
<tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N17e6"></a><div class="titlepage"><div><h2
class="title" style="clear: all"><a name="N17e6"></a><span
class="title">Introduction</span></h2></div></div><div class="section"><a
name="N17eb"></a><div class="titlepage"><div><h3 class="title"><a
name="N17eb"></a><span class="title">JBoss 1.0 (a.k.a
EJBoss/NextGen)</span></h3></div></div><p>JBoss 1.0, a.k.a EJBoss was started in March
1999 and reached 1.0
status in February 2000. The long march towards the promised land of
1.0'ness was not taken lightly. JBoss 1.0 established itself as a
technological leader with many ease of use features pioneered here
before finding their way to the broader audience of commercial
container developers. Mostly thanks to Rickard Oberg, the design
of 1.0 introduced many standard setting features such
as Proxy based deployment and distributed containers.</p><p>Marc Fleury had been
working for almost 6 months on a traditional,
compilation heavy approach to the container design, when Rickard came
along with the logical skeletons and the dynamic proxies as the basis
for a radically new design. Marc started coding feverishly and codenamed
the container "NextGen" truly believing it was a blueprint of things to
come, a "next generation" container.</p></div><div class="section"><a
name="N17f7"></a><div class="titlepage"><div><h3 class="title"><a
name="N17f7"></a><span class="title">JBoss 2.0</span></h3></div></div><p>JBoss 2.0
that we are about to explore is truly a 3rd generation
container. It takes the patterns and ideas that were investigated in
1.0 and then does it right. Designed from the ground up to be modular,
JBoss introduces yet again many ground breaking features, such as
automated re-deploy, but most importantly a plug-in approach to
container implementation. Borrowing from the success that met with
Linux 2.0 and a it's modular approach to Open Source software
implementation, JBoss 2.0 is meant to be developed by distributed
parties each working on a cleanly separated part of the server.</p><p>JBoss 2.0
also standardizes on JMX, the Java Management eXtension
(TM) to offer standard interfaces to the management of its components
as well as the applications deployed on it. Ease of use is still the
number one priority here at JBoss, and JBoss 2.0 will set a new
standard.</p><p>We have to admit that it was hard to decide where to begin and how
to proceed on this journey through JBoss. Although it's architecture is
clean, modular, and a mecca of best programming practices we know of,
the inhereted complexity of a distributed system carries it's weight.</p><p>In
order to understand how JBoss 2.0 works one could go many ways.
The approach we chose could be loosely described as "follow the call".
We'll not dwelve into container architecture directly, but in contrast
will build the foundation first on understanding client object structures,
how they pass the call to container over the network layer. Finally,
before we discuss container architecture in detail, we'll focus on
the container entry point.</p><p> With regard to container architecture, we'll
explore all the
slices from the container entry point to database access structures,
focusing on various patterns, the renowned container plugin-in approach,
and how they relate to key points in EJB in general. </p><p>Now, let's not spoil
all the fun parts.
Put your helmets on, we are going straight to the trenches!!!</p></div></div><div
class="section"><a name="N1810"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1810"></a><span class="title">Client
Objects</span></h2></div></div><div class="section"><a name="N1815"></a><div
class="titlepage"><div><h3 class="title"><a name="N1815"></a><span
class="title">EJBObject and EJBHome</span></h3></div></div><p>As previously discussed
in many EJB resources, an
<tt>EJBObject</tt> is an
object that represents a client's view of the Enterprise Java Bean. It is
generated by the container provider. A client never references an ejb bean
instance directly, but rather references the
<tt>EJBObject</tt> which implements the
bean remote interface. The <tt>EJBHome</tt> object is very
similar to <tt>EJBObject</tt> in
the sense that it is also generated by the container. Also, it implements
the bean's home interface, which is defined by the bean provider. Rather
than implementing business logic, however, it provides life-cycle
operations on the enteprise beans.</p></div><div class="section"><a
name="N182a"></a><div class="titlepage"><div><h3 class="title"><a
name="N182a"></a><span class="title">Virtual EJBObject - the big
picture</span></h3></div></div><p><tt>EJBObject</tt> is more of an abstract idea than
a
physical
implementation. So far, we know that
clients are given a remote
handle to EJBObjects, but how is the
EJBObject physically
implemented on the server side? Well,
it is not implemented at all !</p><p>Most EJB servers that are available today are
literally implementing
the EJB
specification. That is, for each
logical EJBObject there is one physical EJBObject that
receives requests.</p><p>This approach is
very naive and may easily lead to scalability
problems if there are many EJBObjects
alive at any one time.
In addition, this gives a rather
complex structure to the EJB container.</p><p>For example, one can have a finder
method that returns an enumeration
of
1.000.000 EJBObjects. Does this mean
that we now have to create 1.000.000
server EJBObject counterparts? This
would be a serious resource drain ! </p><p>In JBoss there is only one physical
EJBObject that serves all logical
EJBObjects. That physical EJBObject is
Container. For each EJB type there is
one container object, which plays the
role of EJBObject by wrapping all instances
of a particular EJB type.</p><p>JBoss'
approach is superior in many aspects, and it simplifies the
container architecture immensely.
Clients, however, never notice this. They have
something that looks and feels like a
real server EJBObject, but this is merely an
illusion. Behind the scenes there is
only one object (Container) handling all method
invocations. The final result is full
EJBObject conformity.</p></div><div class="section"><a name="N1844"></a><div
class="titlepage"><div><h3 class="title"><a name="N1844"></a><span class="title">Two
flavours of implementation</span></h3></div></div><p>JBoss's client objects
(<tt>EJBObject</tt> and
<tt>EJBHome</tt>) are constructed as
dynamic proxies. But before we investigate dynamic proxies, it is
important to notice that there are two different implementations of
dynamic proxies, that are in fact almost totally the same. The package
jrmp13.interfaces* contains default implementation of
<tt>EJBObject</tt>
proxies that utilizes the core java.lang.reflect package of j2se 1.3.
In contrast, the package jrmp12.interfaces* contains
<tt>EJBObjects</tt> proxies
that are using JBoss's home brewed proxy framework of j2se 1.2.
This package is primarly intended to serve for "history proofing"
of JBoss (i.e., enabling JBoss to be used with j2se 1.2 version).</p><p>*Full
package names are:</p><p>
<tt>org.jboss.ejb.plugins.jrmp13.interfaces</tt>
</p><p>
<tt>org.jboss.ejb.plugins.jrmp12.interfaces</tt>
</p></div><div class="section"><a name="N1868"></a><div
class="titlepage"><div><h3 class="title"><a name="N1868"></a><span
class="title">Relation to ContainerInvoker</span></h3></div></div><p> The
ContainerInvoker component, which we will focus on in detail
later,
is responsible for maintaining <tt>EJBObject</tt> and
<tt>EJBHome</tt>. A closer look
at <tt>ContainerInvoker</tt> reveals an interface for
obtaining these objects.
Dynamic proxies of <tt>EJBObject</tt> and
<tt>EJBHome</tt> are created in
<tt>JRMPContainerInvoker</tt>,
a default implementation of the <tt>ContainerInvoker</tt>
interface.</p></div><div class="section"><a name="N1886"></a><div
class="titlepage"><div><h3 class="title"><a name="N1886"></a><span
class="title">Dynamic proxies</span></h3></div></div><p>A dynamic proxy is an object
that implements a list of interfaces
specified at runtime when the object is created. A proxy interface
is an interface that is implemented by a proxy class. Each proxy
class instance has an associated invocation handler object, which
implements the interface InvocationHandler. </p></div><div class="section"><a
name="N188f"></a><div class="titlepage"><div><h3 class="title"><a
name="N188f"></a><span class="title">EJBObject as a dynamic
proxy</span></h3></div></div><p>EJBObject and EJHome object are created by following
classical
proxy instantiation technique:</p><p>
<pre
class="programlisting">Proxy.newProxyInstance(bean.getRemoteClass().getClassLoader(),
new Class[] { bean.getRemoteClass() },
new EntityProxy());</pre>*</p><p>*Not exactly as is,
simplified to a certain degree</p><div class="section"><a name="N18a2"></a><div
class="titlepage"><div><h4 class="title"><a name="N18a2"></a><span class="title">What
do we need to create a client proxy ?</span></h4></div></div><p>In this particular
case, given the classloader that loaded
the entity bean's remote interface, its Class class, and the invocation
handler (<tt>EntityProxy</tt>), we are able to create a new
Proxy instance
which implements the bean's remote interface. Since
<tt>java.lang.reflect.Proxy</tt>
class is serializible, it can be sent to the remote client across
the network.</p></div><div class="section"><a name="N18b1"></a><div
class="titlepage"><div><h4 class="title"><a name="N18b1"></a><span
class="title">Relation between proxy and invocation
handler</span></h4></div></div><p>The remote client, having a dynamic proxy class that
implements
the bean's remote interface, dispatches all method invocation on that
interface to the instance of the underlying invocation handler.</p></div><div
class="section"><a name="N18ba"></a><div class="titlepage"><div><h4 class="title"><a
name="N18ba"></a><span class="title">EJB proxy
types</span></h4></div></div><p>Depending on the type of the EJB bean on the server,
there are four
proxy classes: <tt>EntityProxy</tt>,
<tt>HomeProxy</tt>,<tt>StatelessSessionProxy</tt>
and <tt>StatefulSessionProxy</tt>.</p></div><p>All four proxies implement the
<tt>java.lang.reflect.InvocationHandler</tt>
interface and also subclass <tt>GenericProxy</tt>, which in
turn contains a
stub of the <tt>ContainerRemote</tt> interface implementor
from the server side.
That implementor is <tt>JRMPContainerInvoker</tt>.</p></div><div
class="section"><a name="N18df"></a><div class="titlepage"><div><h3 class="title"><a
name="N18df"></a><span class="title">Invoke method</span></h3></div></div><p>Each of
the proxy classes implements the only method defined
in the <tt>InvocationHandler</tt> interface: invoke.
The invoke method intercepts all calls to the EJB remote
interface (client side) and depending on the particular type of EJB
method, does one of the following:</p></div><p>- handles the method locally in
the <tt>Proxy</tt> class
- passes the method call accross the wire to the remote EJB container
- invokes the method in the local EJB container</p><div class="section"><a
name="N18f1"></a><div class="titlepage"><div><h3 class="title"><a
name="N18f1"></a><span class="title">Advantages</span></h3></div></div><p>This design
of client objects gives maximum flexibility in the
following sense: all calls that can be handled by clients themselves
are handled locally, preventing the roundtrip across the wire and
saving the container from unneccessary loading. Calls coming from other
EJBs, but local to the JVM, are also optimized since they bypass the network
transport layer and call the specific underlying container directly.
Finally, only calls that absolutely must leave the local VM are passed
across the wire.</p></div><div class="section"><a name="N18fa"></a><div
class="titlepage"><div><h3 class="title"><a name="N18fa"></a><span
class="title">Closing the first half of the circle</span></h3></div></div><p>Let's
trace the remote call on busines method B of an entity
bean.</p><p>First, the method call goes on the proxy interface where it is
dispatched to its invocation handler, which in this case is EntityProxy.
Entity proxy converts the call into a
<tt>RemoteMethodInvocation</tt>object and stuffs it
into a <tt>MarshalledObject</tt>. Using a stub of the
<tt>JRMPContainerInvoker</tt>, the remote
call is sent over the "wire" to the server's
<tt>JRMPContainerInvoker</tt> object
where it is unpacked from <tt>MarshalledObject</tt> and handed
off to the container.</p><p>*Note that, since the jdk1.2 release, skeletons are
avoided on the
server side. Consult RMI specification for more info.</p></div></div><div
class="section"><a name="N1919"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1919"></a><span class="title">JMX - foundation of JBoss
infrastructure</span></h2></div></div><div class="section"><a name="N191e"></a><div
class="titlepage"><div><h3 class="title"><a name="N191e"></a><span
class="title">Introduction</span></h3></div></div><p>JMX technology represents a
standard coherent framework for
instrumentation and management of Java
technology-based resources. JMX defines a management architecture, APIs, and
management services all
under a single umbrella specification. On top of this specification promises
hooks into existing management
systems.</p></div><div class="section"><a name="N1927"></a><div
class="titlepage"><div><h3 class="title"><a name="N1927"></a><span class="title">JMX
core components</span></h3></div></div><p>MBeanServer is core JMX abstraction, a
component which provides
services for manipulating MBeans. All
management operations performed on MBeans are done through MBeanServer
interface. MBeanServer
contains the necessary methods for the creation, registration, and deletion of
MBeans as well as the access
methods for registered MBeans. This is the core component of the JMX
infrastructure.</p><p>MBean is a "regular" Java component volunteering to be
instrumented.
Every MBean component which is
added to the MBeanServer becomes manageable: its attributes and operations
become remotely accessible
through the connectors/adaptors connected to that MBeanServer. A Java object
cannot be registered in
the MBeanServer unless it is a JMX compliant MBean.</p></div><div class="section"><a
name="N1933"></a><div class="titlepage"><div><h3 class="title"><a
name="N1933"></a><span class="title">JBoss and
JMX</span></h3></div></div><p>MBeanServer in Jboss architecture plays a role of
microkernel
aggregator component. All other managable
MBeans components are plugged into MBeanServer. The kernel in that sense is
only an aggregator, and not
a source of actual functionality. The functionality is provided by MBeans and
infact all major JBoss
components, are managable MBeans interconnected through MBeanServer. The
managibility is provied by
MBeanServer which instuments registered MBeans.</p><p>The modular architecture of
JBoss , provided by JMX foundation
moves all dependency checking from
compile time to run-time enviroment. The rigourous runtime depedencies
check mechanism, in the form
of JBoss' DependencyManager component, enforces dependencies between different
resources and services.</p><p>It is important to notice that "management
dependencies" are
something independent of the managed
blocks but dependent on the context of a particular deployment/environment. In
any case, the dependencies
are runtime oriented and the external management of them (JMX) is the way
to go.</p></div></div><div class="section"><a name="N1943"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N1943"></a><span
class="title">ContainerInvoker - Container entry point</span></h2></div></div><div
class="section"><a name="N1948"></a><div class="titlepage"><div><h3 class="title"><a
name="N1948"></a><span class="title">Introduction</span></h3></div></div><p>Certainly
one of the most important parts of a distributed system
is its RPC interface, as well as techniques used in passing that RPC
call between different parts of the system.</p><p>The component that plays the
role of the container entry point, a
"call
router", to insides of the container is the
<tt>ContainerInvoker</tt>. By closely
looking at this entry point to the JBoss container, one would understand
the semantics of calls made from clients, client object structure, the
passing
of client calls over the network layer (a.k.a "wire") and unpacking
them in a local VM. Similar semantics are employed in returning the result
of the call and how it is handled on the client side. Also, great attention
has to be dedicated to methods employed in bypassing the network layer if
these
calls are made from clients local to the container, i.e intra-VM.</p></div><div
class="section"><a name="N1957"></a><div class="titlepage"><div><h3 class="title"><a
name="N1957"></a><span class="title">ContainerInvoker in
focus</span></h3></div></div><div class="section"><a name="N195c"></a><div
class="titlepage"><div><h4 class="title"><a name="N195c"></a><span class="title">How
are calls passed into a container?</span></h4></div></div><p>Container invoker
utilizes RMI exporting* to make itself
available to remote clients. By implementing
<tt>ContainerRemote</tt> interface,
which in turn extends the familiar <tt>java.rmi.Remote</tt>
interface,
ContainerInvoker acts as an RMI server object and as such is able to
accept calls that come from both remote clients (other JVMs) and
from other beans "living" in containers of the same EJB
application (within the same JVM).</p></div><div class="section"><a
name="N196b"></a><div class="titlepage"><div><h4 class="title"><a
name="N196b"></a><span class="title">ContainerRemote interface - two flavours of
invoke methods</span></h4></div></div><p>Before going further into the details, let's
look closer into
<tt>ContainerRemote</tt> interface. It has two methods,
<tt>invoke</tt> and <tt>invokeHome</tt>, each of
which
has two flavors:</p><p>
<pre class="programlisting">public
MarshalledObject invoke(MarshalledObject mi)
throws Exception;</pre>
</p><p>
<pre class="programlisting">public Object
invoke(Object id, Method m, Object[] args,
Transaction tx,
Principal identity,
Object credential )
throws Exception;</pre>
</p><p>The first accepts only one parameter
(<tt>MarshalledObject</tt>), while
second accepts "regular" java objects. Why is this distinction
between the two sets important? </p><p>The distinction exists exactly for the
reason that it enables the
container to accept both remote and local client calls. But it is
important
to notice that not only does this design approach enable two different
call methodologies, it optimizes them at the same time.</p></div><div
class="section"><a name="N199a"></a><div class="titlepage"><div><h4 class="title"><a
name="N199a"></a><span class="title">Remote call unpacking
stage</span></h4></div></div><p>Remote calls are unpacked from
<tt>MarshalledObject</tt>.
<tt>MarshalledObject</tt>
contains a byte stream with serialized representation
of an object given to its constructor. In our case, this object is
<tt>RemoteMethodInvocation</tt>.
The <tt>RemoteMethodInvocation</tt> instance,
created by a remote client proxy, describes all needed attributes
of an EJB method call. Some of these attributes, as you
may have guessed by now, are the ID of the object, a method to
invoke, security credentials, principal of the caller(identity),
and a transactional context of the call.</p></div><div class="section"><a
name="N19af"></a><div class="titlepage"><div><h4 class="title"><a
name="N19af"></a><span class="title">MethodInvocation</span></h4></div></div><p>Upon
receving <tt>MarshalledOjbect</tt> from client
proxy, <tt>ContainerInvoker</tt>
recreates a copy of the original
<tt>RemoteMethodInvocation</tt>
object, by deserializing it from the contained byte stream in
<tt>MarshalledObject</tt>.
<tt>RemoteMethoInvocation</tt> is then converted to
<tt>MethodInvocation</tt> and handed off to the
container.</p></div><div class="section"><a name="N19ca"></a><div
class="titlepage"><div><h4 class="title"><a name="N19ca"></a><span class="title">Bean
to Bean calls</span></h4></div></div><p>Local calls coming from clients in the same
VM, usually a
"bean/bean" method call, are directly handed off to the container.
This bypasses the network layer, and serialization/deserialization
stage of the call that remote method calls have to go through.</p></div><div
class="section"><a name="N19d3"></a><div class="titlepage"><div><h4 class="title"><a
name="N19d3"></a><span class="title">Other ContainerInvoker
duties</span></h4></div></div><p>Before forwarding a call to the container,
<tt>ContainerInvoker</tt> also
resets the call's thread classloader with the specified container
classloader, propagates transaction, and security context. </p><p>Another
important role played by
<tt>ContainerInvoker</tt> is that it
provides implementation of <tt>EJBObject</tt> and
<tt>EJBHome</tt> parts of container.
As mentioned before, <tt>ContainerInvoker</tt> creates
<tt>EJBObject</tt> and <tt>EJBHome</tt>
in the form of dynamic proxies.</p><p>For example, an <tt>EntityBean</tt> finder
may result
in a set of primary
keys whose EJB-objects should be returned to the client. The
<tt>ContainerInvoker</tt> is then responsible for creating
<tt>EJBObject</tt>
instances that can be used by the client, as specified in the
EJB 1.1 specification. The client must then be able to remotely
access the container and actual bean instances through
these <tt>EJBObjects</tt>.</p></div><div class="section"><a name="N1a03"></a><div
class="titlepage"><div><h4 class="title"><a name="N1a03"></a><span class="title">Why
ContainerInvoker if we have container?</span></h4></div></div><p>One may wonder why
there is such a big distinction between
container invoker and the container.
<tt>ContainerInvoker</tt> also
uses the naming tree. Why should the container invoker know
anything about the naming tree? You end up having the container
invoker taking care of all the important registrations...</p><p>Wasn't the
container responsible for all this crucial work?</p><p>No, this architectural approach
was intentional in JBoss. Since
different distribution protocols use different naming systems
(IIOP would use the CORBA naming system), the only part of the
container that knows what naming system to use is the container invoker.
Now, if we want to add another/different distribution protocol to JBoss, we
can
simply implement it in the container invoker; everything else stays
untouched.
ContainerInvoker is free to choose which distribution protocol to use
to access the container. Valid options would be JRMP, IIOP, or SOAP. The
default
plugin uses the standard RMI protocol JRMP to allow client access to
the container. </p><p>*Exporting - making object available to accept incoming
calls by
listening on specified TCP port</p></div></div></div><div class="section"><a
name="N1a1a"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1a1a"></a><span class="title">Container</span></h2></div></div><div
class="section"><a name="N1a1f"></a><div class="titlepage"><div><h3 class="title"><a
name="N1a1f"></a><span class="title">Concepts</span></h3></div></div><p>A
<tt>Container</tt> is the component that runs a
particular EJB. When an
EJB-jar is deployed, typically a number of containers are created
which are connected internally into Applications. The
Application lets Containers handle references between beans, for
example for JNDI EJB-references as specified in the EJB 1.1
specification.</p><p>But let's not dive into the nuts and bolts of the container
component without first looking into the container's creation process.
The component responsible for creating the container is the container
factory.</p></div><div class="section"><a name="N1a2e"></a><div
class="titlepage"><div><h3 class="title"><a name="N1a2e"></a><span
class="title">Container Factory</span></h3></div></div><p>The container factory, as
its name implies, simply creates containers.
Simple, right? Wrong !!! Lets investigate this process in more
detail.</p><div class="section"><a name="N1a36"></a><div class="titlepage"><div><h4
class="title"><a name="N1a36"></a><span
class="title">Introduction</span></h4></div></div><p>Given an EJB-jar that is ready
for deployment, the container factory
will create and initialize the necessary EJB-containers - one for each
deployed EJB. The factory contains two central methods:
<tt>deploy</tt> and
<tt>undeploy</tt>. The <tt>deploy</tt> method takes
a URL, which either points to an
EJB-jar, or to a directory whose structure is the same as a valid
EJB-jar(convenient for development purposes). Once a deployment has
been made, it can be undeployed by calling <tt>undeploy</tt> on
the same URL.
A call to <tt>deploy</tt> with an already deployed URL will
cause an <tt>undeploy</tt>
followed by deployment of the URL, i.e. a re-deploy. JBoss has support
for full re-deployment of both implementation and interface classes,
and will reload any changed classes. This will allow you to develop
and update EJBs without ever stopping a running server.</p></div><div
class="section"><a name="N1a5d"></a><div class="titlepage"><div><h4 class="title"><a
name="N1a5d"></a><span class="title">What the container factory needs to
know</span></h4></div></div><p>In order to properly deploy the bean into a container,
the container
factory
has to have "intimate" knowledge about the bean being deployed to the
finest level of granularity. This is where the notion of bean metadata
comes into the picture. The metadata package, which in turn utilizes a
standard DOM document model, creates an "object-tree" in-memory replica of
ejb-jar.xml file. Having an object tree structure of bean metadata,
the container factory can easily access it and then succesfully deploy
a bean into a container. Bean metadata is actually a super set of
other finer-grained metadata components like method, ejb-ref, environment
entries, resource entries metadata.</p></div><div class="section"><a
name="N1a66"></a><div class="titlepage"><div><h4 class="title"><a
name="N1a66"></a><span class="title">Container
configuration</span></h4></div></div><p>Besides standard EJB 1.1 ejb-jar.xml file that
contains metadata
about beans being deployed, JBoss defines its own container
configuration file - standardjboss.xml. Standardjboss.xml specifies
default container configurations for each EJB bean type. Each configuration
specifies which components to use, such as container invoker type, instance
caches/pools and their sizes, persistence manager etc.</p></div><div
class="section"><a name="N1a6f"></a><div class="titlepage"><div><h4 class="title"><a
name="N1a6f"></a><span class="title">Configuration
flexibility</span></h4></div></div><p>A quick look at standardjboss.xml gives us a
hint about all default
container configurations. EJB adminstrator/developer is also given an
opportunity to override these default container settings in jboss.xml
file. The advantage of this approach is that it gives great flexibility
in the configuration of containers. As we have seen, all container
configuration attributes have been externalized and as such are easily
modifiable. Knowledgeable developers can even implement specialized
container components such as instance pools or caches and easily integrate
them with the container.</p></div><div class="section"><a name="N1a78"></a><div
class="titlepage"><div><h4 class="title"><a name="N1a78"></a><span class="title">Bean
Verifier</span></h4></div></div><p>As an option, Jboss also attempts to verify EJB 1.1
specification
compliance of
the beans. For more details, the curious reader should look into the
verifier
package.</p></div><div class="section"><a name="N1a81"></a><div
class="titlepage"><div><h4 class="title"><a name="N1a81"></a><span
class="title">Deployment semantics</span></h4></div></div><p>Having a bean and
container metadata, the container factory iterates
over
all beans it has to deploy and:</p><p>- creates specific container subclass
- sets all container attributes from container metadata*
- adds all container interceptors*
- adds container to application
- after all beans have been succesfully deployed, starts application</p><p>*Note
the difference between container interceptors in specific
container
subclasses</p><p>*The metadata specifies the type of TM (transaction manager)
to use but, in fact, we need look it up from the naming tree. In fact,
there is (and should be) only
one TM per VM since transactions have to be coordinated across containers.
Also note that <tt>EJBSecurityManager</tt> and
<tt>RealmMapping</tt> are shared between
containers (for more details refer to the security section of this
paper).</p></div></div><div class="section"><a name="N1a9a"></a><div
class="titlepage"><div><h3 class="title"><a name="N1a9a"></a><span
class="title">Automatic deployment</span></h3></div></div><div class="section"><a
name="N1a9f"></a><div class="titlepage"><div><h4 class="title"><a
name="N1a9f"></a><span class="title">Introduction</span></h4></div></div><p>The
container factory can be invoked manually from a management
console or automatically by using the <tt>AutoDeployer</tt>.
AutoDeployer
(which is an MBean) is a component that periodically checks EJB-jars
for modification timestamps. If an update has been made the EJB-jar
is re-deployed. When the server is started and an EJB-jar is found
it will be deployed automatically.</p></div><p>The deployer is given a URL to
watch. The URL can point to one of
three things:</p><p>- EJB-jar</p><p>- directory whose contents are structured like
an EJB-jar. Timestamp
checks will be done on the META-INF/ejb-jar.xml file.</p><p>- directory
into which EJB-jar files or directories containing
valid EJB-jar contents is placed. This may only be a file URL,
since it is not possible to do file listing checks on HTTP
URL's.</p><div class="section"><a name="N1ab7"></a><div class="titlepage"><div><h4
class="title"><a name="N1ab7"></a><span class="title">Advantage of automatic
deployment</span></h4></div></div><p>The last variant is very powerful. The default
configuration of
JBoss starts an <tt>AutoDeployer</tt> that checks the /deploy
directory. Here
you can place any EJB-jars that you want to be deployed on startup.
If you want to add deployments at runtime you simply drop them in
that directory.</p></div></div><div class="section"><a name="N1ac4"></a><div
class="titlepage"><div><h3 class="title"><a name="N1ac4"></a><span
class="title">EnterpriseContext</span></h3></div></div><p>
<tt>EnterpriseContext</tt> and its subclasses,
<tt>StatefulSessionEnterpriseContext</tt>,
<tt>StatelessSessionEntepriseContext</tt>,
and <tt>EntityEntepriseContext</tt> implement
<tt>EJBContext</tt> part of EJB 1.1 spec.</p><div class="section"><a
name="N1adb"></a><div class="titlepage"><div><h4 class="title"><a
name="N1adb"></a><span class="title">Client view</span></h4></div></div><p>From a
bean's perspective <tt>EJBContext</tt> is a
gateway to container;
it represents a way for a bean to perform callbacks to the
container.</p></div><div class="section"><a name="N1ae7"></a><div
class="titlepage"><div><h4 class="title"><a name="N1ae7"></a><span
class="title">Container view</span></h4></div></div><p>From a container's perspective,
the container uses
<tt>EntepriseContext</tt> to
associate a bean instance with all information that the container
needs about
that instance to properly manage it. This infomation includes
a callback reference to the container hosting the instance,
synchronization associated with
that instance, instance's transaction,
<tt>Principal</tt> and object Id.
Simply put, <tt>EntepriseContext</tt> associates a
bean's instance with its metadata.
It is the container's responsibilty to manage bean's context, which
changes over the lifecycle of a bean.</p></div></div><div class="section"><a
name="N1afa"></a><div class="titlepage"><div><h3 class="title"><a
name="N1afa"></a><span class="title">Container's nuts and
bolts</span></h3></div></div><div class="section"><a name="N1aff"></a><div
class="titlepage"><div><h4 class="title"><a name="N1aff"></a><span
class="title">Container class itself</span></h4></div></div><p>JBoss container is
mainly a framework into which one can plug in
implementations of various parts. The
<tt>Container</tt> itself does not perform
any significant work other than connecting the various plugins.
There are three subclasses of <tt>Container</tt>, each
one implementing a
particular bean-type:</p><p>
<tt>EntityContainer</tt> handles EntityBeans,
<tt>StatelessSessionContainer</tt> handles Stateless
SessionBeans, and
<tt>StatefulSessionContainer</tt> handles Stateful
SessionBeans.</p><p>They are very similar, but are different in some respects. The
stateless session container does not have an instance cache (since
no instances have identity), and the entity container has an
<tt>EntityPersistenceManager</tt> to help it with
persisting entity beans in
various storages.</p></div><div class="section"><a name="N1b20"></a><div
class="titlepage"><div><h4 class="title"><a name="N1b20"></a><span
class="title">Container plugin framework</span></h4></div></div><p>The plugins can be
added by implementing various interfaces, and
by selecting them in the JBoss-specific deployment XML file (which
can be edited in a GUI-tool). The interfaces are:</p><p>
<tt>InstanceCache</tt>,
<tt>InstancePool</tt>,
<tt>Interceptor</tt>,
<tt>EntityPersistenceManager</tt>,
<tt>StatefulSessionPersistenceManager</tt>
</p><p>
<tt>InstancePool</tt> and
<tt>Interceptors</tt> are used in all three different types of
containers. <tt>InstanceCache</tt> is only used for
entity beans and stateful
session beans. <tt>EntityPersistenceManager</tt> is
only used for entity beans.
<tt>StatefulSessionPersistenceManager</tt> is only used
for stateful session
beans.</p><p>These interfaces are described in detail below. All plugins
have
a callback to the container through which they can access all other
plugins or configuration information. The container's main
responsibility
is therefore to manage the plugins, and to see to it that the plugins
have all
the information they need in order to implement some
functionality.</p><div class="section"><a name="N1b4f"></a><div
class="titlepage"><div><h5 class="title"><a name="N1b4f"></a><span
class="title">Interceptor</span></h5></div></div><div class="section"><a
name="N1b54"></a><div class="titlepage"><div><h6 class="title"><a
name="N1b54"></a><span class="title">Creation and
ordering</span></h6></div></div><p>All interceptors are created and added to the
interceptor
linked-list by
the container factory. The last interceptor is not added by the
container
factory but rather by the container itself.</p></div><p>The order of the
interceptor in the chain is not accidental. The
idea
behind ordering is that intereceptors that are not tied to a particular
EnterpriseContext instance are positioned before interceptors that
interact with caches and pools.</p></div><div class="section"><a
name="N1b61"></a><div class="titlepage"><div><h5 class="title"><a
name="N1b61"></a><span class="title">Structure, complexity,
cardinality</span></h5></div></div><p>Implementors of the <tt>Interceptor</tt>
interface
form
a linked-list like
structure through which the <tt>MethodInvocation</tt>
object
is passed. The first
interceptor in the chain is invoked when
<tt>ContainerInvoker</tt> hands off
<tt>MethodInvocation</tt> to the container. The last
interceptor invokes the business
method on the bean. There are usually between 3 and 6 interceptors in
a chain depending on the bean type and container configuration.
Interceptor
semantic complexity ranges from simple to complex ones, but under the
cover they all present the same simple interface. An example of a
simple interceptor would be <tt>LoggingInterceptor</tt>,
while a complex example is
<tt>EntitySynchronizationInterceptor</tt>.</p></div><div class="section"><a
name="N1b7c"></a><div class="titlepage"><div><h5 class="title"><a
name="N1b7c"></a><span class="title">Advantages</span></h5></div></div><p>One of the
main advantages of <tt>Interceptor</tt>
pattern is flexibility
in the arrangement of interceptors, as well as a clear semantic
distinction
between different interceptors. For example, logic for transaction and
security is in <tt>TXInterceptor</tt> and
<tt>SecurityInterceptor</tt> correspondingly.</p><p>If any of the interceptors fail,
we don't have to continue the call
further
through, which is very useful if the interceptor that failed is before
complex
structures like caches.</p></div></div><div class="section"><a
name="N1b92"></a><div class="titlepage"><div><h4 class="title"><a
name="N1b92"></a><span class="title">Instance Pool</span></h4></div></div><div
class="section"><a name="N1b97"></a><div class="titlepage"><div><h5 class="title"><a
name="N1b97"></a><span class="title">Recycling pool for bean
instances</span></h5></div></div><p>
<tt>InstancePool</tt> is used to
manage the EJB-bean
instances that are
not associated with any identity. In fact, to be exact,
<tt>EnterpriseContext</tt> objects that wrap
non-associated bean instances
are pooled in this data structure.</p></div><div class="section"><a
name="N1ba6"></a><div class="titlepage"><div><h5 class="title"><a
name="N1ba6"></a><span class="title">Pool types and
cardinality</span></h5></div></div><p>Depending on the underlying bean type hosted in
a container, there
are three different instance pool types. However, it is important
to notice that each container has only one pool of either
type.</p></div><div class="section"><a name="N1baf"></a><div
class="titlepage"><div><h5 class="title"><a name="N1baf"></a><span class="title">Size
and roles</span></h5></div></div><p>Depending on the configuration, a container may
choose to have a
certain
size of the pool containing recycled instances, or it may choose to
instantiate and initialize an instance on demand.</p><p>The pool is used by
the <tt>InstanceCache</tt> to
acquire free instances
for activation, and it is used by Interceptors to acquire instances
to be
used for Home interface methods (create and finder
calls).</p></div></div><div class="section"><a name="N1bbf"></a><div
class="titlepage"><div><h4 class="title"><a name="N1bbf"></a><span
class="title">Instance Cache</span></h4></div></div><div class="section"><a
name="N1bc4"></a><div class="titlepage"><div><h5 class="title"><a
name="N1bc4"></a><span class="title">Container's cache
structure</span></h5></div></div><p>
<tt>InstanceCache</tt> handles all
EJB-instances that are
in a active
state, i.e. bean instances that have an identity attached to
them.</p></div><div class="section"><a name="N1bd0"></a><div
class="titlepage"><div><h5 class="title"><a name="N1bd0"></a><span
class="title">Entity and stateful session bean cache</span></h5></div></div><p>Only
entity and stateful session beans are cached. The cache key
of an entity bean is the primary key. It is the session id for
stateful
session beans.</p></div><div class="section"><a name="N1bd9"></a><div
class="titlepage"><div><h5 class="title"><a name="N1bd9"></a><span
class="title">Roles</span></h5></div></div><p>
<tt>InstanceCache</tt> handles the
list of active
instances, and is also
responsible for activating and passivating these instances. If
an instance with a given identity is requested, and it is not
currently active, the <tt>InstanceCache</tt> must use
the <tt>InstancePool</tt>
to acquire a free instance, and the persistence manager to
activate the instance. Similarly, if it decides to passivate
a certain active instance, it must call the persistence manager
to passivate it and release the instance to the
<tt>InstancePool</tt>.</p></div></div><div class="section"><a name="N1bef"></a><div
class="titlepage"><div><h4 class="title"><a name="N1bef"></a><span
class="title">EntityPersistenceManager</span></h4></div></div><p>The
<tt>EntityPersistenceManager</tt> is responsible
for the persistence
of EntityBeans. This includes:</p><p>- Creating EntityBeans in a storage
- Loading the state of a given primary key into an EJB-instance
- Storing the state of a given EJB-instance
- Removing the state from storage
- Activating an EJB-instance
- Passivating an EJB-instance</p><p>As per EJB 1.1 specification, JBoss
supports two entity bean
persistance semantics: CMP (Container Managed Persistence) and
BMP (Bean Managed Persistence).</p><p>The CMP plugin,
<tt>CMPPersistanceManager</tt> uses
the default implementor of
<tt>EntityPersistanceManager</tt>,
<tt>JAWSPersistanceManager</tt> (JAWS-Just Another Web Store).
JAWS performs performs basic O/R functionality against a
JDBC-store.</p><p>The BMP implementor of the
<tt>EntityPersistenceManager</tt>
interface is
<tt>BMPPersistanceManager</tt>. BMP persistance manager
is fairly simple
since all persistence logic is in the entity bean itself. The only
duty of the
persistence manager is to perform container callbacks.</p></div><div
class="section"><a name="N1c16"></a><div class="titlepage"><div><h4 class="title"><a
name="N1c16"></a><span
class="title">StatefulSessionPersistenceManager</span></h4></div></div><p>The
<tt>StatefulSessionPersistenceManager</tt> is
responsible for
the persistence of Stateful SessionBeans. This includes:</p><p>- Creating
stateful sessions in a storage
- Activating stateful sessions from a storage
- Passivating stateful sessions to a storage
- Removing stateful sessions from a storage</p><p>The default implementation
of the
<tt>StatefulSessionPersistenceManager</tt>
is <tt>StatefulSessionFilePersistenceManager</tt>. As
its name implies,
<tt>StatefulSessionFilePersistenceManager</tt> utilizes
the underlying file system
to persist stateful SessionBeans. More specifically, persistence
manager
serializes beans in flat file under bean name + bean Id .ser files.
Having a .ser file per bean instance, the Persistance Manager is able
to
restore a
bean's state for activation and respectively store its state during
passivation.</p></div></div></div><div class="section"><a
name="N1c33"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1c33"></a><span class="title"> Transaction support </span></h2></div></div><div
class="section"><a name="N1c38"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c38"></a><span class="title">Background</span></h3></div></div><p>In the world
of distributed transaction processing (DTP) a series of
specifications developed by OpenGroup
(www.opengroup.org) represent the most widely adopted DTP model.
</p><p>Opengroup specifications define major components participating in the
DTP
model as well as a set of APIs
that define communication between these components. Components
participating in the DTP model are:
application programs, resource managers, and a transaction manager. The
interface
defined between application
programs wishing to participate in global trasactions and the transaction
manager is called the TX
interface, while the interface between transaction managers and the resource
managers is called the XA interface.</p><p>Sun Microsystems Inc followed this DTP
model and as part of J2EE
introduced the Java Transaction Service (JTS)
and the Java Transaction API (JTA) specifications.</p></div><div class="section"><a
name="N1c45"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c45"></a><span class="title">JTS and JTA</span></h3></div></div><p>The
difference between JTS and JTA is often a source of confusion.
Simply
put JTS defines above mentioned components
participating in the DTP model, while JTA captures interfaces between
them.</p><p>JTS defines five major players in the DTP model of Java Enterprise
middleware:</p><p>Transaction Manager as a core component which provides services of
transaction resource management ( i.e resource
enlistment, delistment), transaction demarcation, synchronization notification
callbacks, trasaction context
propagation and two-phase commit initiation and recovery coordination with
resource managers.</p><p>The application server provides infrastructure required to
support the
application run-time environment.</p><p>A resource manager is a component that
manages access to a persistent
stable storage system. Each resource manager cooperates with a
Transaction Manager in two-phase commit intiation and failure recovery. An
example of resource manager would be
database driver.</p><p>EJB's can either use declarative transaction management
specified in
the ejb-jar.jar xml descriptor, or programmatic transaction manager
using the <tt>UserTransaction</tt> interface. Either way, the
transaction services are provided by the application server.</p><p>A communication
resource manager supports transactional context
propagation. Simply put this component allows
the transaction manager to participate in transactions initiated by other
transaction managers. JTS does not
specify a protocol for this component.</p></div><div class="section"><a
name="N1c61"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c61"></a><span class="title">Core
implementation</span></h3></div></div><p>Jboss includes it's support of JTS and JTA
specifications in the
jboss.tm package. This package include implementation of
TransactionManager , Transaction, Xid and Synchronization from JTA
specification. </p><p>However, the key class is TxCapsule. TxCapsule is has a very
abstract notion but it closely matches the idea of
transaction context. Transaction context in turn is best thought of as a
state of all transactional operations on the
participating resources that make up one global transaction . Therefore
transactional context, or in Jboss's case
TxCapsule, captures all participating XaResources and their states, all
particiating threads as well as a global Xid
identifying global transaction.</p><p>TxCapsule provides the real meat. It enables
enlisting and delisting
of transactional resources, importing of
transactions into capsule, provides creational point and access to Xid of the
current global transaction, calls
Synchronization callback but most importantly it initiates the two-phase commit
protocol as well as rollback mechanisms
defined by the two-phase commit protocol.</p><p>TransactionImpl implements
Transaction interface from JTA. Each
transaction is a part of TxCapsule which in turn can
"host" transactions representing the TxCapsule. All of TransactionImpl methods
are basically indirection calls to the hosting
TxCapsule. </p><p>TxManager implements TransactionManager interface defined in JTA.
As
you might have guessed by now, it controls the lifecycle of all
TxCapsules. Since TxCapsule is a relatively heavyweight object, capsules
are recycled in a soft reference queue.</p></div><div class="section"><a
name="N1c74"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c74"></a><span class="title">TxInterceptor</span></h3></div></div><p>Following
the previously introduced interceptor framework JBoss
introduces two transactional interceptors TXIntereceptorBMT
and TXIntereceptorCMT. Both interceptors closely interact with TxManager in
order to achieve proper transactional semantics.</p><p>TXIntereceptorBMT provides an
instance of UserTransaction to the right
transactional context. TxInterceptorBMT is used
in the case of user demarcated, i.e explicit transactional management. For
more information on details of semantics
refer to p174 of EJB1.1 spec.</p><p>TxInterceptorCMT moves all transactional
management work to the
container. Depending on the transaction attributes specified in th
ejb-jar.xml file
(i.e TX_REQUIRED, TX_SUPPORTS, TX_REQUIRES_NEW etc) the container decides how
to manage
the transactional context of the invoked call.</p></div></div><div
class="section"><a name="N1c82"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1c82"></a><span
class="title">Security</span></h2></div></div><div class="section"><a
name="N1c87"></a><div class="titlepage"><div><h3 class="title"><a
name="N1c87"></a><span class="title">Authentication - checking
credentials</span></h3></div></div><p>
<tt>Credential</tt> is an object that the client
supplies to
authenticate himself to the
system. <tt>Credential</tt> might be a password, a digital
signature, or another identifier.
It might also be a wrapper of that credential to indicate that the jboss
server trusts the invoker about the principal and no authentication is
necessary (e.g. for in-VM invocations, or invocations from a web
container).</p><p>The authentication interface is:</p><p>
<pre class="programlisting">public interface
org.jboss.system.SecurityManager
{
public boolean isValid( Principal principal,
Object credential );
}</pre>
</p><p>Judgments about validity are based on the
<tt>Principal</tt> class type,
<tt>Principal</tt> name, and credential. Typically, one
implementation
exists per security realm.</p><p>The security manager implementation is
registered in the JNDI
namespace as "SecurityManager." and is shared between containers.
This system level implementation would only delegate to the realm-level
implementations to see if the Principal/credential pair were
valid.</p></div><div class="section"><a name="N1cad"></a><div
class="titlepage"><div><h3 class="title"><a name="N1cad"></a><span
class="title">Authorization - checking access to
resources</span></h3></div></div><p>Authorization interface is defined as
follows:</p><p>
<pre class="programlisting">public interface RealmMapping
{
public boolean doesUserHaveRole( Principal principal,
Set roleNames );
}</pre>
</p><p>A <tt>RealmMapping</tt> describes a relation between a
list of principals,
and a set of roles assigned to each principal. Unlike
SecurityManagers, RealmMappings are specific to a particular
J2EE application. So the relationship is the following:
J2EE app has many realms, a realm has many principals,
and a principal has many roles.</p><p>The <tt>RealmMapping</tt> interface is
used in
conjunction with the
authorization information in the EJB 1.1 or 2.0 deployment
descriptor. It is also used for the implementation of
<tt>isCallerInRole</tt> call. Set of roleNames would have
only one role in
that case.</p><p>A <tt>CacheRealmMapping</tt> is a "meta-level"
implementation of
RealmMapping that handles lists of realms for a particular J2EE
application. It is called <tt>CacheRealmMapping</tt>
because we cache
information about a particular principal if access to the
persistent mapping is expensive.</p></div><div class="section"><a
name="N1cd8"></a><div class="titlepage"><div><h3 class="title"><a
name="N1cd8"></a><span class="title">SecurityInterceptor</span></h3></div></div><p>The
<tt>SecurityInterceptor's</tt> first task would be
to use the
SecurityManager to authenticate the <tt>Principal</tt>,
based on the
credential available in <tt>MethodInvocation</tt>.</p><p>Then,
<tt>SecurityInterceptor</tt>, given a method that
has to be invoked,
retrieves methodPermissions (set of roles) from the container and checks
if caller's principal has any of those retreived roles.</p></div></div><div
class="section"><a name="N1cf1"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N1cf1"></a><span class="title">Tracing the call through
container</span></h2></div></div><p>The preceding sections discussed specific pieces
of call handling
at length. Now it is time to put all the pieces together to see how a
complete method invocation is handled. In particular, let's look at the
handling of method calls on an Entity Bean.</p><p>The call is first logged. Then
the TxInterceptor decides how to manage
transactions for this call. The information needed for this decision
comes from the standard XML descriptor. Then, the SecurityInterceptor
checks if the caller is allowed to perform this call, again by using
information from the XML descriptor. Up until this point no instance
has been acquired. After all interceptors have been passed the container
will invoke the business method on the EJB instance, so now we
acquire this instance.</p><p>The interceptor calls the InstanceCache with
the given primary key to perform this. Since the cache does not yet
have an instance associated with the given primary key, it first gets
a free instance from the instance pool, which it associates with the
primary key. It then calls the persistence manager which will activate
the instance. This usually only involves calling ejbActivate.</p><p>After
instance acquisition the next interceptor deals with how this
instance is
synchronized with the database. There are a number of options (load on
transaction start, load on each call, load on activate, etc.) and the
interceptor has been configured to perform one of these options. In
this example it will load on activate, so it calls the persistence
manager to perform this. This will cause an ejbLoad call to be made
on the instance.</p><p>Next, the last interceptor is invoked, which is the
container itself. The container always adds itself as the last interceptor
at the end of the chain. The call is now delegated to the EJB instance.
The instance performs some work, and returns a result. The interceptor
chain is now followed in reverse by having each interceptor return from
the invoke-operation. The instance synchronization interceptor chooses
to store the current state into the database and hence calls storeEntity
on the persistence manager. Another valid option would be to wait until
transaction commit.</p><p>Next, the instance is returned to the cache. If the
transaction does not end with this call, it will first lock the instance
to this transaction so that no other transaction may use it for the
duration of this current transaction. This is the same as pessimistic
locking. The transaction interceptor handles the method return according
to the transaction settings, possibly commiting or rollbacking the current
transaction. Finally, the container invoker returns the result to the
client. This completes the call.</p><p>As you can see, all implementation
decisions are performed by various
plugins.
These decisions are fairly loosely coupled, which allows the deployer of
the EJB-application to tweak the behaviour of the container to a great
degree. This also allows for a number of independent plugins to co-exist,
each one allowing for slightly, or radically, different behaviour.</p><p>For
example, some persistence managers could use an XML-file as the
backing
store instead of an RDBMS, and some security interceptor could use ACL's
from a database instead of the XML descriptor to perform security checks.
Or multiple security checks could be done by configuring the container
to have several security interceptors of different types. All of these
options are available by this componentized container
architecture.</p></div></div><div class="chapter" id="N1d10"><div
class="titlepage"><div><h2 class="title"><a name="N1d10"></a>Chapter 9.
Howto</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt> <a
href="#N1d14">Running Tomcat with JBoss</a></dt><dd><dl><dt> <a
href="#N1d18">Goal</a></dt><dt> <a href="#N1d23">Benefits</a></dt><dt> <a
href="#N1d31">Requirements</a></dt><dt> <a href="#N1d3c">How-to setup jboss for
tomcat</a></dt><dt> <a href="#N1d9f">How-to build web applications for jboss and
tomcat</a></dt></dl></dd><dt> <a href="#N1df0">Running the Examples from Enterprise
JavaBeans, by Richard Monson-Haefel (Unix) </a></dt><dt> <a href="#N1ea2">JMX
Connector Description and HowTo</a></dt><dd><dl><dt> <a
href="#N1eb3">Introduction</a></dt><dt> <a href="#N1eee">Design of the JMX
Connector</a></dt><dt> <a href="#N1f71">How To use the JMX Connector</a></dt><dt> <a
href="#N2014">ToDo List</a></dt>!
</dl></dd><dt> <a href="#N2041">How To us the Timer MBean</a></dt><dd><dl><dt> <a
href="#N2052">Introduction</a></dt><dt> <a
href="#N205b">Preparation</a></dt></dl></dd><dt> <a href="#N20f3">Deployment on
JBoss</a></dt><dd><dl><dt> <a href="#N2103">Introduction</a></dt><dt> <a
href="#N210f">J2EE Deployer</a></dt><dt> <a href="#N2130">The AutoDeployer as
helper</a></dt><dt> <a href="#N2148">Creating J2EE applications</a></dt></dl></dd><dt>
<a href="#N219c">JAAS Based Security in JBoss</a></dt><dd><dl><dt> <a
href="#Introduction">Introduction</a></dt><dt> <a href="#jaas1">Security Model
Overview</a></dt><dt> <a href="#jaas2">How to Associate Security With the Container
SecurityInterceptor</a></dt><dt> <a href="#jaas3">Using
JaasSecurityManager</a></dt><dt> <a href="#jaas4">The Session Beans</a></dt><dt> <a
href="#jaas5">Deploying a Bean with Security</a></dt><dt> <a href="#N24c9">Wrap
Up</a></dt></dl></dd><dt> <a href="#N24d2">Using JavaMail in
JBoss</a></dt><dd><dl><dt> <a hr!
ef="#N24e2">Introduction</a></dt><dt> <a href="#N24ea">Installation &
Configuration</a></dt></dl></dd><dt> <a href="#N2554">How to Run JBoss in JBuilder's
Debugger</a></dt><dd><dl><dt> <a href="#N2558">JBuilder Foundation 3.5</a></dt><dt> <a
href="#N2596">JBuilder 4</a></dt></dl></dd><dt> <a href="#N25d3">EJX/AWT Development
HowTo</a></dt><dd><dl><dt> <a href="#N25e3">Introduction</a></dt><dt> <a
href="#ejx1">EJX Insights</a></dt><dt> <a href="#N2623">The launcher</a></dt><dt> <a
href="#N264e">The bean context framework</a></dt><dt> <a href="#N265f">The bean
context root and the services</a></dt><dt> <a href="#N267f">Where the GUI comes in
?</a></dt><dt> <a href="#ejx2">Getting strted with EJX</a></dt><dt> <a
href="#ejx3">EJX/AWT GUI Basics HowTo</a></dt></dl></dd><dt> <a href="#N281e">JBossCX
Configuration</a></dt><dd><dl><dt> <a href="#N282e">Introduction</a></dt><dt> <a
href="#N2841">Contents</a></dt><dt> <a href="#jca1">Terminology</a></dt><dt> <a
href="#jca2">JBoss !
Configuration</a></dt><dt> <a href="#jca3">Example - Black Box Example Adapter from
Sun</a></dt><dt> <a href="#jca4">Implementation Status</a></dt></dl></dd><dt> <a
href="#N2981">External JNDI Configuration and JNDI Viewing</a></dt><dd><dl><dt> <a
href="#N2991">How To Use the JNDI ExternalContext and JNDIView MBeans</a></dt><dt> <a
href="#N299d">Preparation of the ExternalContext MBean</a></dt><dt> <a
href="#N29d3">Preparation of the JNDIView MBean</a></dt><dt> <a href="#N29e3">Using
the JNDIView MBean</a></dt></dl></dd></dl></div><div class="section"><a
name="N1d14"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N1d14"></a><span class="title">Running Tomcat with
JBoss</span></h2></div></div><div class="section"><a name="N1d18"></a><div
class="titlepage"><div><h3 class="title"><a name="N1d18"></a><span
class="title">Goal</span></h3></div></div><p>
As part of project Game Over, the JBoss organization wants to deliver a complete
J2EE based product to the market. The JBoss organization decided to integrate the
Tomcat
engine stack with a running version of JBoss in a single VM. Now you can serve all
your servlet and JSP needs with 2 simple downloads and a couple of configuration files.
Check out the Tomcat homepage for information related to Tomcat. </p><p>
The goal of this page is to explain how to make JBoss automatically start Tomcat,
so that it runs in the same VM.</p></div><div class="section"><a name="N1d23"></a><div
class="titlepage"><div><h3 class="title"><a name="N1d23"></a><span
class="title">Benefits</span></h3></div></div><p>
One benefit of running Tomcat inside the same VM as JBoss is to have an easier to
manage application server. The main goal, however, is greater performance. By
eliminating
unnecessary network calls and keeping all the invocations inside one VM the
performance is significantly enhanced.</p><p>
If you have Servlets/JSPs which access some EJBs, you'll get dramatically improved
performance because the calls will be intra-VM (no network access).</p><p>
WARNING
THIS IS STILL A BETA VERSION. </p></div><div class="section"><a
name="N1d31"></a><div class="titlepage"><div><h3 class="title"><a
name="N1d31"></a><span class="title">Requirements</span></h3></div></div><p>
JBoss 2.0. BETA-PROD 03
Tomcat Version 3.2b4. You can get the latest release of tomcat from the
jakarta website.</p><p>
NOTE: This has been tested with tomcat up to 3.2b6, and should work with the
forthcoming final 3.2 version. However it won't run on tomcat 3.1, and tomcat 3.3 is
not
suppported yet. </p></div><div class="section"><a name="N1d3c"></a><div
class="titlepage"><div><h3 class="title"><a name="N1d3c"></a><span
class="title">How-to setup jboss for tomcat</span></h3></div></div><p>
<div class="itemizedlist"><ul><li><p><a name="N1d44"></a>Setup environment
variables.In whatever batch or shell script you use to launch JBoss and Tomcat, add
entries for the following environment variables
<div class="table"><p><a name="N1d47"></a><b>Table 9.1. Enviromental
variables</b></p><table summary="Enviromental variables"
border="1"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>TOMCAT_HOME</td><td>The
base directory of Tomcat's binaries. With the binary distribution, this would be
jakarta-tomcat under your installation root</td></tr><tr><td>JAVA_HOME</td><td>The
base directory of your JDK 1.2.2 or 1.3
installation</td></tr><tr><td>CLASSPATH</td><td>This should not include anything
(unless you really know what you're doing!). Both Tomcat and JBoss have startup
scripts that load the necessary
JARs onto the classpath.</td></tr></tbody></table></div>
</p></li><li><p><a name="N1d7d"></a>Edit jboss.conf. It is located in the conf
directory under the base of your JBoss binary distribution, or the dist/conf directory
if you built from the JBoss source. There are some commented-out lines near
the end of the file that deal with Tomcat:
<pre class="programlisting">
<!--
-- Uncomment this to add "Integrated Stack (fast) Tomcat support".
-- This service allows you to integrate the stack of Tomcat and jboss.
-- Invocations are not going through network but pass native
-- pointers resulting in dramatic speed increases.
-- This service allows the J2EE deployer to add and remove Tomcat contexts
dynamically
-- through JMX for you and in effect deploy EARs. Note that tomcat's
-- server.xml file will be partially processed for context support: you can
-- also use JMX to add contexts.
-- Use the J2EE deployer to deploy full EARs on this stack
-- Be sure to set your 'TOMCAT_HOME' environment variable before starting
JBoss.
--
-- The ARG tags are the config file and the port to run tomcat on. Note:
only the url
-- contexts will be parsed, (path and docBase attruibutes only) all other
-- configurations are not yet supported.
--
-- MLET CODE = "org.jboss.tomcat.EmbeddedTomcatService" ARCHIVE="jboss.jar"
CODEBASE="../../lib/ext/">
-- ARG TYPE="java.lang.String" VALUE="full path to tomcat config file">
-- ARG TYPE="int" VALUE=8080>
-- /MLET>
</pre>
</p><p>
You need to uncomment these lines so they read as follows (note you must add
the < signs at the beginning of the
three relevant lines and the file path must always begin with a '/'):
<pre class="programlisting">
<MLET CODE = "org.jboss.tomcat.EmbeddedTomcatService" ARCHIVE="jboss.jar"
CODEBASE="../lib/ext/">
<ARG TYPE="java.lang.String" VALUE="/yyy/server.xml">
<ARG TYPE="int" VALUE=8080>
</MLET>
</pre>
</p></li><li><p><a name="N1d8f"></a>Start JBoss. If you start JBoss now by
typing run.sh (or run.bat for Windows) you should see the following Tomcat related
output
in your log messages:
<pre class="programlisting">
...
[EmbeddedTomcat] Initializing
[EmbeddedTomcat] Initialized
[EmbeddedTomcat] Starting
[EmbeddedTomcat] Testing if Tomcat is present....
[EmbeddedTomcat] OK
[EmbeddedTomcat] ContextManager: Adding context Ctx( )
[EmbeddedTomcat] path="" :jsp: init
[EmbeddedTomcat] PoolTcpConnector: Starting HttpConnectionHandler on 8080
[EmbeddedTomcat] Started
...
</pre>
</p></li></ul></div>
</p><p>
That's it !! You just have to launch JBoss now and it will start Tomcat and you
will have an EJB/JSPs/Servlets server running in one VM... </p></div><div
class="section"><a name="N1d9f"></a><div class="titlepage"><div><h3 class="title"><a
name="N1d9f"></a><span class="title">How-to build web applications for jboss and
tomcat</span></h3></div></div><p>
In order to benefit from the classloader integration, you have to deploy your
application in an ear file as recommended by the J2EE specification.</p><p>
Tomcat's server.xml file will not be processed!</p><p>
The reason is that we want to share the classloader for your application between
tomcat and jboss. Since this classloader must be initialized at
deployment time, your EJBs and your servlets/JSPs must be bundled together for
jboss to know who talks to whom! </p><p>
In case you don't want to read all the J2EE spec, here is a brief summary of what
you have to do:</p><div class="orderedlist"><ol type="1"><li><p><a
name="N1db5"></a>Write your beans and package them in an ejb-jar file. You don't have
to do anything special here.
See the manual for details on how to package beans for
jboss.</p></li><li><p><a name="N1db9"></a>Write your servlets/JSPs and package them in
a war file. Assuming you have a bean deployed under the jndi name "myBean",
the calls to this bean from your servlets will look like that: </p><pre
class="programlisting">
MyBeanHome home = (MyBeanHome)new InitialContext().lookup("myBean");
MyBean bean = home.create();
</pre><p>
Notes:
We don't support lookups in the "java:" namespace from the servlets yet,
but work is in progress.
Since jboss takes care of the classloader stuff, you don't have to
include much in the WEB-INF/lib directory: you don't any of your beans interfaces, and
you
don't need the usual jboss-client.jar, jnp-client.jar...
</p></li><li><p><a name="N1dc6"></a>Package your application in an ear file. An ear
file is a jar archive which contains:</p><div class="itemizedlist"><ul><li><p><a
name="N1dcc"></a>Your jar files</p></li><li><p><a name="N1dd0"></a>Your war
files</p></li><li><p><a name="N1dd4"></a>A deployment descriptor for your application.
This file must be named "application.xml", and must be located in the META-INF
directory in the ear archive. This file tells jboss which modules are
EJBs, which ones are web modules, and the context paths for the web-modules.
Here is a sample application.xml file:
<pre class="programlisting">
<?xml version="1.0" encoding="ISO-8859-1"?>
<application>
<display-name>My application</display-name>
<module>
<web>
<web-uri>webmodule.war</web-uri>
<context-root>/servlets</context-root>
</web>
</module>
<module>
<ejb>beans.jar</ejb>
</module>
</application>
</pre>
</p></li></ul></div><p>
See also the DTD for application.xml on Javasoft's website.
</p></li><li><p><a name="N1de2"></a>Deploy your ear file. Surf to
http://yourhost:8082, and find the J2eeDeployer service. Give it the URL of your ear
file
(don't forget the protocol, be it http: or file:), and click on the deploy
button.</p></li><li><p><a name="N1de6"></a>That's it! The server console should show
your application being deployed on tomcat and jboss, and your web module should be
available on
http://yourhost:8080/servlets (assuming the context-root was
"/servlets").</p></li></ol></div><p>
For a full example including a servlet and an EJB, see the contrib module
</p></div></div><div class="section"><a name="N1df0"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N1df0"></a><span
class="title">Running the Examples from Enterprise JavaBeans, by Richard Monson-Haefel
(Unix) </span></h2></div></div><p>Author:
<span class="author">Sebastien Alborini</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><p>
This page describes how to run the examples from Richard Monson-Haefel's book
Enterprise JavaBeans, 2nd Edition
(Chapter 4) in JBoss.</p><p>
You can download the examples (zip file) from O'Reilly's site. I will assume you
have unzipped this file and you work in
the chapter4/EJB11 directory.</p><p>
These examples need to be slightly modified to run with JBoss. You can download the
modified version from the files area in the
documentation section on www.jboss.org. The archive name is
“rmh_jboss.zip”. But I
recommend you to follow these instructions which tell exactly what has to be
modified.</p><div class="itemizedlist"><ul><li><p><a name="N1e0e"></a>Setup your
environment.</p><p>JBoss libraries will be needed to compile and run the examples, so
you have to set the environment variable
JBOSS_HOME to your JBoss installation. For example:
<div class="itemizedlist"><ul><li><p><a name="N1e16"></a>export
JBOSS_HOME=$HOME/jboss_pr4 if you have the binary version in your home directory
</p></li><li><p><a name="N1e1a"></a>export JBOSS_HOME=$HOME/jboss/dist if you have the
CVS version.</p></li></ul></div>
</p></li><li><p><a name="N1e21"></a>Compile and deploy the beans.</p><p>The
beans are almost ok for JBoss, the only difference is about the reference made by
TravelAgentBean to
CabinBean: a bean must lookup in the java:comp/env namespace. Edit
com/titan/travelagent/TravelAgentBean.java, and replace
<pre class="programlisting">
Object obj = jndiContext.lookup("ejb/CabinHome");</pre>
with
<pre class="programlisting">
Object obj = jndiContext.lookup("java:comp/env/ejb/CabinHome"); </pre>
</p><p>
This ejb-reference from TravelAgentBean (in travelagent.jar) to CabinBean (in
cabin.jar) is an external
reference (different ejb-jar file). You must then provide the full jndi name
for CabinBean in a jboss.xml for
TravelAgentBean: create and edit com/titan/travelagent/jboss.xml
<pre class="programlisting">
<?xml version="1.0"?>
<jboss>
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<ejb-ref>
<ejb-ref-name>ejb/CabinHome</ejb-ref-name>
<jndi-name>CabinBean</jndi-name>
</ejb-ref>
</session>
</enterprise-beans>
</jboss>
</pre>
</p><p>
You don't jave to change anything in ejb-jar.xml. You can now use the following
script jbossMakeIt.sh to
compile and deploy:
<div class="literallayout"> <br>
<b><br>
#!/bin/sh <br>
<br>
# make cabin bean<br>
<br>
javac -classpath $JBOSS_HOME/lib/ext/ejb.jar:. \<br>
com/titan/cabin/Cabin*.java<br>
<br>
cp com/titan/cabin/ejb-jar.xml META-INF/ejb-jar.xml<br>
jar cvf cabin.jar com/titan/cabin/Cabin*.class META-INF/ejb-jar.xml<br>
<br>
<br>
# make travelagent bean<br>
<br>
javac -classpath $JBOSS_HOME/lib/ext/ejb.jar:. \<br>
com/titan/travelagent/TravelAgent*.java<br>
<br>
cp com/titan/travelagent/ejb-jar.xml \<br>
com/titan/travelagent/jboss.xml \<br>
META-INF/<br>
<br>
# JBoss needs the Home, Remote and primary key (PK) classes<br>
# of the Cabin in travelagent.jar so that TravelAgent*.class<br>
# can access the Cabin bean<br>
<br>
jar cvf travelagent.jar \<br>
com/titan/cabin/CabinHome.class \<br>
com/titan/cabin/Cabin.class \<br>
com/titan/cabin/CabinPK.class \<br>
com/titan/travelagent/TravelAgent*.class \<br>
META-INF/ejb-jar.xml META-INF/jboss.xml<br>
<br>
rm -f META-INF/ejb-jar.xml<br>
rm -f META-INF/jboss.xml<br>
<br>
# deploy<br>
cp cabin.jar travelagent.jar $JBOSS_HOME/deploy<br>
</b></div>
</p></li><li><p><a name="N1e48"></a>Compile the clients.</p><p>
The clients from the examples perform a lookup on the java:comp/env namespace,
which is not
currently supported by JBoss for the clients. You have to make the following
edits: (CabinBean is the jndi
name under which the Cabin Bean is deployed, see the jndi howto)
In com/titan/cabin/Client_1.java replace
<pre class="programlisting">
Object obj = jndiContext.lookup("java:comp/env/ejb/CabinHome");</pre>
by
<pre class="programlisting">
Object obj = jndiContext.lookup("CabinBean");</pre>
In com/titan/cabin/Client_2.java replace
<pre class="programlisting">
Object obj = jndiContext.lookup("ejb/CabinHome");</pre>
by
<pre class="programlisting">
Object obj = jndiContext.lookup("CabinBean");</pre>
In com/titan/travelagent/Client_1.java replace
<pre class="programlisting">
Object obj = jndiContext.lookup("ejb/CabinHome");</pre>
by
<pre class="programlisting">
Object obj = jndiContext.lookup("CabinBean");</pre>
You can now use jBossMakeClients.sh to compile:
<div class="literallayout"><br>
<b><br>
#!/bin/sh <br>
<br>
javac -classpath $JBOSS_HOME/lib/ext/ejb.jar:. \<br>
com/titan/cabin/Client*.java \<br>
com/titan/travelagent/Client*.java<br>
<br>
</b><br>
</div>
</p></li><li><p><a name="N1e79"></a>Run the clients</p><p>
We don't use Sun's RI runclient tool, so RunIt.sh won't work. Instead, we
provide the following script:
jBossRunClient.sh. This file includes all the jBoss libraries needed in the
classpath.
<div class="literallayout"><br>
<b><br>
#!/bin/sh <br>
<br>
CP=$JBOSS_HOME/client/ejb.jar<br>
CP=$CP:$JBOSS_HOME/client/jndi.jar<br>
CP=$CP:$JBOSS_HOME/client/jta-spec1_0_1.jar<br>
CP=$CP:$JBOSS_HOME/client/jboss-client.jar<br>
CP=$CP:$JBOSS_HOME/client/jnp-client.jar<br>
<br>
CP=$CP:.<br>
<br>
java -cp $CP $1<br>
</b><br>
</div>
You also have to set the jndi properties to connect to the server. This is done
in the jndi.properties file (this file
must be in the same directory as jBossRunClient.sh)
<pre class="programlisting">
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost
java.naming.factory.url.pkgs=org.jboss.naming;
</pre>
You can now run the clients. The script take the name of the client as an
argument, try
<div class="literallayout"> <br>
<b><br>
./jBossRunClient.sh com.titan.cabin.Client_1<br>
./jBossRunClient.sh com.titan.cabin.Client_2<br>
./jBossRunClient.sh com.titan.travelagent.Client_1<br>
</b></div>
</p><p>
NOTES:
the clients will only run once, since they use the EJBHome.create() method:
at second run, a
DuplicateKeyException will occur.
I recommend you to turn off debug logging for these examples. Edit
$JBOSS_HOME/conf/jboss.conf, in
the ConsoleLogging section, set the first ARG to "Error".
</p></li></ul></div></div><div class="section"><a name="N1ea2"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N1ea2"></a><span
class="title">JMX Connector Description and HowTo</span></h2></div></div><p>Author:
<span class="author">Andreas Shaefer</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N1eb3"></a><div class="titlepage"><div><h3
class="title"><a name="N1eb3"></a><span
class="title">Introduction</span></h3></div></div><div class="section"><a
name="N1eb7"></a><div class="titlepage"><div><h4 class="title"><a
name="N1eb7"></a><span class="title">JMX Spec from Sun</span></h4></div></div><p>
Sun release recently the final specification, API and Reference Implemenation
to the
<a href="http://www.javasoft.com/products/JavaManagement/index.html"
target="_top"><i>Java Management
Extention(JMX)</i></a>.
The idea behind this is to provide an API to which the component vendors can
make their components
manageable and the management tools vendor can use this API to manage these
components. </p><p>
Therefore the whole JMX is separated into 3 parts:
<div class="orderedlist"><ol type="1"><li><p><a name="N1ecc"></a>
Components implement a certain API to offer their management API to
the JMX world. There are 3 ways: through an Interface, through a API
descriptions (Open MBean) and through a Model MBean (but for this
have a look at the spec).
</p></li><li><p><a name="N1ed0"></a>
JMX Agent which contains a MBean Server, certain services like
dynamic download, timers, relations etc. and at least one Connector
or Adaptor.
</p></li><li><p><a name="N1ed4"></a>
Management Tool using a Connector or Adaptor to manage the
components of the JMX Agent the tool is connected to.
</p></li></ol></div>
</p></div><div class="section"><a name="N1edb"></a><div
class="titlepage"><div><h4 class="title"><a name="N1edb"></a><span class="title">
JMX Implementation in JBoss</span></h4></div></div><p>
At the moment (8th of September 2000) JBoss uses the final release JMX API for
its services defined in the
jboss.conf file (in there you see that also HTML
Adaptor and the JMX Connector are manageable components). In addition JBoss
use the MBean Server implementation
and the HTML adaptor from the JMX-RI.
The JMX Connector also follows the JMX final spec and API.</p><p>
You use JMX first when you start JBoss because the Main class loads the MLET
tags from the jboss.conf file and
hand it over to the MBeanServer which loads the
MBean dynamically (MLET is the tag to dynamically load a MBean by the
MBeanServer). Afterwards it went through
the loaded MBeans and starts all the loaded
MBeans. </p><p>
Afterwards you can use JMX either trough the JMX HMTL Adaptor on port 8082 or
through the new JMX Connector. The
JMX HTML Adaptor is provided by the
JMX-RI and the source code is not available (it is part of Sun's JDMK which
you have to buy when you want to get
the source as far as I know). The JMX
Connector is part of the JBoss code and should be considered as first draft
because the Connector is mentioned
within the spec by not further specified.
</p><p>
Finally JMX is used within the shutdown hook to terminate all the services
before JBoss is terminated itself
(whatever this means) by going through all available
MBeans and send them the stop signal (call the appropriate method).
</p></div></div><div class="section"><a name="N1eee"></a><div
class="titlepage"><div><h3 class="title"><a name="N1eee"></a><span
class="title">Design of the JMX Connector</span></h3></div></div><div
class="section"><a name="N1ef3"></a><div class="titlepage"><div><h4 class="title"><a
name="N1ef3"></a><span class="title">Introduction</span></h4></div></div><p>
According to the JMX spec the Connector should allow a management tool to work
on a MBeanServer and its MBeans
from another JVM which can be on the same
computer or a remote computer. One particular Connector is bound to its
protocol it supports but a MBeanServer
can offer more than one (a JMX agent has to offer
at least an Adaptor or a Connector) supporting different protocols. Because
the spec does not say much about
Connectors I take the freedom and implemented the
actual Connector within JBoss to lay the base for a remote JBoss management
which is a little bit more
comfortable than the HTML Adaptor.</p><p>By the way I will take this
opportunity to thanks Rickard ֢erg for his support. </p></div><div
class="section"><a name="N1eff"></a><div class="titlepage"><div><h4 class="title"><a
name="N1eff"></a><span class="title">Goals</span></h4></div></div><p>These are my
goals for a JMX Connector:
<div class="itemizedlist"><ul><li><p><a name="N1f08"></a>Ease of
use</p></li><li><p><a name="N1f0c"></a>From the user perspective the Connector should
appear like a local</p></li><li><p><a name="N1f10"></a>MBeanServer</p></li><li><p><a
name="N1f14"></a>Unsupported methods throw an exception</p></li><li><p><a
name="N1f18"></a>Supports remote notification handling</p></li><li><p><a
name="N1f1c"></a>First draft supports RMI protocol</p></li></ul></div>
</p><p>
According to the spec the JMX Connector should offer the client a Proxy for a
remote MBean but then the MBean
proxy must be available at compile time and this
compete with the JMX agent requirements that an JMX agent has to support
dynamic loading of MBeans therefore this
is not supported now. </p><div class="section"><a name="N1f25"></a><div
class="titlepage"><div><h5 class="title"><a name="N1f25"></a><span
class="title">Design</span></h5></div></div><p>
The JMX Connector is separated into 4 parts:
<div class="orderedlist"><ol type="1"><li><p><a name="N1f32"></a>Server-side
implementation </p></li><li><p><a name="N1f36"></a>Client-side implementation
</p></li><li><p><a name="N1f3a"></a>Connector Factory to lookup servers and protocols
(optional)</p></li><li><p><a name="N1f3e"></a>Test client </p></li></ol></div>
</p><div class="section"><a name="N1f44"></a><div class="titlepage"><div><h6
class="title"><a name="N1f44"></a><span class="title">Server-side
implementation</span></h6></div></div><p>
The server-side implementation is loaded and started by the MBeanServer which
should become available for remote
management. For this we have the necessary
MBean service classes, the Connector implementation and an Object Handler
class.
The Object Handler class is a serializable class allowing the remote client to
deal with remotely instantiated
classes. This eliminates problems with not serializable
classes and with the unique identification of serialized classes (on a round
trip you get a copy of the original
instance). </p><p>
The Object Handler is also used to avoid
troubles with not serializable classes used as a Handback object in the
Notification handling. This class allows
the client to work on the JMX Connector as he
would work on a local MBeanServer.</p></div><div class="section"><a
name="N1f50"></a><div class="titlepage"><div><h6 class="title"><a
name="N1f50"></a><span class="title"> Client-side
implementation</span></h6></div></div><p>
The client-side implementation can either be used directly by instantiating
the RMIClientConnectorImpl or by
using the Connector Factory. The client-side
Connector is more or less a MBeanServer which sends the request over the
supported protocol to the server-side
connector and returns the returned object back to
the caller. There are a few methods which cannot be supported and therefore
throw a unsupported operation
exception. </p><p>
To make it clear and also for documentation purpose the client-side connector
implements the JMXConnector
Interface. At the moment I want still keep this
interface even when MBeanServer is now an interface too because which all good
programming techniques it is (at
least at the moment) not possible to make it
100% transparent (but see later under limitations). </p></div><div
class="section"><a name="N1f5c"></a><div class="titlepage"><div><h6 class="title"><a
name="N1f5c"></a><span class="title"> Connector Factory</span></h6></div></div><p>
When I started with the JMX Connector I had a management tool in mind like the
network administration tool from
CA or the proposed AppCenter from Inprise.
Therefore I want to make it as easy as possible for the client to connector as
many remote MBeanServers as he/she
wants and which any protocol available. The
client should never have to worry about the protocol or to know which classes
are behind. That's why I created
the Connector Factory which allows the client to
search for all the remote available MBeanServers and their supported
protocols. The user only has to select a
server and then a protocol and the Connector Factory
returns the appropriate instance of the JMXConnector interface. </p></div><div
class="section"><a name="N1f65"></a><div class="titlepage"><div><h6 class="title"><a
name="N1f65"></a><span class="title"> Test Client</span></h6></div></div><p>
The JMX Connector Test Client is first a test tool that the JMX Connector is
working and second a demonstration
how to use it. The test tool first starts a local
MBeanServer and register the Connector Factory as first and then only MBean.
Now the test client ask the
Connector Factory for all available, remote
MBeanServers and let the user select one, then it asks the Connector Factory
for all available Connectors or more
precise all the supported protocols of the
available Connectors. Now the user can select the protocol and the Test Client
loads and starts the appropriate
Connector (if available) and register it as a new
MBean at the local MBeanServer. Afterwards it asks the Connector for all
available MBeans on the remote server,
displays it wit all the attributes and operations
on this remote MBean. At the end it will try to register to all remote MBeans
a notification listener which will
inform the client about notification send by the MBean.
That's why the test client will still run after finishing. When the user
terminates the Test Client it will
remove all the notification listeners from the remote
MBeanServer and terminate the Test Client. </p></div></div></div></div><div
class="section"><a name="N1f71"></a><div class="titlepage"><div><h3 class="title"><a
name="N1f71"></a><span class="title">How To use the JMX
Connector</span></h3></div></div><p>
You need the following to use the JMX Connector:
<div class="itemizedlist"><ul><li><p><a name="N1f7a"></a>Connector.jar
(from client directory) </p></li><li><p><a name="N1f7e"></a>jnp-client.jar (from
client directory) </p></li><li><p><a name="N1f82"></a>jmxri.jar (from lib directory)
</p></li><li><p><a name="N1f86"></a>jndi.properties (from conf directory) which you
probably have to
adjust</p></li></ul></div>
</p><div class="section"><a name="N1f8c"></a><div class="titlepage"><div><h4
class="title"><a name="N1f8c"></a><span class="title">How to create a client with the
server and protocol</span></h4></div></div><p>
<div class="orderedlist"><ol type="1"><li><p><a name="N1f99"></a>
Instantiate the RMIClientConnectorImpl.
<pre class="programlisting">
JMXConnector lConnector = new RMIClientConnectorImpl("server-name"
); </pre>
</p></li><li><p><a name="N1fa2"></a>
Use either instance or its interface JMXConnector or MBeanServer. If you
got back an instance you can now
work on the remote MBeanServer like it would be a local one.
</p></li><li><p><a name="N1fa6"></a>
Look up for the available MBeans, its attributes and operations. You can
now retrieve and set the
attributes or perform an operation on the remote MBean.
</p></li><li><p><a name="N1faa"></a>
If you register a Notification Listener then stop this instance before
terminating the program otherwise
the remote MBeanServer will throw an exception when this Notification
Listener is called.
lConnector.stop();
</p></li></ol></div>
</p></div><div class="section"><a name="N1fb1"></a><div
class="titlepage"><div><h4 class="title"><a name="N1fb1"></a><span class="title">How
to create a client without the server and protocol/H3> </span></h4></div></div><p>
First you have to make sure that the JNDI property:
java.naming.provider.url points to the JNDI server your JMX Connectors
are registered to. At the moment you can only have one JMX Connector
running at the same computer (but serveral can be registered at the same
JNDI server) and you can only have one JNDI server. </p><div
class="orderedlist"><ol type="1"><li><p><a name="N1fbf"></a>
Import the necessary classes
<pre class="programlisting">
import com.sun.management.jmx.MBeanServerImpl;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
import javax.naming.InitialContext;
import org.jboss.jmx.interfaces.JMXConnector;
import org.jboss.jmx.client.RMIClientConnectorImpl; </pre>
</p></li><li><p><a name="N1fc8"></a>
Instantiate a local MBeanServer (MBeanServerImpl)
<pre class="programlisting">
final MBeanServer lLocalServer = new MBeanServerImpl(); </pre>
The local variable is made final because it is needed in the shutdown
hook.
</p></li><li><p><a name="N1fd1"></a>
Load the logger MBean (is needed now because the Connector Factory
is a standard JBoss MBean but maybe I should make it to a normal
MBean to make it leaner).
<pre class="programlisting">
lLocalServer.createMBean( "org.jboss.logging.Logger", new
ObjectName( "DefaultDomain :name=Logger" ) ); </pre>
</p></li><li><p><a name="N1fda"></a>
Load and start the ConnectorFactory MBean
<pre class="programlisting">
final ObjectInstance lFactoryInstance =
lLocalServer.createMBean(
"org.jboss.jmx.client.ConnectorFactoryService", new
ObjectName( "DefaultDomain:name=ConnectorFactory" ) );</pre>
</p></li><li><p><a name="N1fe3"></a>
Look for the list of servers (if a null is passed as parameter this
method returns all the servers at the given JNDI server)
<pre class="programlisting">
Collection lServers = (Collection) lLocalServer.invoke(
lFactoryInstance.getObjectName(), "getServers", new
String[] {null}, new String[] {"java.lang.String"} );</pre>
and within a server for the list of protocols (if a null or empty
string is passed then all protocols at
the given JNDI server will be listed)
<pre class="programlisting">
Collection lProtocols = (Collection) lLocalServer.invoke(
lFactoryInstance.getObjectName(), "getProtocols", new
String[] {lServer}, new String[] {"java.lang.String"} ); </pre>
</p></li><li><p><a name="N1ff1"></a>
Create a connection to the selected Connector
<pre class="programlisting">
JMXConnector lConnector = (JMXConnector)lLocalServer.invoke(
lFactoryInstance.getObjectName(),"createConnection", new Object[]
{lServer,lProtocol}, new String[]
{"java.lang.String","java.lang.String");
</pre>
</p></li><li><p><a name="N1ffa"></a>
Use the new Connector MBean on the local MBeanServer to get and set the
attributes and perform
operation on the chosen MBeans on the remote MBeanServer.
<pre class="programlisting">
Iterator i = pConnector.queryMBeans( null, null).iterator();
while( i.hasNext() ) {
MBeanInfo info = pConnector.getMBeanInfo( ( (ObjectInstance)
i.next()).getObjectName() );
MBeanAttributeInfo[] aInfos = info.getAttributes();
.
.
. MBeanOperationInfo[] oInfos = info.getOperations();
}</pre>
</p></li><li><p><a name="N2003"></a>
Register a Notification Listener on a remote MBean and wait for
notification events sent from the
remote MBean.
<pre class="programlisting">
Iterator i = pConnector.queryMBeans( null,
nullitemizedlist).iterator();
int j = 0;
while( i.hasNext() ) {
ObjectInstance lBean = (ObjectInstance) i.next();
try {
pConnector.addNotificationListener( lBean.getObjectName(),
(NotificationListener) new Listener(),(NotificationFilter)
null,
new NotSerializableHandback(lBean.getObjectName() + "" + j++
)
); ... </pre>
But when you terminate the connector you have to remove the connection
by using the Connector
Factory to remove all the Notification Listener from the remote
MBeanServer.
<pre class="programlisting">
lLocalServer.invoke( lFactoryInstance.getObjectName(),
"removeConnection", new Object[] {lServer,lProtocol}, new
String[] {"java.lang.String","java.lang.String"} );</pre>
</p></li></ol></div></div></div><div class="section"><a name="N2014"></a><div
class="titlepage"><div><h3 class="title"><a name="N2014"></a><span class="title">ToDo
List</span></h3></div></div><p>This list contains all the stuff to be done to make the
JMX Connector full
fledged:
<div class="itemizedlist"><ul><li><p><a name="N201c"></a>Implement the server
lookup in the Connector Factory to work with JNDI</p></li><li><p><a
name="N2020"></a>Implement the protocol lookup in the Connector Factory to work with
JNDI</p></li><li><p><a name="N2024"></a>Test all to make sure that it works from any
other JVM that the JBoss VM </p></li></ul></div>
</p><p>
This list contains all the stuff to be done around JMX
<div class="itemizedlist"><ul><li><p><a name="N202e"></a>Initiate and start
full fledged JMX Agent project</p></li><li><p><a name="N2032"></a>Design and implement
Relation Service for the JMX Agent</p></li><li><p><a name="N2036"></a>Design and
implement graphic management tool for JBoss</p></li></ul></div>
</p><p>
If anything is wrong or not correct please contact me at
[EMAIL PROTECTED] Also if you want to know more in detail
or have a request for changes in the JMX Connector.
</p></div></div><div class="section"><a name="N2041"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N2041"></a><span
class="title">How To us the Timer MBean</span></h2></div></div><p>Author:
<span class="author">Andreas Shaefer</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N2052"></a><div class="titlepage"><div><h3
class="title"><a name="N2052"></a><span
class="title">Introduction</span></h3></div></div><p>
As part of the JMX specification each JMX compliant server must provide a
timer service to let the users
beeing notified at a certain time, in a certain interval and/or number of
occurrences.
Therefore you can check for mails, check if some change on target (auto
deployer) or notify the client for a
date.</p></div><div class="section"><a name="N205b"></a><div
class="titlepage"><div><h3 class="title"><a name="N205b"></a><span
class="title">Preparation</span></h3></div></div><div
class="itemizedlist"><ul><li><p><a name="N2062"></a>
First you have to add the timer service into the jboss.conf therefore that
the timer service is loaded, registered
at the JMX server and the initialized and started (done by JBoss's Main.java
class). This MLET tag looks like
this:
<pre class="programlisting">
<MLET CODE = "javax.management.timer.Timer"
NAME="DefaultDomain:service=timer"
ARCHIVE="jmxri.jar" CODEBASE="../../lib"> </MLET>
</pre>
</p></li><li><p><a name="N206d"></a>
If you are not using JBoss then to the following:
<div class="orderedlist"><ol type="1"><li><p><a name="N2077"></a>
Create a MBeanServer
<pre class="programlisting">
MBeanServer lServer =
MBeanServerFactory.createMBeanServer();
</pre>
</p></li><li><p><a name="N2080"></a>
Load and register the Timer MBean
<pre class="programlisting">
ObjectInstance lTimer =
lServer.createMBean(
"javax.management.timer.Timer", new
ObjectName( "DefaultDomain",
"service", "timer" ) );
</pre>
</p></li><li><p><a name="N2089"></a>Initialize and start the timer
service
<pre class="programlisting">
lServer.invoke(
lTimer.getObjectName(), "init", new
Object[] {}, new String[] {} );
lServer.invoke(
lTimer.getObjectName(), "start", new
Object[] {}, new String[] {} );
</pre>
</p></li></ol></div>
</p></li><li><p><a name="N2094"></a>Next step is to get the MBeanServer
within your object to work with the timer.</p><p>
This is quite simple if your are in a MBean registered to the same
JMX server because
then you get it when you overwrite preRegister() method.
When you are in the same JVM as the JMX server (in JBoss is any
instance running
within JBoss like EJBs or other classes). Then you can obtain the
MBeanServer throug: </p><pre class="programlisting">
MBeanServer lServer =
MBeanServerFactory.createMBeanServer();</pre><p>
For the rest it is a little bit more complicated. In a Java client
you can use JBoss RMI
connector which will be released as separat package till mid
December 2000. Then you
connect to a MBeanServer through the JMXConnector interface which is
more or less
the same. </p></li><li><p><a name="N20a5"></a>
We are nearly there: now we need the reference to the timer service to work
on it (lServer can be either of
type MBeanServer or JMXConnector): </p><pre class="programlisting">
Set lBeans = lServer.queryMBeans( new ObjectName(
"DefaultDomain", "service", "timer" ), null ); if(
!lBeans.isEmpty() ) { // Should be the first and
only element ObjectInstance lTimer =
(ObjectInstance) lBeans.iterator().next();
</pre></li><li><p><a name="N20b0"></a>
Let's go to work with the timer. Because the timer sends a Notification Event
to the listeners we have to
register first: </p><pre class="programlisting">
lServer.addNotificationListener(
lTimer.getObjectName(), new Listener(), // No
filter null, // No object handback necessary null
);</pre></li><li><p><a name="N20bb"></a>
The Listener (in this case) is an inner class implementing the
NotificationListener interface: </p><pre class="programlisting">
public class Listener implements
NotificationListener { public handleNotification(
Notification pNotification, Object pHandback ) {
// Here to whatever you want or call a method //
in the outer class System.out.println( "You got a
Notification: " + pNotification ); } } </pre></li><li><p><a
name="N20c6"></a>
Finally we are ready to rock and roll. We set a timer event for a particular
time and at this time the
Listener.handleNotification() get called.</p><pre class="programlisting">
Integer lOneMinuteTimer = lServer.invoke(
lTimer.getObjectName(), "addNotification", new
Object[] { "IDoNotKnowWhatTypeIs", "I call you
with this timer once", // No user object null, //
I one minute from now new Date( new
Date().getTime() + Timer.ONE_MINUTE ), }, new
String[] { String.getClass().getName(),
String.getClass().getName(),
Object.getClass().getName(),
Date.getClass.getName() } ); </pre></li><li><p><a name="N20d1"></a>
A timer notification after an Hour from now repeating every minute for ten
times.</p><pre class="programlisting">
Integer lOneHourTimer = lServer.invoke(
lTimer.getObjectName(), "addNotification", new
Object[] { "IDoNotKnowWhatTypeIs", "I call you
with this timer once", // No user object null, //
I one minute from now new Date( new
Date().getTime() + Timer.ONE_HOUR ),
Timer.ONE_MINUTE, 10 }, new String[] {
String.getClass().getName(),
String.getClass().getName(),
Object.getClass().getName(),
Date.getClass.getName(), Long.TYPE.getName(),
Long.TYPE.getName() } ); </pre></li><li><p><a name="N20dc"></a>
If you want to get ride of the second timer then do:</p><pre
class="programlisting">
lServer.invoke( lTimer.getObjectName(), "removeNotification", new
Object[] {
// You could also use the type: "IDoNotKnowWhatTypeIs" lOneHourTimer },
new String[] { // If you remove by type: String.getClass().getName()
Integer.TYPE.getName() } ); </pre></li></ul></div><p>
Now the rest is quite simple. Have a look at the javax.management.Timer class
description and use the
MBeanServer.invoke() method style.</p><p>Attention: When you have basic data
type in the method signature then
you have to use its wrapper class TYPE variable to get its class instead of
using just "long" etc.</p><p>If anything is wrong or not correct please contact me at
[EMAIL PROTECTED] Also if
you want to know more in detail or have a request for further
infos.</p></div></div><div class="section"><a name="N20f3"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N20f3"></a><span
class="title">Deployment on JBoss</span></h2></div></div><p>
Author:
<span class="author">Daniel Schulze</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N2103"></a><div class="titlepage"><div><h3
class="title"><a name="N2103"></a><span
class="title">Introduction</span></h3></div></div><p>
The application deployment on JBoss is managed by the J2eeDeployer MBean. The
J2eeDeployer is able
to deploy ejb.jar packages, webapplication.war packages and j2ee
application.ear packages.
Furthermore he is able to deploy unpacked ejb.jar files for development
purposes.
</p><p>
The deployment is url based, so it is possible to deploy from whatever source
as long as there is
a url handler for that source available in your environment.
(ie. http://somehost/applications/app.ear or
file:///home/user/development/myapp.ear)
</p></div><div class="section"><a name="N210f"></a><div class="titlepage"><div><h3
class="title"><a name="N210f"></a><span class="title">J2EE
Deployer</span></h3></div></div><p>
The J2eeDeployer currently provides 3 methods:
</p><div class="itemizedlist"><ul><li><p><a name="N2119"></a>
void deploy (URL)
this method starts the deployment process for the application this URL points
to. The URL can be a
file: or a http:// or any other type of url your environment is capable to
handle. In case of
deploying a unpacked ejb.jar package the URL type is currently limited to file.
The deployment of an already deployed application (the name of the app is
significant) will result in an
undeployment of this app followed by a redeployment.
</p></li><li><p><a name="N211f"></a>
void undeploy (URL or Application name)
use this to undeploy an application. the parameter can be the URL that was
used to deploy this application or just the name (application name = file name
of the app package or directory name in case of unpacked) of the application.
</p></li><li><p><a name="N2125"></a>
boolean isDeployed (URL or Application name)
use this method to ask for the state of an application. The argument follows
the same rules as for the undeploy method.
</p></li></ul></div><p>
These 3 methods can be used via the web interface of JBoss at port 8082 at the
host JBoss is running on.
</p></div><div class="section"><a name="N2130"></a><div class="titlepage"><div><h3
class="title"><a name="N2130"></a><span class="title">The AutoDeployer as
helper</span></h3></div></div><p>
The AutoDeployer MBean is a helper for the J2eeDeployer to allow doing
administration smoothly via drag and drop
or to automate the redeployment in case of development. He observes the given
directories for changes and calls
the appropriate methods on the J2eeDeployer.
</p><p>
The AutoDeployer observes the timestamps of the application packages or the
timestamp of the META-INF/ejb-jar.xml
file in case of unpacked ejb.jar files.
</p><p>
The AutoDeployer is configured whether static by the MLET configuration or
dynamic by adding urls to watch for
in its web interface (port 8082 at the host JBoss is running on).
</p><p>
In its current version the AutoDeployer supports only local directories to
observe.
</p><p>
To deploy an ejb, web or ear package simply drop it in one of the observed
directories.
To autodeploy an unpacked ejb application, add the base directory of that
application
(base directory = the directory which containes the META-INF directory) to the
AutoDeployers
observed urls.
</p><p>
Note: There is still a misbehavior when the autodeployer thread wins the race
against the copy thread
which modifies a package!
</p></div><div class="section"><a name="N2148"></a><div class="titlepage"><div><h3
class="title"><a name="N2148"></a><span class="title">Creating J2EE
applications</span></h3></div></div><p>
j2ee applications or .ear files are jar archives containing a collection of
ejb, web, client, connector and/or
other library packages. Currently JBoss only supports ejb, web and other
library packages (client and connector
packages are ignored if present).
</p><p>
Other Library packages are class packages that are needed by your application
and are not provided by the j2ee
runtime environment (ie: some xml tools)
</p><p>
This document will only describe the JBoss relevant stuff in creating j2ee
packages for a detailed description
of how to build such applications see the J2EE specification under chapter 8!
</p><p>
First create all ejb, war and library archives you want to put together to
make up your application. Make sure
that all dependencies are solved, means: all classes that are needed by your
application must be contained in
your application (besides the classes that made up the J2EE platform (java
core, javax.transaction,
javax.sql, javax.servlet ...). Its up to you to create an arbitrary directory
structure for your application
to make it easier to maintain. Once you ve created your structure and moved
all files on their place you have
to create a deployment descriptor. This file must reside in the
<your_app_dir>/META-INF directory and must be
named application.xml.
</p><p>
Example:
the content of a simple application.xml file:
</p><pre class="programlisting">
<application>
<display-name>My Application</display-name>
<module>
<web>
<web-uri>web-app.war</web-uri>
<context-root>/myapp</context-root>
</web>
</module>
<module>
<ejb>ejb-app.jar</ejb>
</module>
</application>
</pre><p>
This descriptor describes an application that contains a web application
package (JSPs/Servlets/HTML) and an
ejb application (EJBs). The web applications war package is located at the
root of the .ear file and is named
web-app.war. It will be deployed under the webcontext /myapp. The ejb package
also resides in the applications
root directory and is called ejb-app.jar.
</p><p>
Understanding the shared classloader architecture in JBoss
</p><p>
When an application in JBoss gets deployed, every module will get deployed by
a separate container.
Every container will get its own classloader - this means that a call from one
module to an other must
be an remote call and all parameters must be serialized, because the classes
(even if they are loaded
from the same physical file) are not compatible across container boundaries.
To allow optimized
interaction across container boundaries (local calls with parameter ... per
reference) the classes
that are involved in this communication must be loaded by the same classloader.
</p><p>
In JBoss we achieve this issue with the following classloader architecture:
</p><p>
On deployment one - common - classloader is created. This classloader will get
all archives in its classpath
that are referenced (MANIFEST.MF/Class-Path)by any module contained in this
application.
</p><p>
When afterwards all modules become deployed in their containers, the
classloaders created by these containers
are all children of the common classloader.
</p><p>
Now on runtime the communication between modules across container
boundaries can be optimized when the classes used for the communication are
loaded by the common classloader.
</p><p>
example (continued):
To allow our previous mentioned simple example to make use of the
optimization, we must provide the classes the web
module needs to communicate with the ejb module in an separate third package,
lets call it ejb-client.jar.
This ejb-client.jar archive contains the remote interfaces of the ejbs and
special method parameter types that are
needed for the communication (if any). Now we put this package in the
directory /lib of our application.
</p><p>
To make sure that this package is now loaded by the common classloader, we
reference it from within the web
package by adding a Class-Path: entry to the web packages MANIFEST.MF file
that it looks something like that:
</p><div class="literallayout"> <br>
<tt><br>
Manifest-Version: 1.0<br>
Class-Path: ./lib/ejb-client.jar<br>
</tt><br>
</div><p>
Now you just jar your applications directory, name it
<anyhow>.ear, and drop it in one of JBoss'
autodeploy directories...
</p><p>
the content of our simple applications archive:
</p><div class="literallayout"> <tt><br>
META-INF/<br>
META-INF/MANIFEST.MF<br>
META-INF/application.xml<br>
ejb-app.jar<br>
web-app.war<br>
lib/<br>
lib/ejb-client.jar<br>
</tt><br>
</div></div></div><div class="section"><a name="N219c"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N219c"></a><span
class="title">JAAS Based Security in JBoss</span></h2></div><div><h2
class="subtitle">Custom Security in JBoss Using the JBossSX
Framework</h2></div></div><p>
Author:
<span class="author">Scott Stark</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3
class="title"><a name="N21b1">Note</a></h3><p>The JBossSX framework is a new addition
to JBoss that requires a
cvs snapshot that is latter than March 4 2001, or the JBoss-2.1 final binary.
</p></div>
</p><div class="section"><a name="Introduction"></a><div class="titlepage"><div><h3
class="title"><a name="Introduction"></a><span
class="title">Introduction</span></h3></div></div><p>
This document describes the setting up secured access to JBoss hosted EJBs
for both the standard declarative J2EE security model as well as custom
JAAS Subject based security. It should be sufficient to allow you to configure
a simple security setup for testing and also give you a good start to being
able to inegrate your own custom security implementation into JBoss. For
a more detailed description of the JBossSX framework see the JBossSX
chapter.
</p><div class="itemizedlist"><ul><li><p><a name="N21c3"></a><a
href="#jaas1">Security Model Overview</a></p></li><li><p><a name="N21ca"></a><a
href="#jaas2">How to Associate Security With the Container
SecurityInterceptor</a></p></li><li><p><a name="N21d1"></a><a href="#jaas3">Using
JaasSecurityManager</a></p></li><li><p><a name="N21d8"></a><a href="#jaas4">The
Session Beans</a></p></li><li><p><a name="N21df"></a><a href="#jaas5">Deploying a Bean
with Security</a></p></li></ul></div></div><div class="section"><a
name="jaas1"></a><div class="titlepage"><div><h3 class="title"><a
name="jaas1"></a><span class="title">Security Model Overview</span></h3></div></div><p>
The security model in JBoss is based on the server container architecture's
pluggable method interceptors and the fact that the container factory always
inserts security interceptor(org.jboss.ejb.plugins.SecurityInterceptor).
The SecurityInterceptor delegates the tasks of principal authentication
and and principal role mapping to two different security interfaces;
org.jboss.security.EJBSecurityManager and org.jboss.security.RealmMapping.
JBoss includes a number of sample implementations of both interfaces which
can be found in the org.jboss.security.plugins.samples package.
</p><p>
The default security implementation that comes pre-configured is JMX service
bean and a JAAS based implementation of both interfaces. The JMX bean is
org.jboss.security.plugins.JaasSecurityManagerService and the security
interfaces implementation is org.jboss.security.plugins.JaasSecurityManager.
This document will focus on setting up the JaasSecurityManager via the
JaasSecurityManagerService for a trivial stateless session bean. Once you can
perform the steps documented to secure the example bean, you should be able
to introduce your own production ready security using this example as a
template.
</p></div><div class="section"><a name="jaas2"></a><div class="titlepage"><div><h3
class="title"><a name="jaas2"></a><span class="title">How to Associate Security With
the Container SecurityInterceptor</span></h3></div></div><p>
Ok, so you know that every EJB container in JBoss includes a SecurityInterceptor
that delegates its security checks to a security manager implementation.
How do you choose which implementations a given container uses?
You specify this information via the jboss deployment descriptor.
</p><div class="section"><a name="N2200"></a><div class="titlepage"><div><h4
class="title"><a name="N2200"></a><span class="title">
The JBoss Deployment Descriptor(jboss.xml and standardjboss.xml)
</span></h4></div></div><p>
The JBoss deployment descriptor is the JBoss application specific deployment
configuration file. It describes implementation behavior that is outside of the
EJB spec ejb-jar.xml deployment descriptor. The standardjboss.xml version of the
file is located in ${jboss_home}/conf/conf_name where ${jboss_home} is the
directory into which you have installed the JBoss distribution and conf_name is
the specific runtime configuration that you specify to the run.sh or
run.bat script when starting the server. The default value for conf_name is
"default". The standardjboss.xml specifies the global configuration default
values. You can also specific ejb-jar or j2ee-ear specific jboss.xml descriptors
that override specific or all configuration properties as appropriate for
your application. There are a quite a few configurable properties that can be
set in the file, but all are optional. For all of the possible configuration
elements and their details see the jboss.dtd. We are only concerned with the
three security specific elements: </p><div class="itemizedlist"><ul><li><p><a
name="N2209"></a>security-domain</p></li><li><p><a
name="N220d"></a>role-mapping-manager</p></li><li><p><a
name="N2211"></a>authentication-module</p></li></ul></div><div class="section"><a
name="N2216"></a><div class="titlepage"><div><h5 class="title"><a
name="N2216"></a><span class="title">security-domain</span></h5></div></div><p>
The security-domain element specifies the an implementation of both the
org.jboss.security.RealmMapping and org.jboss.security.EJBSecurityManager
interfaces to use for all J2EE deployment units in the ear or ejb-jar.
The value is specified as the JNDI name where the object is located.
Hence, the security-domain is like a JMS TopicConnectionFactory in
that it is accessed via a JNDI name whose setup is a managed process.
</p></div><div class="section"><a name="N221e"></a><div class="titlepage"><div><h5
class="title"><a name="N221e"></a><span
class="title">role-mapping-manager</span></h5></div></div><p>
The role-mapping-manager element specifies the implementation of the
org.jboss.security.RealmMapping interface that is to be used by the container
SecurityInterceptor. The value is specified as the JNDI name where the object is
located. As far as the container configuration is concerned, an implementation
of org.jboss.security.RealmMapping exists in the JBoss server JNDI namespace
and role-mapping-manager element provides the location.
</p></div><div class="section"><a name="N2226"></a><div class="titlepage"><div><h5
class="title"><a name="N2226"></a><span
class="title">authentication-module</span></h5></div></div><p>
The authentication-module element specifies the implementation of the
org.jboss.security.EJBSecurityManager interface that is to be used by the
container SecurityInterceptor. The value is specified as the JNDI name to where
the object is located, just like the role-mapping-manager.
</p></div><div class="section"><a name="N222e"></a><div class="titlepage"><div><h5
class="title"><a name="N222e"></a><span class="title">Sample
jboss.xml</span></h5></div></div><p>
The sample jboss.xml descriptor we will use is:
</p><div class="figure"><p><a name="jboss.xml"></a><b>Figure 9.1.
jboss.xml</b></p><pre class="programlisting">
<?xml version="1.0"?>
<jboss>
<!-- All bean containers use this security manager by default -->
<security-domain>java:/jaas/other</security-domain> <a
name="jboss.sample.sd"></a><img border="0" alt="1" src="./images/callouts/1.png">
<container-configurations>
<!-- Override the role mapping function from that of the
security-domain setting for stateless session beans -->
<container-configuration>
<!-- Use the standardjboss.xml container-name so we only have
to specify the elements we want to override -->
<container-name>Standard Stateless
SessionBean</container-name>
<role-mapping-manager>java:/jaas/session-roles</role-mapping-manager><a
name="jboss.sample.rmm"></a><img border="0" alt="2" src="./images/callouts/2.png">
</container-configuration>
</container-configurations>
</jboss>
</pre><div class="calloutlist"><a name="N224a"></a><table summary="Callout list"
border="0"><tr><td align="left" valign="top" width="5%"><a name="N224c"></a><a
href="#jboss.sample.sd"><img border="0" alt="1" src="./images/callouts/1.png"></a>
</td><td align="left" valign="top"><p>
Establishes a global security manager via the
<tt>security-domain</tt> element.
</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="N2259"></a><a
href="#jboss.sample.rmm"><img border="0" alt="2" src="./images/callouts/2.png"></a>
</td><td align="left" valign="top"><p>
Overrides the global security manager role mapping function for
stateless session beans.
</p></td></tr></table></div></div><p>
Here we are assigning a global security manager for all beans to the
the object located at java:/jaas/other and we are setting a different
role mapping manager for the “Standard Stateless SessionBean”
container. This means that any stateless session beans bundled in the
ear or jar will use the RealmMapper located at java:/jaas/session-roles rather
the the security-domain element setting.
We will see the reason for choosing JNDI names of the form java:/jaas/XXX
over the next couple of sections.
</p></div></div><div class="section"><a name="N226d"></a><div
class="titlepage"><div><h4 class="title"><a name="N226d"></a><span
class="title">Setting Up the Security Manager Implementation in
JNDI</span></h4></div></div><p>
So we have setup the container configuration security elements to specify the
JNDI names where the desired RealmMapping and EJBSecurityManager implementations
are to be obtained from. Now the question is how to bind implementations into the
JBoss server JNDI namespace. The answer is to create a JMX mbean that creates and
binds the desired implementations at server startup. The
JaasSecurityManagerService is an mbean that has been written that we will use to
perform the required setup.
</p><p>
To configure the JaasSecurityManagerService, open the
${jboss_home}/conf/default/jboss.jcml file and look for an entry like:
</p><pre class="programlisting">
<!-- JAAS security manager and realm mapping -->
<mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
name="Security:name=JaasSecurityManager">
<attribute
name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
<attribute
name="SecurityProxyFactoryClassName">org.jboss.security.SubjectSecurityProxyFactory</attribute>
</mbean>
</pre><p>
If it is commented out or does not exist, uncomment or add the entry. The
JaasSecurityManagerService service creates a reference to a JNDI Context at
java:/jaas that lazily binds instances of
org.jboss.security.plugins.JaasSecurityManager
under java:/jaas as they are requested via JNDI. The details of how this happens are
not important(if they are to you, look at the code). All we care about is that with
the
JaasSecurityManagerService setup, any lookup on the JBoss server JNDI InitialContext
using a name of the form java:/jaas/xyz results in an object of type
org.jboss.security.plugins.JaasSecurityManager that has the name xyz. Translated to
code,
this means:
</p><pre class="programlisting">
InitialContext ctx = new InitialContext();
JaasSecurityManager jsm1 = (JaasSecurityManager) ctx.lookup("java:/jaas/xyz");
String securityDomain = jsm1.getSecurityDomain();
// securityDomain == "xyz"
</pre><p>
where <tt>jsm1</tt> is an instance of JaasSecurityManager that was created
using the name "xyz".
We are using this feature to bind a single instance of JaasSecurityManager for
use as both the RealmMapping and EJBSecurityManager implementations in the preceeding
jboss.xml descriptor. We can do this because JaasSecurityManager implements both
interfaces. Now we need to know how we can actually authenticate users and specify
the
roles/identies they possess with a JaasSecurityManager.
</p></div></div><div class="section"><a name="jaas3"></a><div
class="titlepage"><div><h3 class="title"><a name="jaas3"></a><span class="title">Using
JaasSecurityManager</span></h3></div></div><p>
As you would expect, the JaasSecurityManager uses JAAS(Java Authentication and
Authorization Service) to implement both the user authentication and role mapping
function of the RealmMapping and EJBSecurityManager interfaces. It does this by
creating
a JAAS Subject using the javax.security.auth.login.LoginContext mechanism. When
the JaasSecurityManager needs to authenticate a user, it does a JAAS
login using the following programmatic steps:
</p><pre class="programlisting">
Principal principal = ... passed in by SecurityInterceptor;<a
name="jaas.principal"></a><img border="0" alt="1" src="./images/callouts/1.png">
Object credential = ... passed in by SecurityInterceptor;<a
name="jaas.credential"></a><img border="0" alt="2" src="./images/callouts/2.png">
/* Access the security domain to which the security manager is bound. This is
the xyz component of java:/jaas/xyz name used when defining the security-domain
or role-mapping-manager config elements. */
String name = getSecurityDomain();
CallbackHandler handler = new
org.jboss.security.plugins.SecurityAssociationHandler();
handler.setSecurityInfo(principal, credential);
LoginContext lc = new LoginContext(name, handler);
// Validate principal, credential using the LoginModules configured for 'name'
lc.login();
Subject subject = lc.getSubject();
Set subjectGroups = subject.getPrincipals(Group.class);
// Get the Group whose name is 'Roles'
Group roles = getGroup(subjectGroups, "Roles");
</pre><div class="calloutlist"><a name="N22a4"></a><table summary="Callout list"
border="0"><tr><td align="left" valign="top" width="5%"><a name="N22a6"></a><a
href="#jaas.principal"><img border="0" alt="1" src="./images/callouts/1.png"></a>
</td><td align="left" valign="top"><p>
A Principal is an identity object. Often it represents the username string,
but it can be an X509 cert, an http cookie, etc. This is ultimately passed to
the LoginModule chain and so the interpretation of what the Principal is
depends on the configured LoginModules for the security domain.
</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="N22ae"></a><a
href="#jaas.credential"><img border="0" alt="2" src="./images/callouts/2.png"></a>
</td><td align="left" valign="top"><p>
The credential is the value the principal is attempting to use to
verify his identity. It could be a password string or one-way has
of the password, a session key or token, etc.
This is ultimately passed to the LoginModule chain
and so the interpretation of what the credential is depends on the
configured LoginModules for the security domain.
</p></td></tr></table></div><p>
If your familiar JAAS, you'll see that the name that was used in the creation of
the JaasSecurityManager correlates with the LoginContext Configuration
name. The JAAS LoginContext object looks to a configuration object that is made up
of named sections that describe the LoginModules that need to be
executed in order to perform authentication. This abstraction allows the
authentication api to be independent of a particular implementation. The
authentication of users and the assignment of user roles comes down to
implementing a javax.security.auth.spi.LoginModule and creating login
configuration entry that correlates with the JaasSecurityManager name.
There exist a number of sample LoginModule implementation in the
org.jboss.security.plugins.samples package. We are going to use the
JaasServerLoginModule to demonstrate the how to configure a LoginModule to
work with the JaasSecurityManager. For your particular application you would
likely need different authentication and role mapping. You can choose another
LoginModule that integrates with your security environment, or implement you own
and then configure it using the same steps we will use.
</p><div class="section"><a name="N22ba"></a><div class="titlepage"><div><h4
class="title"><a name="N22ba"></a><span class="title">Using
JaasServerLoginModule</span></h4></div></div><p>
The JaasServerLoginModule class is a simple properties file based implemention
that uses two files(users.properties and roles.properities) to perform
authentication and role mapping respectively.
</p><div class="section"><a name="N22c1"></a><div class="titlepage"><div><h5
class="title"><a name="N22c1"></a><span
class="title">users.properties</span></h5></div></div><p>
The users.properties file is a java properties formatted file that specifies the
username to password mapping. Its format is:
<pre class="programlisting">
username1=password1
username2=password2
...
</pre>
with one entry per line.
</p></div><div class="section"><a name="N22ce"></a><div class="titlepage"><div><h5
class="title"><a name="N22ce"></a><span
class="title">roles.properties</span></h5></div></div><p>
The roles.properties file is a java properties formatted file that specifies
the username to role(s) mapping. Its format is:
<pre class="programlisting">
username1=role1[,role2,...]
username2=role1
...
</pre>
with one entry per line. If a user has multiple roles they are specified using a
comma separated list.
</p></div><div class="section"><a name="N22db"></a><div class="titlepage"><div><h5
class="title"><a name="N22db"></a><span class="title">The LoginModule Configuration
File</span></h5></div></div><p>
By default JAAS uses a LoginModule configuration file to describe which
LoginModule instances need to be executed during a login. The default
config for the JBoss server is ${jboss_home)/conf/default/auth.conf.
The syntax is:
<pre class="synopsis">
name {
login_module_class_name (required|optional|...)
[options]
;
};
</pre>
See the JAAS documentation for the complete syntax description. In the JBoss server
auth.conf file there should be an entry like 'other' in the figure below.
Also shown is a 'session-roles' entry that we have added that specfies two
login modules.
</p><div class="figure"><p><a name="auth.conf"></a><b>Figure 9.2. The JBoss Server
JAAS Login Config File</b></p><pre class="programlisting">
// The default server login module
other {
// A realistic server login module...
org.jboss.security.plugins.samples.JaasServerLoginModule required;
};
// Augment the JaasServerLoginModule roles with a CallerPrincipal mapping
// using the RolesLoginModule
session-roles {
org.jboss.security.plugins.samples.JaasServerLoginModule required
password-stacking="useFirstPass"
;
org.jboss.security.plugins.samples.RolesLoginModule required
;
};
</pre></div><p>
This indicates that the JaasServerLoginModule we want to use is setup for
the configuration named 'other'. This name also matches name of the
security domain portion of the JNDI name java:/jaas/other, which is what
we want. Recall that we specified an different security domain for
the role-mapping-manager element for the stateless session bean container
configuration. We used java:/jaas/session-roles. When a user accesses a
stateless session bean, they will be authenticated by the login modules
configured for the 'session-roles' domain. Referring to Figure 1 shows
that both the JaasServerLoginModule and RolesLoginModule login modules
will be executed for perform the authentication in this domain.
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3
class="title"><a name="N22f7">Note</a></h3>The configuration named 'other' is used
JAAS whenever it can't find
an entry matching the name passed to the LoginContext constructor. So
if we had used a JNDI name like java:/jaas/global as the security-domain
configuration element, we would still be using the 'other' login configuration
entry unless there also happened to be a 'global' entry.
</div>
</p></div></div><p>
We have now touched on all of the JBoss security related elements we need to
configure to secure the deployment of EJBs.
Let's now put together two simple session beans that we will secure to
demonstrate how to use what we have gone over.
</p></div><div class="section"><a name="jaas4"></a><div class="titlepage"><div><h3
class="title"><a name="jaas4"></a><span class="title">The Session
Beans</span></h3></div></div><p>
The following figures give the code listings for the the home, remote
and bean classes for the simple stateless and stateful session beans we
are going to secure, along with a simple client that accesses instances
of the session beans.
</p><div class="figure"><p><a name="Session.java"></a><b>Figure 9.3. The Session
Beans Remote Interface</b></p><pre class="programlisting">
import javax.ejb.*;
import java.rmi.*;
public interface Session extends EJBObject
{
public String echo(String arg) throws RemoteException;
}
</pre></div><div class="figure"><p><a name="SessionHome.java"></a><b>Figure 9.4. The
Session Beans Home Interface</b></p><pre class="programlisting">
import javax.ejb.*;
import java.rmi.*;
public interface SessionHome extends EJBHome
{
public Session create() throws RemoteException, CreateException;
}
</pre></div><div class="figure"><p><a name="StatelessSessionBean.java"></a><b>Figure
9.5. The Stateless Session Bean</b></p><pre class="programlisting">
import java.rmi.RemoteException;
import java.security.Principal;
import javax.ejb.*;
/**
@ejbHome: SessionHome
@ejbRemote: Session
*/
public class StatelessSessionBean implements SessionBean
{
private SessionContext sessionContext;
public void ejbCreate() throws RemoteException, CreateException
{
System.out.println("StatelessSessionBean.ejbCreate() called");
}
public void ejbActivate() throws RemoteException
{
System.out.println("StatelessSessionBean.ejbActivate() called");
}
public void ejbPassivate() throws RemoteException
{
System.out.println("StatelessSessionBean.ejbPassivate() called");
}
public void ejbRemove() throws RemoteException
{
System.out.println("StatelessSessionBean.ejbRemove() called");
}
public void setSessionContext(SessionContext context) throws RemoteException
{
sessionContext = context;
}
public String echo(String arg)
{
System.out.println("StatelessSessionBean.echo, arg="+arg);
Principal p = sessionContext.getCallerPrincipal();
System.out.println("StatelessSessionBean.echo, callerPrincipal="+p);
return arg;
}
}
</pre></div><div class="figure"><p><a name="StatefulSessionBean.java"></a><b>Figure
9.6. The Stateful Session Bean</b></p><pre class="programlisting">
import java.rmi.RemoteException;
import java.security.Principal;
import javax.ejb.*;
/**
@ejbHome: SessionHome
@ejbRemote: Session
*/
public class StatefulSessionBean implements SessionBean
{
private SessionContext sessionContext;
public void ejbCreate() throws RemoteException, CreateException
{
System.out.println("StatefulSessionBean.ejbCreate() called");
}
public void ejbActivate() throws RemoteException
{
System.out.println("StatelessSessionBean.ejbActivate() called");
}
public void ejbPassivate() throws RemoteException
{
System.out.println("StatefulSessionBean.ejbPassivate() called");
}
public void ejbRemove() throws RemoteException
{
System.out.println("StatefulSessionBean.ejbRemove() called");
}
public void setSessionContext(SessionContext context) throws RemoteException
{
sessionContext = context;
}
public String echo(String arg)
{
System.out.println("StatefulSessionBean.echo, arg="+arg);
Principal p = sessionContext.getCallerPrincipal();
System.out.println("StatefulSessionBean.echo, callerPrincipal="+p);
return arg;
}
}
</pre></div><div class="figure"><p><a name="ejb-jar.xml"></a><b>Figure 9.7. The
ejb-jar Deployment Descriptor</b></p><pre class="programlisting">
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans
1.1//EN"
"http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">
<ejb-jar>
<display-name>SecurityTests</display-name>
<enterprise-beans>
<session>
<description>A trival stateless session echo
bean</description>
<ejb-name>StatelessSession</ejb-name>
<home>SessionHome</home>
<remote>Session</remote>
<ejb-class>StatelessSessionBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
<session>
<description>A trival stateful session echo
bean</description>
<ejb-name>StatefulSession</ejb-name>
<home>SessionHome</home>
<remote>Session</remote>
<ejb-class>StatelessSessionBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<security-role>
<role-name>Echo</role-name>
</security-role>
<method-permission>
<role-name>Echo</role-name>
<method>
<ejb-name>StatelessSession</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
<method-permission>
<role-name>Echo</role-name>
<method>
<ejb-name>StatefulSession</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
</assembly-descriptor>
</ejb-jar>
</pre></div><div class="figure"><p><a name="SessionClient.java"></a><b>Figure 9.8.
The Client</b></p><pre class="programlisting">
import java.io.IOException;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
/** Run with -Djava.security.auth.login.config=${jboss_home}/client/auth.conf
where ${jboss_home} is the location of your JBoss distribution.
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class SessionClient
{
static class AppCallbackHandler implements CallbackHandler
{
private String username;
private char[] password;
public AppCallbackHandler(String username, char[] password)
{
this.username = username;
this.password = password;
}
public void handle(Callback[] callbacks) throws
java.io.IOException, UnsupportedCallbackException
{
for (int i = 0; i < callbacks.length; i++)
{
if (callbacks[i] instanceof NameCallback)
{
NameCallback nc = (NameCallback)callbacks[i];
nc.setName(username);
}
else if (callbacks[i] instanceof PasswordCallback)
{
PasswordCallback pc = (PasswordCallback)callbacks[i];
pc.setPassword(password);
}
else
{
throw new UnsupportedCallbackException(callbacks[i],
"Unrecognized Callback");
}
}
}
}
public static void main(String args[]) throws Exception
{
try
{
if( args.length != 2 )
throw new IllegalArgumentException("Usage: username password");
String name = args[0];
char[] password = args[1].toCharArray();
AppCallbackHandler handler = new AppCallbackHandler(name, password);
LoginContext lc = new LoginContext("TestClient", handler);
System.out.println("Created LoginContext");
lc.login();
}
catch (LoginException le)
{
System.out.println("Login failed");
le.printStackTrace();
}
try
{
InitialContext iniContext = new InitialContext();
SessionHome home = (SessionHome) iniContext.lookup("StatelessSession");
System.out.println("Found StatelessSessionHome");
Session bean = home.create();
System.out.println("Created StatelessSession");
System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
bean.remove();
home = (SessionHome) iniContext.lookup("StatefulSession");
System.out.println("Found StatefulSessionHome");
bean = home.create();
System.out.println("Created StatefulSession");
System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
bean.remove();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
</pre></div><p>
The session beans are trivial and both the stateless and stateful bean use the
same home and remote interfaces. The client is also trivial except for the use
of a JAAS LoginContext and CallbackHandler implementation. This is how a client
establishes the username and password that is sent to jboss.
Now, finally let's put everything together and deploy the session bean.
</p></div><div class="section"><a name="jaas5"></a><div class="titlepage"><div><h3
class="title"><a name="jaas5"></a><span class="title">Deploying a Bean with
Security</span></h3></div></div><p>
This section details the procedure for building, deploying and testing
the secured ejb-jar.
The steps I'll go through are on a windows 2000 box using the cygwin port
of the GNU tools, so most things will look like unix with the exception of
the ';' path separator used in the java classpath.
</p><div class="procedure"><p><b>Deployment Steps</b></p><ol><li><p>Compile the
session bean and client
</p><ol><li><p>Save all of the files presented in the figures of this document:
<div class="itemizedlist"><ul><li><p><a name="N2382"></a><a
href="#jboss.xml">jboss.xml</a></p></li><li><p><a name="N2389"></a><a
href="#auth.conf">auth.conf</a></p></li><li><p><a name="N2390"></a><a
href="#Session.java">Session.java</a></p></li><li><p><a name="N2397"></a><a
href="#SessionHome.java">SessionHome.java</a></p></li><li><p><a name="N239e"></a><a
href="#StatelessSessionBean.java">StatelessSessionBean.java</a></p></li><li><p><a
name="N23a5"></a><a
href="#StatefulSessionBean.java">StatefulSessionBean.java</a></p></li><li><p><a
name="N23ac"></a><a href="#ejb-jar.xml">ejb-jar.xml</a></p></li><li><p><a
name="N23b3"></a><a
href="#SessionClient.java">SessionClient.java</a></p></li></ul></div>
This will give you the following 8 files:
</p><div class="literallayout"><br>
<b><br>
howto-jaas 1053>ls<br>
Session.java StatefulSessionBean.java ejb-jar.xml<br>
SessionClient.java StatelessSessionBean.java jboss.xml<br>
SessionHome.java auth.conf<br>
</b></div></li><li><p>Create a users.properties and
roles.properties with the following
data in each file: </p><div class="literallayout"><br>
<b><br>
bash 1090>cat users.properties<br>
scott=echoman<br>
stark=javaman<br>
bash 1091>cat roles.properties<br>
scott=Echo<br>
stark=Java,Coder<br>
scott.CallerPrincipal=caller_scott<br>
stark.CallerPrincipal=caller_stark<br>
bash 1092><br>
<br>
</b></div></li><li><p>
Next, setup the classpath as follows by substituting the value for jboss_home
appropriate for your system. For example, I'm using jboss_home is a
fresh build from cvs and jboss_home=/tmp/cvs/jboss/dist.
</p><div class="literallayout"><b><br>
howto-jaas 1055>export jboss_home=/tmp/cvs/jboss/dist<br>
howto-jaas 1056>export CLASSPATH="${jboss_home}/client/jaas.jar"<br>
howto-jaas 1057>CLASSPATH="${CLASSPATH};${jboss_home}/client/ejb.jar"<br>
howto-jaas 1058>CLASSPATH="${CLASSPATH};${jboss_home}/client/jnp-client.jar"<br>
howto-jaas 1059>CLASSPATH="${CLASSPATH};${jboss_home}/client/jboss-client.jar"<br>
howto-jaas 1060>CLASSPATH="${CLASSPATH};${jboss_home}/client/jbosssx-client.jar"<br>
howto-jaas 1061>CLASSPATH="${CLASSPATH};."<br>
howto-jaas 1062>echo $CLASSPATH<br>
/tmp/cvs/jboss/dist/client/jaas.jar;/tmp/cvs/jboss/dist/client/ejb.jar;/tmp/cvs/jboss/dist/client/jnp-client.jar;/tmp/cvs/jboss/dist/client/jboss-client.jar;/tmp/cvs/jboss/dist/client/jbosssx-client.jar;.<br>
</b></div></li><li><p>Next, compile all of the source.
</p><div class="literallayout"><b><br>
howto-jaas 1087>javac -g *.java<br>
howto-jaas 1088>ls<br>
Session.class StatefulSessionBean.java<br>
Session.java StatelessSessionBean.class<br>
SessionClient$AppCallbackHandler.class StatelessSessionBean.java<br>
SessionClient.class auth.conf<br>
SessionClient.java ejb-jar.xml<br>
SessionHome.class jboss.xml<br>
SessionHome.java roles.properties<br>
StatefulSessionBean.class users.properties<br>
</b></div></li></ol></li><li><p>Create the session bean
ejb-jar with the ejb-jar.xml and jboss.xml security
elements</p><p>Next, create the session bean jar as follows:</p><ol><li><div
class="literallayout"><b><br>
howto-jaas 1089>mkdir META-INF<br>
howto-jaas 1090>mv *.xml META-INF<br>
howto-jaas 1091>jar -cf $jboss_home/deploy/ssbean.jar Session.class SessionHome.class StatefulSessionBean.class StatelessSessionBean.class roles.properties users.properties META-INF<br>
howto-jaas 1092>jar -tf $jboss_home/deploy/ssbean.jar<br>
META-INF/<br>
META-INF/MANIFEST.MF<br>
Session.class<br>
SessionHome.class<br>
StatefulSessionBean.class<br>
StatelessSessionBean.class<br>
roles.properties<br>
users.properties<br>
META-INF/ejb-jar.xml<br>
META-INF/jboss.xml<br>
</b></div></li></ol></li><li><p>Deploy the session bean jar.
We already deployed the session bean jar by
jaring the files to the $jboss_home/deploy directory. The deploy directory is
where the JBoss server's autodeploy process looks for ejb jars.
</p></li><li><p>Edit the JBoss server jboss.jcml and auth.conf files.
These files need to be setup as described earlier.</p><ol><li><p>The
$jboss_home/conf/default/jboss.jcml file needs to have the
JaasSecurityManagerService mbean element setup as follows:</p><pre
class="programlisting">
<!-- JAAS security manager and realm mapping -->
<mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
name="Secuty:name=JaasSecurityManager">
<attribute
name="SecurityManagerClassName">org.jboss.security.plugins.JaasSerityManager</attribute>
</mbean>
</pre></li><li><p>Copy the auth.conf that you created from Figure <a
href="#auth.conf">Figure 9.2.</a> to
$jboss_home/conf/default and overwrite the existing file.</p><div
class="literallayout"><tt><br>
howto-jaas 1103>cp auth.conf $jboss_home/conf/default<br>
cp: overwrite '/tmp/cvs/jboss/dist/conf/default/auth.conf'? y<br>
</tt></div></li></ol></li><li><p>Start the JBoss server.
Go to the $jboss_home/bin directory and use the run.sh or run.bat script as
appropriate for you system to start the JBoss server. You will see a good
deal of ouput on your console. Below is some console output and I have
emphasized the session bean deployment output.
</p><div class="literallayout"><tt><br>
bin 608>run.bat<br>
Using configuration "default"<br>
[Info] Java version: 1.3.0_01,Sun Microsystems Inc.<br>
[Info] Java VM: Java HotSpot(TM) Client VM 1.3.0_01,Sun Microsystems Inc.<br>
[Info] System: Windows 2000 5.0,x86<br>
[Shutdown] Shutdown hook added<br>
[Service Control] Registered with server<br>
[Service Control] Initializing 24 MBeans<br>
...<br>
<i><br>
[Auto deploy] Starting<br>
[Auto deploy] Watching D:\tmp\cvs\jboss\dist\deploy<br>
[Auto deploy] Auto deploy of file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar<br>
[J2EE Deployer Default] Deploy J2EE application: file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar<br>
[J2EE Deployer Default] Create application ssbean.jar<br>
[J2EE Deployer Default] install module ssbean.jar<br>
[Container factory] Deploying:file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar<br>
[Verifier] Verifying file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar/ejb1001.jar<br>
[Container factory] Deploying StatelessSession<br>
[Container factory] lookup securityManager name: java:/jaas/other<br>
[Container factory] JAAS.Created securityMgr=org.jboss.security.plugins.JaasSecurityManager@5f1832<br>
[Container factory] JAAS.setCachePolicy, c=null<br>
[Container factory] JAAS.Added other, org.jboss.security.plugins.JaasSecurityManager@5f1832 to map<br>
[Container factory] JAAS.Created securityMgr=org.jboss.security.plugins.JaasSecurityManager@2d8659<br>
[Container factory] JAAS.setCachePolicy, c=null<br>
[Container factory] JAAS.Added session-roles, org.jboss.security.plugins.JaasSecurityManager@2d8659 to map<br>
[Container factory] Deploying StatefulSession<br>
[Container factory] lookup securityManager name: java:/jaas/other<br>
[Bean Cache] Cache policy scheduler started<br>
[Container factory] Deployed application: file:/D:/tmp/cvs/jboss/dist/tmp/deploy/Default/ssbean.jar<br>
[J2EE Deployer Default] J2EE application: file:/D:/tmp/cvs/jboss/dist/deploy/ssbean.jar is deployed.<br>
</i><br>
...<br>
[Service Control] Started 24 services<br>
[Default] JBoss PRE-2.1 Started in 0m:10s<br>
</tt></div></li><li><p>Setup client env and test access to the session bean</p><p>
At this point the session bean is deployed and it should only be accessible by
users with a role of 'Echo', and we have one user with a username 'scott'
and a password 'echoman' that has this role. We have another user with a
username 'stark' and a password 'javaman' that should not be able to
acccess the session bean because he does not have the required role. We
need to setup the client env and run the client to test this.
</p><ol><li><p>
We need one final bit of information in order for the client to find the JBoss
server
JNDI name service. Since we are using a no arg InitialContext in the
client, we need a jndi.properties file in our classpath(or we need to specify all
required properities on the command line). For JBoss, the jndi.properties
file should look like the following for the server running on the localhost with
the default name service port: </p><div class="literallayout"><tt><br>
bash 1108>cat jndi.properties<br>
# JNDI initial context properties for jboss app server<br>
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory<br>
java.naming.provider.url=localhost<br>
java.naming.factory.url.pkgs=org.jboss.naming<br>
</tt></div><p>
Create this file in the same directory as your SessionClient.java file since
this directory is on the classpath we setup earlier.</p></li><li><p>Now, run the
client as user scott and specify the location of
the JBoss client side JAAS login configuration file as follows: </p><div
class="literallayout"><tt><br>
--- Client:<br>
howto-jaas 1133>java -Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient scott echoman<br>
Created LoginContext<br>
Found StatelessSessionHome<br>
Created StatelessSession<br>
Bean.echo('Hello') -> Hello<br>
Found StatefulSessionHome<br>
Created StatefulSession<br>
Bean.echo('Hello') -> Hello<br>
<br>
--- Server console:<br>
[JAASSecurity] User 'scott' authenticated.<br>
[JAASSecurity] User 'scott' authenticated.<br>
[StatelessSession] StatelessSessionBean.ejbCreate() called<br>
[StatelessSession] StatelessSessionBean.echo, arg=Hello<br>
[StatelessSession] StatelessSessionBean.echo, callerPrincipal=caller_scott<br>
[StatefulSession] StatelessSessionBean.ejbCreate() called<br>
[StatefulSession] StatelessSessionBean.echo, arg=Hello<br>
[StatefulSession] StatelessSessionBean.echo, callerPrincipal=scott<br>
[StatefulSession] StatelessSessionBean.ejbRemove() called<br>
</tt></div></li><li><p>Ok, so that succeed as desired. Now
we need to make sure that unauthorized
users are actually denied access. This time run as user stark:</p><div
class="literallayout"><tt><br>
--- Client:<br>
howto-jaas 1135>java -Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient stark javaman<br>
Created LoginContext<br>
Found StatelessSessionHome<br>
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:<br>
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:<br>
<br>
java.lang.SecurityException: Illegal access exception<br>
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:<br>
java.lang.SecurityException: Illegal access exception<br>
java.lang.SecurityException: Illegal access exception<br>
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:245)<br>
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:220)<br>
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:122)<br>
at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invokeHome(Unknown Source)<br>
at org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:248)<br>
at $Proxy0.create(Unknown Source)<br>
at SessionClient.main(SessionClient.java:74)<br>
<br>
--- Server console:<br>
[JAASSecurity] User 'stark' authenticated.<br>
[JAASSecurity] User 'stark' authenticated.<br>
[StatelessSession] Illegal access, principal=stark<br>
</tt></div></li><li><p>Alright, seems secure. Let's try user
scott with an invalid password: </p><div class="literallayout"><tt><br>
--- Client:<br>
howto-jaas 1137>java -Djava.security.auth.login.config=file://${jboss_home}/client/auth.conf SessionClient scott badpass<br>
Created LoginContext<br>
Found StatelessSessionHome<br>
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:<br>
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:<br>
<br>
java.lang.SecurityException: Authentication exception<br>
java.rmi.RemoteException: checkSecurityAssociation; nested exception is:<br>
java.lang.SecurityException: Authentication exception<br>
java.lang.SecurityException: Authentication exception<br>
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:245)<br>
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:220)<br>
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:122)<br>
at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invokeHome(Unknown Source)<br>
at org.jboss.ejb.plugins.jrmp.interfaces.HomeProxy.invoke(HomeProxy.java:248)<br>
at $Proxy0.create(Unknown Source)<br>
at SessionClient.main(SessionClient.java:74)<br>
<br>
--- Server console:<br>
[JAASSecurity] Bad password.<br>
[StatelessSession] javax.security.auth.login.FailedLoginException: Password Incorrect/Password Required<br>
[StatelessSession] at org.jboss.security.plugins.AbstractServerLoginModule.login(AbstractServerLoginModule.java:141)<br>
[StatelessSession] at org.jboss.security.plugins.samples.JaasServerLoginModule.login(JaasServerLoginModule.java:94)<br>
[StatelessSession] at java.lang.reflect.Method.invoke(Native Method)<br>
[StatelessSession] at javax.security.auth.login.LoginContext.invoke(LoginContext.java:595)<br>
[StatelessSession] at javax.security.auth.login.LoginContext.access$000(LoginContext.java:125)<br>
[StatelessSession] at javax.security.auth.login.LoginContext$3.run(LoginContext.java:531)<br>
[StatelessSession] at java.security.AccessController.doPrivileged(Native Method)<br>
[StatelessSession] at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:528)<br>
[StatelessSession] at javax.security.auth.login.LoginContext.login(LoginContext.java:449)<br>
[StatelessSession] at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:291)<br>
[StatelessSession] at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:260)<br>
[StatelessSession] at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:149)<br>
[StatelessSession] at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:196)<br>
[StatelessSession] at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:131)<br>
[StatelessSession] at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:106)<br>
[StatelessSession] at org.jboss.ejb.StatelessSessionContainer.invokeHome(StatelessSessionContainer.java:253)<br>
[StatelessSession] at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invokeHome(JRMPContainerInvoker.java:358)<br>
[StatelessSession] at java.lang.reflect.Method.invoke(Native Method)<br>
[StatelessSession] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)<br>
[StatelessSession] at sun.rmi.transport.Transport$1.run(Transport.java:142)<br>
[StatelessSession] at java.security.AccessController.doPrivileged(Native Method)<br>
[StatelessSession] at sun.rmi.transport.Transport.serviceCall(Transport.java:139)<br>
[StatelessSession] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)<br>
[StatelessSession] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)<br>
[StatelessSession] at java.lang.Thread.run(Thread.java:484)<br>
[StatelessSession] Authentication exception, principal=scott<br>
</tt></div></li></ol></li></ol></div></div><div
class="section"><a name="N24c9"></a><div class="titlepage"><div><h3 class="title"><a
name="N24c9"></a><span class="title">Wrap Up</span></h3></div></div><p>This has been
an introduction to the steps required to enable security
for EJB containers. Support for more advanced customization of security is
documented in the JBossSX chapter.
</p></div></div><div class="section"><a name="N24d2"></a><div
class="titlepage"><div><h2 class="title" style="clear: all"><a name="N24d2"></a><span
class="title">Using JavaMail in JBoss</span></h2></div></div><p>
<span class="author">Michel de Groot</span>
<tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N24e2"></a><div class="titlepage"><div><h3
class="title"><a name="N24e2"></a><span
class="title">Introduction</span></h3></div></div><p>
JBoss has a built-in implementation of the JavaMail API. You can use this
service from inside and outside EJBs. We
describe here how to use the service. </p></div><div class="section"><a
name="N24ea"></a><div class="titlepage"><div><h3 class="title"><a
name="N24ea"></a><span class="title">Installation &
Configuration</span></h3></div></div><div class="orderedlist"><ol type="1"><li><p><a
name="N24f4"></a>Edit conf/<yourconfig>/jboss.jcml and find Mail
Service MBean (almost on the bottom).</p><p>
a) Replace the User and Password attributes values with the user name and
password used to connect to your
mail server. You can find these values in your mail program. The mail
service will use this account to send mails,
so be sure that this mail account works properly (test it with your mail
program for example).</p><p>
b) Replace the ConfigurationFile attribute value with the file containing
the mail settings. Default is
"mail.properties", which is also in the conf/<yourconfig>
directory. This file will be edited in step 2.</p><p>
c) Replace the JNDIName attribute value with the JNDI name for your mail
session. The default is "Mail". This
JNDI name will be used in jboss.xml to identify the resource. This is
explained in more detail in step 4.</p></li><li><p><a name="N2502"></a>Edit the mail
properties file you identified in step 1b. By
default, this is conf/<yourconfig>/mail.properties.</p><p>
Edit the following lines:
<pre class="programlisting">
mail.user = sa005697 // the user to connect with; same as in step 1a
mail.pop3.host = pop3.wolmail.nl // the pop host to store the mail
on
mail.smtp.host = smtp.wolmail.nl // the smtp host to send the mail
to
mail.from = [EMAIL PROTECTED] // the 'from' field that is
filled in by default in e-mails
</pre>
</p><p>
You can find most value in your mail program. You might want to inspect
the JavaMail specification for more
details.</p><p>
The last line, mail.debug, should be set to 'true' for now. This will
provide you with verbose debugging
information. Once you have everything running correctly, you can set it
to false.</p></li><li><p><a name="N2515"></a>Edit the ejb-jar.xml of the EJB that
uses the mail service.
In your EJB, specify a <resource-ref> like this:
<pre class="programlisting">
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Mailer</ejb-name>
<home>some.package.MailerHome</home>
<remote>some.package.Mailer</remote>
<ejb-class>some.package.MailerEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>mail/MyMail</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</session>
</enterprise-beans>
</ejb-jar>
</pre>
</p><p>
This will tell the EJB container that the EJB uses a javax.mail.Session
resource named mail/MyMail and that
authorization is container managed.</p><p>
You can change the name if you like, but be sure to use the same name in
step 6, in the code example. </p></li><li><p><a name="N2525"></a>Edit the jboss.xml
of the EJB that uses the mail service.
If you don't have this file, create it and place it in the
same directory as the ejb-jar.xml of the EJB. This file is JBoss specific
and tells JBoss how to map the mail
resource to the mail service provider in JBoss.
In this file, specify a <resource-manager> like this:
<pre class="programlisting">
<jboss>
<resource-managers>
<resource-manager>
<res-name>mail/MyMail</res-name>
<res-jndi-name>Mail</res-jndi-name>
</resource-manager>
</resource-managers>
</jboss>
</pre>
</p><p>
The name that you specify here is the name that you specified in step 3.
The JNDI name that you specify here is
the name that you specified in step 1c.</p></li><li><p><a name="N2532"></a>Edit
the bin/run.bat file of your JBoss installation.
Include ../lib/ext/mail.jar and ../lib/ext/activation.jar in the
classpath explicitly. This assumes that you start JBoss from the bin
directory. If not, you should modify the paths
to the jars accordingly.</p><p>
TO BE IMPROVED: This step should not be required; both mail.jar and
activation.jar are correctly found during
the ClassPathExtension scan, but somehow their classes cannot be found
later. Maybe something missing in the
manifest.mf files? </p></li><li><p><a name="N253a"></a>Code example
This code example assumes that you are working from inside a JBoss
container. For example, this is the case if
the code is placed in a JBoss managed SessionBean.</p><p>
TO BE IMPROVED: This code example does not use PortableRemoteObject,
because I could not locate it
anywhere in the JBoss jars. The code will work without it on JBoss. It
should be used however to make the
code more portable. I'm also not sure what happens in a distributed JBoss
installation. </p><pre class="programlisting">
import java.util.Date;
import javax.ejb.SessionBean;
import javax.naming.InitialContext;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.InternetAddress;
import javax.mail.Transport;
import javax.mail.Address;
import javax.mail.Message;
//import javax.rmi.PortableRemoteObject;
public class SomeEJB implements SessionBean {
public void ejbCreate() {}
public void ejbPostCreate() {}
public void sendMails() throws java.rmi.RemoteException {
Session session = null;
try {
session = (Session)new
InitialContext().lookup("java:comp/env/mail/MyMail");
//session = (Session)PortableRemoteObject.narrow(
// new
InitialContext().lookup("java:comp/env/mail/MyMail"), Session.class);
} catch (javax.naming.NamingException e) {
e.printStackTrace();
}
try {
MimeMessage m = new MimeMessage(session);
m.setFrom();
Address[] to = new InternetAddress[] {new
InternetAddress("<your_email_adres@<your_provider>.<your_extension>");
m.setRecipients(Message.RecipientType.TO, to);
m.setSubject("JavaMail Test");
m.setSentDate(new Date());
m.setContent("Test from inside EJB Using JBoss",
"text/plain");
Transport.send(m);
} catch (javax.mail.MessagingException e) {
e.printStackTrace();
}
}
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbRemove() {}
public void setSessionContext(javax.ejb.SessionContext ec) {}
}
</pre></li><li><p><a name="N2547"></a>Using the JavaMail service with mail
servers that require
POP authentication before SMTP
You can do this by using: </p><pre class="programlisting">
import javax.mail.Store;
Store s = session.getStore();
s.connect(); // POP authentication
Transport.send(m);
</pre></li></ol></div></div></div><div class="section"><a
name="N2554"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N2554"></a><span class="title">How to Run JBoss in JBuilder's
Debugger</span></h2></div></div><div class="section"><a name="N2558"></a><div
class="titlepage"><div><h3 class="title"><a name="N2558"></a><span
class="title">JBuilder Foundation 3.5</span></h3></div></div><p>
With each of these, replace <JBOSS-HOME> with the location of your JBoss
directory, for example, C:\jboss.</p><div class="orderedlist"><ol type="1"><li><p><a
name="N2565"></a>Launch JBuilder.</p></li><li><p><a name="N2569"></a>Go to
Project|Properties, click the Paths tab, and make sure you're using JDK 1.3 as your
JDK. To have 1.3 available, you
may need to add it or change your default JDK. First install JDK 1.3 (from
Sun) on your PC, then point JBuilder to it by
clicking "new" or "edit" in the Select a JDK dialog.</p></li><li><p><a
name="N256d"></a>On the Paths tab, go to the Required Libraries tab, click "add" and
then "new" to create a new one, and call it "JBoss Server"
(or something similar). Add the following .jar file:
<JBOSS-HOME>\bin\run.jar </p></li><li><p><a name="N2571"></a>Click
OK on the Edit library dialog, then OK on the Select one or more libraries dialog,
which should add the new library to
your project. The library will now be available to other projects as
well.</p></li><li><p><a name="N2575"></a>Go to the Run tab of the Project Properties
dialog. On the Application tab, set the main class to org.jboss.Main. Note that this
is project-specific and will need to be done for each project running JBoss.
</p></li><li><p><a name="N2579"></a>On the Run tab, under "VM Parameters", add the
following (again, for each project):
-Duser.dir=<JBOSS-HOME> </p></li><li><p><a name="N257d"></a>Click
OK and close JBuilder.</p></li><li><p><a name="N2581"></a>Create a copy of your
JBuilder shortcut (in Win98, it should be in C:\WINDOWS\Start Menu\Programs\JBuilder
3.5). Rename
the copy to something appropriate, such as "JBuilder with JBoss working
directory". </p></li><li><p><a name="N2585"></a>Edit the shortcut's properties by
right-clicking and choosing properties. Change the "Start in" folder to
<JBOSS-HOME>\bin\. Click OK. </p></li><li><p><a name="N2589"></a>To run
or debug JBoss within JBuilder, first use the modified shortcut to launch JBuilder,
then open your project as normal and
select Run|Run Project or Run|Debug Project. </p></li><li><p><a
name="N258d"></a>To debug EJBs within this setup, first build and deploy them in
<JBOSS-HOME>\deploy as you would normally. Then set
breakpoints in your EJB code and debug the project using org.jboss.Main as the
main class using the instructions above. </p></li></ol></div><p>
NOTE: When running JBoss within JBuilder, it will launch an empty console window
with "java" as the title. I'm not sure why this is,
but it appears to have some relation to Hypersonic SQL. You will probably need to
close this window manually after stopping JBoss.
</p></div><div class="section"><a name="N2596"></a><div class="titlepage"><div><h3
class="title"><a name="N2596"></a><span class="title">JBuilder
4</span></h3></div></div><p>
Author: Peter Henderson
</p><div class="orderedlist"><ol type="1"><li><p><a name="N25a3"></a>Project
Properties. (Project properties/paths)
Set the working directory to the JBoss bin dir. For example:
C:/jboss_tomcat/jboss-2.0-FINAL/bin</p></li><li><p><a name="N25a7"></a>Set
VM parameters. (Project properties/run)
-classic -Dtomcat.home=C:\jboss_tomcat\tomcat-3.2-b7
-Duser.dir=C:\jboss_tomcat\jboss-2.0-FINAL/bin </p></li><li><p><a name="N25ab"></a>Set
Main class
Set main class to org.jboss.Main </p></li><li><p><a name="N25af"></a>Create a
JBoss Server Library. (Project properties/required libs) </p><p>Add: </p><pre
class="programlisting">
/jboss_tomcat/jboss-2.0-FINAL/bin/run.jar
/jboss_tomcat/jboss-2.0-FINAL/bin
/jboss_tomcat/jboss-2.0-FINAL/conf
/jboss_tomcat/jboss-2.0-FINAL/lib/jaas.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/jboss-jaas.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/jdbc2_0-stdext.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/jmxri.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/xml.jar
/jboss_tomcat/tomcat-3.2-b7/lib/servlet.jar
/jboss_tomcat/tomcat-3.2-b7/lib/jaxp.jar
/jboss_tomcat/tomcat-3.2-b7/lib/webserver.jar
/jboss_tomcat/tomcat-3.2-b7/lib/parser.jar
/jboss_tomcat/tomcat-3.2-b7/lib/jasper.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/activation.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/awt.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/dynaserver.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejb.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejxeditor.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejxejb.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejxjaws.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/ejxjboss.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/hsql.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/idb.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jboss.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jetty-service.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jms.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jmxtools.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jndi.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jnpserver.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jpl-util-0_5b.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/jta-spec1_0_1.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/mail.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/spydermq.jar
/jboss_tomcat/jboss-2.0-FINAL/lib/ext/tomcat-service.jar
/jboss_tomcat/jboss-2.0-FINAL/db
/jboss_tomcat/jboss-2.0-FINAL/log
/jboss_tomcat/jboss-2.0-FINAL/conf/tomcat
</pre><p>
Also the source dir for jboss sources should be set to:
/jboss_tomcat/jboss-2.0-FINAL/src
</p></li><li><p><a name="N25be"></a>Add JBoss Server Library to your project.
</p></li><li><p><a name="N25c2"></a>Rebuild all. </p></li><li><p><a
name="N25c6"></a>Deploy your application.
Copy your jar to the jboss/deploy dir </p></li></ol></div><p>
If all is well, you should be able to set break points etc and single step your
code. </p><p>
Notes
Do NOT include the Sun J2EE SDK jars in your project. </p></div></div><div
class="section"><a name="N25d3"></a><div class="titlepage"><div><h2 class="title"
style="clear: all"><a name="N25d3"></a><span class="title">EJX/AWT Development
HowTo</span></h2></div></div><p>Author:
<span class="author">Andreas Shaefer</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N25e3"></a><div class="titlepage"><div><h3
class="title"><a name="N25e3"></a><span
class="title">Introduction</span></h3></div></div><p>
This How To serie is about how to develop EJX plugins with the help of
Rickard's AWT, XML and
BeanContext and NOT about how to use EJX and its plugins (at least for
now)!! </p><div class="orderedlist"><ol type="1"><li><p><a name="N25f0"></a><a
href="#ejx1">Insights to EJX internals by Simon Bordet</a></p></li><li><p><a
name="N25f7"></a><a href="#ejx2">Getting started with EJX</a></p></li><li><p><a
name="N25fe"></a><a href="#ejx3">GUI Basics</a></p></li></ol></div><p>
Next steps
</p><div class="orderedlist"><ol type="1"><li><p><a name="N260f"></a>How to
use resources (especially XML files) in EJX </p></li><li><p><a
name="N2613"></a>Advanced GUIs </p></li></ol></div></div><div class="section"><a
name="ejx1"></a><div class="titlepage"><div><h3 class="title"><a name="ejx1"></a><span
class="title">EJX Insights</span></h3></div></div><p>EJX (created by Rickard
֢erg and are available at his DreamBean Website: www.dreambean.com) is a
launcher for JavaBean plugins
that are written following the Glasgow specification, in particular the Extensible
Runtime Containment and Services Protocol. This
document is intended for programmers that want to write plugins for EJX, and will
(try to) explain the insights of the bean context
hierarchy of EJX, and also classloader issues regarding this hierarchy.
</p></div><div class="section"><a name="N2623"></a><div class="titlepage"><div><h3
class="title"><a name="N2623"></a><span class="title">The
launcher</span></h3></div></div><p>
com.dreambean.ejx.editor.Main is the launcher for EJX. It does the following:
</p><div class="orderedlist"><ol type="1"><li><p><a name="N2630"></a>creates a new
URLClassLoader, whose parent is the current context classloader </p></li><li><p><a
name="N2634"></a>all files under ../lib and ../lib/ext are added to this
URLClassLoader (PENDING: really all files or only jars) </p></li><li><p><a
name="N2638"></a>the context class loader is set to this URLClassLoader
</p></li><li><p><a name="N263c"></a>the class com.dreambean.ejx.editor.EJX is
instantiated using the new context class loader (ie the URLClassLoader)
</p></li></ol></div><p>
All plugins you would like to show in the EJX framework must be under ../lib or
../lib/ext, so that their classes can be loaded through the
context class loader. If this is not the case, your plugin is not even shown in the
EJX first window, where you can choose, among the
available plugins, which one you want to use.</p><p>
Every EJX plugin is archived in a jar and must have an entry in the manifest file
that reads:</p><p>
EJX-plugin: <factory-class-name></p><p>
where <factory-class-name> is the fully qualified name of the
ResourceManagerFactory implementation that can instantiate the
ResourceManager implementation for that plugin.</p></div><div class="section"><a
name="N264e"></a><div class="titlepage"><div><h3 class="title"><a
name="N264e"></a><span class="title">The bean context
framework</span></h3></div></div><p>
Following the Glasgow specification, JavaBeans can be logically grouped in
containers, called BeanContext. A BeanContext can
contain other nested BeanContext, or directly BeanContextChild JavaBeans. While
normal JavaBeans can be added to BeanContexts,
to obtain the full potentiality of the new framework, they should implement the
BeanContextChild interface. A BeanContextChild is
normally a terminal child of the containment hierarchy, so it cannot have nested
JavaBeans. JavaBeans, being they BeanContext or
BeanContextChild can be added to or removed from a BeanContext, and notification of
these events is delivered to registered
membership listeners.</p><p>
A BeanContext can expose services to its children, services that can easily accessed
by them simply specifying the interface that
represent the wanted service. The interfaces that provides this support are
BeanContextServices and BeanContextServiceProvider.</p><p>
BeanContextServices is a BeanContext with the possibility to be queried for services
that it hosts. BeanContextServiceProvider is the
service hosted by a BeanContextServices. Services can be added or removed from a
BeanContextServices, and notification of these
events is delivered to registered service listeners.</p><p>
Within this framework, JavaBeans can obtain a reference to the BeanContext in which
they are hosted and thus be aware of the
environment in which they're running; plus they can query the BeanContext for
services, if the BeanContext hosting them is a
BeanContextServices. If this BeanContextServices does not have the requested
service, the request goes up in the hierarchy, eventually
finding the BeanContextServices that provides the service.</p></div><div
class="section"><a name="N265f"></a><div class="titlepage"><div><h3 class="title"><a
name="N265f"></a><span class="title">The bean context root and the
services</span></h3></div></div><p>
As you may have guessed, com.dreambean.ejx.editor.EJX is a BeanContextServices
instance, and is the root of the bean context
hierarchy of the application.</p><p>
It hosts 2 services: </p><div class="orderedlist"><ol type="1"><li><p><a
name="N266f"></a>a Preference service, used to store user preferences like screen size
</p></li><li><p><a name="N2673"></a>an XMLManager service, used to allow JavaBeans to
read from / write to XML files.</p></li></ol></div><p>
Direct children EJX are the plugins, that implements the ResourceManager interface.
ResourceManager extends BeanContextChild so
that implementors can be directly plugged in the containment hierarchy, but normally
implementors of the ResourceManager interface
implements BeanContextServices, to provide plugin-specific services to their nested
JavaBeans.</p><p>
PENDING: add a figure / schema of the containment tree with different colors
representing services</p></div><div class="section"><a name="N267f"></a><div
class="titlepage"><div><h3 class="title"><a name="N267f"></a><span class="title">Where
the GUI comes in ?</span></h3></div></div><p>
We saw the bean context hierarchy, but what you can see on the screen is not totally
related to it (though there is a relationship). How
can EJX show the GUI for JavaBeans component seamlessly ?</p><p>
Every JavaBean that wants to display a GUI in EJX must implement either
BeanContextContainerProxy or
BeanContextChildComponentProxy. </p><p>
com.dreambean.ejx.editor.EJX implements BeanContextContainerProxy and its
getContainer() method expose a JDesktopPane of a
JFrame (also held by com.dreambean.ejx.editor.EJX [NOTE: this JFrame is not exposed
(as of 15 Nov 2000), so it is not accessible from
nested JavaBeans if they want play with the menu bar. I have in mind to change this
and indirectly expose the JFrame as a EJX
service]).</p><p>
JDesktopPane is the specialized class that hosts JInternalFrames. Normally plugins
implement the BeanContextChildComponentProxy
interface returning a java.awt.Component (subclass) that can be added to a
JInternalFrame and finally added to the JDesktopPane.</p><p>
The difference between BeanContextChildComponentProxy and BeanContextContainerProxy
is that the former is implemented by
JavaBeans whose enclosing BeanContext is responsible to call getComponent and add
the resulting java.awt.Component to some
existing GUI, while the latter is implemented by JavaBeans whose enclosed JavaBeans
are responsible to call getContainer() and add to
this java.awt.Container GUI components taken from somewhere else. The former says "I
know my children, let's take their GUI
components and add them here", the latter says "I know my parent, let's add this GUI
components to its GUI container".</p></div><div class="section"><a
name="ejx2"></a><div class="titlepage"><div><h3 class="title"><a name="ejx2"></a><span
class="title">Getting strted with EJX</span></h3></div></div><div class="section"><a
name="N2699"></a><div class="titlepage"><div><h4 class="title"><a
name="N2699"></a><span class="title">Introduction</span></h4></div></div><p>
EJX/AWT written by Rickard ֢erg</p><p>
Both packages are created by Rickard ֢erg and are available at his
DreamBean Website: www.dreambean.com.
Both packages are heavily used in jBoss do create/maintain EJB descriptor
and other XML files.
The reason or motivation for me to write this HowTo was that I struggle to
understand EJX and AWT. On the
other hand Rickard was so busy with other stuff that I had to dig throug
myself and to save time for other
members of jBoss I started writing this HowTo. This document is still under
construction and will maybe never
be finished. </p><p> Idea of EJX</p><p>
EJX is a package and runtime environment enabling you to create a plugin to
add new functionality and new GUI
elements. EJX will dynamically lookup for plugins on the predefined package
/lib/ext and load them for you.
Whenever you create a new file or open a given file it will instantiate
your plugin and show as an Frame within
the EJX framework.
EJX uses XML but at the moment this is not quite clear for me but I am
working on it (AS 9/15/00), </p><p>
Idea of AWT</p><p>
AWT (or here called Advanced Window Toolkit and do not mix it up with
java.awt.*) enables you to use an
uniform GUI Environment and to use BeanContext with an easy to write XML
definition file.
I am still at the beginning to understand AWT and EJX but I will upgrade
this document as soon as I have more
information and examples. </p></div><div class="section"><a
name="N26b0"></a><div class="titlepage"><div><h4 class="title"><a
name="N26b0"></a><span class="title">Project</span></h4></div></div><div
class="section"><a name="N26b4"></a><div class="titlepage"><div><h5 class="title"><a
name="N26b4"></a><span class="title">Introduction</span></h5></div></div><p>
Based on the first draft of this document I separated the core EJX stuff from
the EJX examples to make it a little bit more
clear. Afterwards I implemented these changes in the EJX module of jBoss CVS
server. If you now download the EJX
module you can create a slim release of EJX without the examples. If you need
them you can just jump to the examples
directory and build the example from there (one by one) and only the examples
you want or need. </p></div><div class="section"><a name="N26bc"></a><div
class="titlepage"><div><h5 class="title"><a name="N26bc"></a><span
class="title">Structure</span></h5></div></div><p>
To go through this document download the EJX module from the jBoss CVS server.
Attention: Before you start with compiling any examples you have to run the
compilation of the core project first. For this
go to the "ejx/src/build" and start the build.bat file. This compiles the core
project, copies the necessary jar-files to the
right place and creates the necessary ejxeditor.jar file.
Now you are ready for the examples. </p></div><div class="section"><a
name="N26c4"></a><div class="titlepage"><div><h5 class="title"><a
name="N26c4"></a><span class="title">Plain Pane Example</span></h5></div></div><p>
This example can be found under "ejx/examples/plain.pane".
This was my first example and the goal was to creat a Panel within EJX
framework to display just a simple text. I used
this example to find simplest example within EJX.
According to the EJX spec the only necessary thing you have to to is: </p><div
class="orderedlist"><ol type="1"><li><p><a name="N26d1"></a>Create a class extending
the com.dreambean.ejx.FileManagerFactory interface </p></li><li><p><a
name="N26d5"></a>Create a class extending the com.dreambean.ejx.FileManager
interface</p></li><li><p><a name="N26d9"></a>Create an appropriate Manifest file with
looks like this for this example:
Class-Path: awt.jar ejb.jar EJX-plugin:
com.madplanet.plainPane.FileManagerFactoryImpl Name:
com/madplanet/plainPane/ Specification-Title: PlanePane
0.1 Specification-Version: v0.1 Specification-Vendor: MAD
plaNET plc Implementation-Title: ejx-plain-pane
Implementation-Version: build1 Implementation-Vendor: MAD
plaNET plc
</p></li><li><p><a name="N26dd"></a>Compile these two classes
</p></li><li><p><a name="N26e1"></a>Put these two classes and the Manifest file into a
jar-file (name does not matter but I always name
it this way: ejx.<ProjectName>.jar).</p></li><li><p><a
name="N26e5"></a>And last but not least the just created jar-file into the
ejx/dist/lib/ext directory. </p></li></ol></div><p>
Now the only thing left is to start EJX (go to ejx/dist/bin directory and
start EJX with "java -jar ejx.jar"). When the EJX
Frame comes up go to file/new and select "Plain Pane XML" and you will see our
plugin coming up.
Now let's have a closer look to the classes we created in our
plugin.</p></div><div class="section"><a name="N26ee"></a><div
class="titlepage"><div><h5 class="title"><a name="N26ee"></a><span
class="title">FileManagerFactoryImpl</span></h5></div></div><p>
Implements the com.dreambean.ejx.FileManagerFactory and enables the EJX
framework to select the right file for you.
But now let's delf into the code </p><p>
Classes to be imported </p><pre class="programlisting">
import java.io.File;
import javax.swing.filechooser.FileFilter;
import com.dreambean.ejx.FileManager;
import com.dreambean.ejx.FileManagerFactory;
</pre><p>
Class definition (to extend this class from FileFilter is just
convenience because it is needed either
way):</p><pre class="programlisting">
public class FileManagerFactoryImpl extends FileFilter
implements FileManagerFactory </pre><p>
These methods must be implement due FileManagerFactory interface.
The first method creates the
FileManager when a file is selected or in a given directory a new
one can be created. The second
method returns a FileFilter to select a file or directory and the
last is used to get a name for the
Plugin to select the right one. </p><pre class="programlisting">
public FileManager createFileManager() {
return new FileManagerImpl( this );
}
public FileFilter getFileFilter() {
return this;
}
public String toString(){
return "Plain Pane XML";
}
</pre></div><div class="section"><a
name="N270e"></a><div class="titlepage"><div><h5 class="title"><a
name="N270e"></a><span class="title">FileManagerImpl</span></h5></div></div><p>
Implements the com.dreambean.ejx.FileManager and enables the plugin to decide
what GUI element to display. For each
file or directory selected a new instance of this class is created. </p><p>
Classes to be imported </p><pre class="programlisting">
import java.awt.BorderLayout;
import java.awt.Component;
import java.beans.beancontext.BeanContextServicesSupport;
import java.io.File;
import javax.swing.JPanel;
import javax.swing.JLabel;
import com.dreambean.ejx.FileManager;
import com.dreambean.ejx.FileManagerFactory;
</pre><p>
I am only so pitty about what classes are imported to show you at
the header where the used
classes are coming from.
Constructor of the class: </p><pre class="programlisting">
FileManagerImpl( FileManagerFactory pCaller ) {
mFactory = pCaller;
}
</pre><p>
Methods must be overwriten by the class, The important part is the
getComponent() method which
is called by the EJX framework to get the GUI component to be
displayed. </p><pre class="programlisting">
public boolean isChanged() {
return true;
}
public void createNew() {
}
public void load( File file ) throws Exception {
}
public void save( File f ) throws Exception{
}
public File getFile() {
return null;
}
public void setFile( File pFile ) {
}
public FileManagerFactory getFactory() {
return mFactory;
}
public Component getComponent() {
JPanel lPane = new JPanel( new BorderLayout()
);
lPane.add( new JLabel(
"<HTML><BODY><H1>Hello
World</H1>"
+ "<H2>Next
Step</H2></BODY></HTML>" ),
BorderLayout.CENTER );
return lPane;
}
</pre></div><div class="section"><a name="N272e"></a><div
class="titlepage"><div><h5 class="title"><a name="N272e"></a><span
class="title">Simple Component Example</span></h5></div></div><p>
This example can be found under "ejx/examples/simple.component".
This example is an introduction to AWT and how it can be used to define a GUI
by the XML description file, compiled and
display on the Panel in the EJX framework. To shorten the further discussion I
only show the important stuff having
changed or is new. </p><p>
The only thing with AWT you have to consider is that you have to use XMLBeans
to compile the BeanInfo XML
description into a Java class and then to compile it to a java bytecode class.
For that have a look at the build.xml and look
for xmlbeans. </p><p>
According to the AWT spec the only necessary thing you have to to is:</p><div
class="orderedlist"><ol type="1"><li><p><a name="N2741"></a>Create an Bean Info XML
description file like this:
<bean class="com.madplanet.simpleComponent.MainPane"
displayname="Simple Component's Main Pane"
iconcolor16="/images/container.gif"> <property
name="FirstProperty" class="java.lang.String"
displayname="First Property"/> <property
name="SecondProperty" class="java.lang.String"
displayname="Second Property"/>
</p></li><li><p><a name="N2745"></a>Create a GUI component class and
add the GenericCustomizer to it (as parameter you have to
pass the class instance which is referred above (here it is
com.madplanet.singleComponent.MainPane). There are other classes
you can use but at the
moment I have no more informations. </p></li><li><p><a
name="N2749"></a>Compile all the java classes</p></li><li><p><a name="N274d"></a>User
XMLBeans to create the java sourcecode from the XML beaninfo. The newly created java
classes are named like the referred class but with Beaninfo at the
end (same package structure). </p></li><li><p><a name="N2751"></a>Compile the bean
info java sourcecode files. </p></li></ol></div><p>
That's it. </p></div><div class="section"><a name="N275a"></a><div
class="titlepage"><div><h5 class="title"><a name="N275a"></a><span
class="title">FileManagerImpl</span></h5></div></div><p>Like the one before except the
getComponent() method: </p><pre class="programlisting">
public Component getComponent() { // Create the Property Container and
return its GUI component return new MainPane().getComponent();
}
</pre></div><div class="section"><a name="N2767"></a><div
class="titlepage"><div><h5 class="title"><a name="N2767"></a><span
class="title">MainPane</span></h5></div></div><p> This class now creates the GUI
component using AWT to display the properties this class have.</p><p>
Classes to be imported </p><pre class="programlisting">
import java.awt.BorderLayout;
import java.awt.Component;
import java.beans.beancontext.BeanContextSupport;
import
java.beans.beancontext.BeanContextChildComponentProxy;
import javax.swing.JPanel;
import com.dreambean.awt.GenericCustomizer;
</pre><p>
This class has to supclass the BeanContextSupport </p><pre
class="programlisting">
public class MainPane extends BeanContextSupport </pre><p>
There are the properties the Main Pane offer and which can then be
set by GUI component defined
by the Bean Context Attention: All the properties in the BeanInfo
XML file need here a public
getter and setter method with the appropriate type. </p><pre
class="programlisting">
public String getFirstProperty() {
return mFirstProperty;
}
public void setFirstProperty( String pToSet ) {
mFirstProperty = pToSet;
}
public String getSecondProperty() {
return mSecondProperty;
}
public void setSecondProperty( String pToSet ) {
mSecondProperty = pToSet;
}
</pre><p>
This method returns the GUI component which contains the Generic
Customizer need to display
the properties of this instance accordingly to the Bean Info XML
description mentioned above.</p><pre class="programlisting">
public Component getComponent() {
JPanel lPane = new JPanel( new BorderLayout()
);
lPane.add( new GenericCustomizer( this ),
BorderLayout.CENTER );
return lPane;
}
</pre><p>
Eh voilଠthat's it. When you build this example, start EJX and select
Simple Component XML you will see two lines with
the tag "First Property" and a Text Field (and also for Second
Property).</p><p>
That's all for now. In the next step I will delf further into AWT and how you
can use the Bean Info XML description to
describe more advanced application. In addition I will then use the save() and
load() method to load XML files which are
the persistent part of a plugin. </p><p>
I anything is wrong or not correct please contact me at
[EMAIL PROTECTED] Also if you want to know more in
detail or have a request for changes in this HowTo document.
</p></div></div></div><div class="section"><a name="ejx3"></a><div
class="titlepage"><div><h3 class="title"><a name="ejx3"></a><span
class="title">EJX/AWT GUI Basics HowTo</span></h3></div></div><div class="section"><a
name="N27a0"></a><div class="titlepage"><div><h4 class="title"><a
name="N27a0"></a><span class="title">Introduction</span></h4></div></div><p>
In this How To I will discuss the use of the BeanContext und AWT to create
GUIs and GUI components within
EJX but you can also use AWT outside of EJX.Attention: please note that I
always mean Rickard ֢erg's AWT
and not the Java AWT!</p><p>The AWT provides you with the following
opportunities: </p><div class="orderedlist"><ol type="1"><li><p><a
name="N27b0"></a>Customizers for your Beans</p></li><li><p><a
name="N27b4"></a>Property Editors to edit or select properties</p></li></ol></div><p>
This seems to be simple but combining them together with the Java Bean
Support and ordinary Swing coding
leads to advanced GUIs like the actual version of EJX used in jBoss (I am not
taking about the lack of User
guidance but about the abilities of the GUI to display and edit the data).
</p><p>
My biggest problem to understand EJX/AWT was that you have to deal with EJX,
AWT, Java Bean Support,
XML and Swing coding. Therefore I started from the simplest example to
understand each component, its
function and how to use it. In the "Getting-Started" How To I showed how to
create an EJX plugin and then
create a basic Bean GUI. Now I go a step further to dynamically manage GUI
components, use of more BeanInfo
features and to edit properties with the AWT property editors. So let's start
it! </p></div><div class="section"><a name="N27c0"></a><div class="titlepage"><div><h4
class="title"><a name="N27c0"></a><span class="title">
Tabbed Panes and Editors</span></h4></div></div><div class="section"><a
name="N27c4"></a><div class="titlepage"><div><h5 class="title"><a
name="N27c4"></a><span class="title">Goals</span></h5></div></div><p>
From the last example of the first How To create and remove GUI Components
(Tabbed Panes) dynamically and
edit the properties of the data instance with the AWT editors. </p></div><div
class="section"><a name="N27cc"></a><div class="titlepage"><div><h5 class="title"><a
name="N27cc"></a><span class="title">Design</span></h5></div></div><p>
First of all I want correct I mistake in the previous example. In the
MainPane class it is said that getComponent()
is implemented because of BeanContextChildComponentProxy which is not
implemented in the class but it works
because the caller does not relay on this fact. But in this example I fixed
this. The question but still remains why
it should (will maybe be explained later). </p><p>
This example is really not a good example how to use EJX but it shows how to
use EJX/AWT. The idea is to use
a tabbed pane to display different views in our EJX frame. In addition the
user can create and remove the tabbed
pane as long as there is at least one left. And last but not least the user
should be able to select a value through
an editor instead of a plain input field. </p><p>
As we saw in the last example the initial GUI component to show the plugin is
created in the ResourceManager
on the getComponent() call which is called by the BeanContext structure we
use. But instead of create a Panel
which just keeps the GUI of the plugin we create now a viewer of the plugin
to display itself. This makes the
design more flexible because it is now defined in the Viewer instead of the
ResourceManager where it does not
belong. Now the viewer is an inner class because it is so closely related to
its outer component that it makes
sense to be there. </p><p>
The construct following is a little bit ugly and should not be MADE this way
but it is enough for us.
The ResourceManager getComponent() now calls the MainPane's getComponent()
method and this instantiate its
viewer and returns this Viewer as the GUI component to be shown. </p><p>
When the users now hits the create a new Tab or remove this tab the
appropriate method is called (by the
BeanContext) and it will create a new MainPane instance and adds its also
created Viewer instance as a new
Tab to the tabbed pan or remove the actual shown tab from the tabbed pane.
As you can see above the buttons we have a text input field and a drop down
box letting the user select between
two items. Both are AWT editors. </p></div><div class="section"><a
name="N27e0"></a><div class="titlepage"><div><h5 class="title"><a
name="N27e0"></a><span class="title">Implementation</span></h5></div></div><p>
First lets have a look at the changes in the ResourceManager where the
getComponent() just instanciate the
MainPane and returns its GUI component.</p><pre class="programlisting">
public Component getComponent() {
// Create the Property Container and return its GUI component
return new MainPane().getComponent();
}
</pre><p>
Now let's look at the new BeanInfo description of the MainPane: </p><pre
class="programlisting">
<bean class="com.madplanet.tabbedEditor.MainPane"
displayname="Tab Pane and Editor's Main Pane"
iconcolor16="/images/container.gif"> <property
name="FirstProperty" class="java.lang.String"
displayname="First Property"
propertyeditor="com.dreambean.awt.editors.TextEditor"/>
<property name="SecondProperty"
class="java.lang.String" displayname="Second
Property"
propertyeditor="com.madplanet.tabbedEditor.editors.SecondPropertyEditor"/>
<method name="createTab" displayname="Create a new
Tab"> <parameter displayname="Title"/> </method>
<method name="removeTab" displayname="Remove this
Tab"> </method> </bean>
</pre><p>
As you can see there are property editors settings for the first and second
property and the second
property uses its own editors. In addition you have methods listed which
appears as buttons in the
GUI because we use the GenericCustomizer. </p><p>
The new editor is just a simple subclass of the AWT TagsEditor defining what
items it has to show and to what
value the item relate to (you can use any Java Object you like): </p><pre
class="programlisting">
package com.madplanet.tabbedEditor.editors;
import com.dreambean.awt.editors.TagsEditor;
/** * Editor to select the Second Property in a DD - editor */
public class SecondPropertyEditor extends TagsEditor
{ // Constructors
--------------------------------------------------
public SecondPropertyEditor() {
super(new String[] {"First Selection","Second Selection"},
new Object []{"First", "Second"});
}
} </pre><p>
And as "Grande Finale" we come to the heart of the plugin to the MainPane
class. </p><p>
The new viewer class is an inner class to the MainPane and creates a
GUI to display the
instance of its outer class instance. It keeps a list of outer class
instances to find the
index of the tab to be removed. The setObject() creates a new tab
and memorize the given
outer class. The removeTab() looks for the given outer instance and
removes its related
tab (by this index). </p><pre class="programlisting">
public class Viewer extends JTabbedPane implements Customizer
{ // Attributes
---------------------------------------------------
private Vector mDataObjectList = new Vector(); // Customizer
implementation
------------------------------------
public void setObject( Object pDataObject ) {
// Init UI
addTab( "Main", new GenericCustomizer( pDataObject ) );
mDataObjectList.addElement( pDataObject );
}
/** * Removes the given Tab with the given Data Object *
from the
Tabbed Pane * * @param pDataObject Tab with this Data
Object has to be removed if found **/
public void removeTab(Object pDataObject ) {
int lIndex = mDataObjectList.indexOf(
pDataObject );
if( lIndex >= 0 ) {
remove( lIndex );
mDataObjectList.removeElementAt( lIndex );
}
}
} </pre><p>
These are the new methods (already defined in the BeanInfo see
above) which are called if
the appropriate button is pressed. </p><pre class="programlisting">
public void createTab( String pTitle ) throws Exception {
System.out.println("Create new Tab with title: " + pTitle);
MainPane lNewPane = new MainPane();
lNewPane.mCustomizer = mCustomizer;
lNewPane.mCustomizer.setObject(
lNewPane );
}
public void removeTab() {
System.out.println( "Remove this tab");
( (Viewer) mCustomizer ).removeTab(this );
}
</pre></div></div><div class="section"><a
name="N2814"></a><div class="titlepage"><div><h4 class="title"><a
name="N2814"></a><span class="title"> Remarks</span></h4></div></div><p>
This is more ore less EJX and AWT. But it does not end here. The power of EJX
lays in the BeanContext and
how you combine EJX, BeanContext and AWT. You maybe think what's about XML
and we will come to XML
soon but (in my opinion) this is not a core part of EJX and AWT just use it
but just as the name of the EJX base
classes said they manage resources (or earlier just files). Therefore it must
be a way do deal with resources and
especially with XML resources. </p></div></div></div><div class="section"><a
name="N281e"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N281e"></a><span class="title">JBossCX Configuration</span></h2></div></div><p>
Author:
<span class="author">Toby Allsop</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N282e"></a><div class="titlepage"><div><h3
class="title"><a name="N282e"></a><span
class="title">Introduction</span></h3></div></div><p>
This section describes the configuration changes necessary in order to use
a resource adapter conforming to
the J2EE Connector Architecture (JCA) in your application. </p><p>
The JCA specifies how J2EE application components can access resources
other than those explicitly
specified in the J2EE 1.2 specification. It will be part of the J2EE 1.3
specification. You can read more about
the JCA at its <a href="http://java.sun.com/j2ee/connector"
target="_top"><i>official home page</i></a></p><p>
JBossCX is the name of the JBoss module that provides RAR deployment and
connects a resource adapter to
a connection manager to create a connection factory accessible by
application components through JNDI. </p></div><div class="section"><a
name="N2841"></a><div class="titlepage"><div><h3 class="title"><a
name="N2841"></a><span class="title">Contents</span></h3></div></div><div
class="itemizedlist"><ul><li><p><a name="N2847"></a><a
href="#jca1">Terminology</a></p></li><li><p><a name="N284e"></a><a href="#jca2">JBoss
Configuration</a></p></li><li><p><a name="N2855"></a><a href="#jca3">Example - Black
Box Example Adapter from Sun</a></p></li><li><p><a name="N285c"></a><a
href="#jca4">Implementation Status</a></p></li></ul></div></div><div
class="section"><a name="jca1"></a><div class="titlepage"><div><h3 class="title"><a
name="jca1"></a><span class="title">Terminology</span></h3></div></div><div
class="table"><p><a name="N286b"></a><b>Table 9.2. Terminology</b></p><table
summary="Terminology"
border="1"><thead><tr><th>Concept</th><th>Description</th></tr></thead><tbo!
dy><tr><td>Resource</td><td>an external system that provides some service to
application components. Examples include JDBC
databases and mainframe systems</td></tr><tr><td>Resource adapter
Connector</td><td>an application component that implements access to a
resource</td></tr><tr><td>Resource instance</td><td>a particular configuration of a
resource, e.g. an Oracle database running on machine "foo" at port
"1234"</td></tr><tr><td>Connection factory</td><td>an object,
available through JNDI, that provides access to connections to a particular resource
instance</td></tr><tr><td>Connection manager</td><td>an object that
implements the javax.resource.spi.ConnectionManager interface - provides connection
pooling, transaction association, security and other "quality of
services"</td></tr></tbody></table></div></div><div class="section"><a
name="jca2"></a><div class="titlepage"><div><h3 class="title"><a name="jca2"></a><span
class="title">JBoss Configuration</span></h3></div></div><p>
There are two steps that must be performed to provide access to a
connection factory in JBoss: </p><div class="orderedlist"><ol type="1"><li><p><a
name="N28c1"></a>Configure a connection factory in jboss.jcml </p></li><li><p><a
name="N28c5"></a>Deploy the resource adapter </p></li></ol></div><div
class="section"><a name="N28ca"></a><div class="titlepage"><div><h4 class="title"><a
name="N28ca"></a><span class="title">Connection Factory
Configuration</span></h4></div></div><p>
Connection factories are created by the ConnectionFactoryLoader MBean, so
an <mbean> section must be
added to jboss.jcml for each connection factory that is required. The
format for this entry is as follows.</p><pre class="programlisting">
<mbean code="org.jboss.resource.ConnectionFactoryLoader"
name="JCA:service=ConnectionFactoryLoader,name=name">
<!-- General attributes -->
<attribute name="name">value</attribute>
<!-- Security attributes -->
<attribute name="name">value</attribute>
</mbean>
</pre><p>General Attributes</p><div class="table"><p><a
name="N28d9"></a><b>Table 9.3. General Attributes</b></p><table summary="General
Attributes"
border="1"><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td>FactoryName</td><td>The
name of the connection factory. This is the name under which the
connection factory will be bound in
JNDI</td></tr><tr><td>RARDeployerName</td><td>The name of the MBean that will deploy
the resource adapter that this
connection factory relates
to</td></tr><tr><td>ResourceAdapterName</td><td>The name of the resource adapter for
which this connection factory will
create connections. This is the name
given in the resource adapter's
<display-name> deployment
descriptor element</td></tr><tr><td>Properties</td><td>The properties to set on the
resource adapter to configure it to connect to a
particular resource instance. This is
in java.util.Properties.load format
(essentially one property per line,
name=value)</td></tr><tr><td>ConnectionManagerFactoryName</td><td>The name of the
connection manager factory to use. This is the name given
in a previously defined
ConnectionManagerFactoryLoader MBean.
Currently there are two choices:
MinervaSharedLocalCMFactory and
MinervaXACMFactory. The former should
be used for resource adapters that
support local transactions and the
latter for those that support XA
transactions.</td></tr><tr><td>ConnectionManagerProperties</td><td>The properties (in
java.util.Properties.load format) to set on the
connection manager for this connection
factory. These properties control
things such as connection pooling
parameters. The example connection
factory in jboss.jcml shows the
possible properties for the Minerva
connection
managers</td></tr></tbody></table></div><p>Security Attributes</p><p>TBD - no
interesting options yet</p></div><div class="section"><a name="N2931"></a><div
class="titlepage"><div><h4 class="title"><a name="N2931"></a><span
class="title">Deploying the Resource Adapter</span></h4></div></div><p>
Currently the J2EE deployer does not recognise resource adapters, so it is
not possible to deploy them with the
auto deployer or as part of an EAR. This functionality will be added at a
later date.</p><p>
To deploy a resource adapter, and thus activate any connection factories
configured for it, invoke the
deploy(String) operation on the RARDeployer MBean, passing it a URL
pointing to the RAR file containing the
resource adapter. The RAR deployer can also deploy directories that are
structured like a RAR file.</p><p>
The easiest way to invoke operations on MBeans is using the HTML adapter
that is, by default, accessible on
port 8082, i.e. point a browser at http://localhost:8082 if running the
browser on the machine running JBoss.
Then find the RARDeployer MBean and it should be self explanatory from
there. </p></div></div><div class="section"><a name="jca3"></a><div
class="titlepage"><div><h3 class="title"><a name="jca3"></a><span
class="title">Example - Black Box Example Adapter from Sun</span></h3></div></div><p>
For this example you will need Sun's example resource adapter, available
here. The source code for this
resource adapter is also available - this is useful if writing your own
adapter. </p><p>
This resource adapter accesses a JDBC 2.0 compliant database. The
advantage of this is that you don't need
any weird or wacky resource to access and that you can compare the
behaviour with a straight JDBC
connection pool. </p><p>
In order to make a connection factory from this resource adapter available
to application components, we need
to add the ConnectionFactoryLoader MBean that will create the connection
factory from the resource adapter
when it is deployed. We will create a connection factory called BlackBoxDS
that will appear in JNDI at
java:/BlackBoxDS. Below is the MBean definition that we will use (this is
taken from the default jboss.jcml.</p><pre class="programlisting">
<!-- Example connection factory for the example "Black Box" resource
adapter. This points at the same database as DefaultDS. -->
<mbean code="org.jboss.resource.ConnectionFactoryLoader"
name="JCA:service=ConnectionFactoryLoader,name=BlackBoxDS">
<attribute name="FactoryName">BlackBoxDS</attribute>
<attribute
name="RARDeployerName">JCA:service=RARDeployer</attribute>
<attribute name="ResourceAdapterName">Black Box LocalTx
Adapter</attribute>
<attribute name="Properties">
ConnectionURL=jdbc:HypersonicSQL:hsql://localhost:1476
</attribute>
<attribute
name="ConnectionManagerFactoryName">MinervaSharedLocalCMFactory</attribute>
<!-- See the documentation for the specific connection manager
implementation you are using for the properties you can set
-->
<attribute name="ConnectionManagerProperties">
# Pool type - uncomment to force, otherwise it is the default
#PoolConfiguration=per-factory
# Connection pooling properties - see
# org.opentools.minerva.pool.PoolParameters
MinSize=0
MaxSize=10
Blocking=true
GCEnabled=false
IdleTimeoutEnabled=false
InvalidateOnError=false
TrackLastUsed=false
GCIntervalMillis=120000
GCMinIdleMillis=1200000
IdleTimeoutMillis=1800000
MaxIdleTimeoutPercent=1.0
</attribute>
<!-- Principal mapping configuration -->
<attribute name="PrincipalMappingClass"
>org.jboss.resource.security.ManyToOnePrincipalMapping</attribute>
<attribute name="PrincipalMappingProperties">
userName=sa
password=
</attribute>
</mbean>
</pre><p>
Note that the connection manager we have chosen is the Minerva local
transaction connection manager. It is
important to choose the connection manager that matches the capabilities
of the resource adapter. This choice
should be automated in the future. </p><p>
Once jboss.jcml is set up with the desired connection factory loaders,
start JBoss and bring up the HTML JMX
connector which lives on port 8082 by default. If your browser is running
on the same box as JBoss then you
can just go to http://localhost:8082. Then find the RARDeployer MBean and
invoke the deploy operation,
passing it the URL to the resource adapter you want to deploy. In this
case it is the path to blackbox-tx.rar
which you should save somewhere local. </p><p>
Assuming that the deployment was successful, you should now have a
connection factory bound in JNDI at
java:/BlackBoxDS that you can use just like a normal JDBC DataSource.
</p></div><div class="section"><a name="jca4"></a><div class="titlepage"><div><h3
class="title"><a name="jca4"></a><span class="title">Implementation
Status</span></h3></div></div><p>
Note that this section is likely to lag the latest developments in CVS.
When a stable release including JBossCX
is made then this section should reflect the status of the released
implementation. </p><div class="section"><a name="N2967"></a><div
class="titlepage"><div><h4 class="title"><a name="N2967"></a><span
class="title">Unimplemented Features</span></h4></div></div><div
class="itemizedlist"><ul><li><p><a name="N296d"></a>Automatic connection manager
selection based on resource adapter capabilities. </p></li><li><p><a
name="N2971"></a>Mapping to more than one resource principal per connection
factory.</p></li></ul></div></div><div class="section"><a name="N2977"></a><div
class="titlepage"><div><h4 class="title"><a name="N2977"></a><span
class="title">Limitations</span></h4></div></div><p>
Transaction association doesn't work properly unless the
transaction is started before the connection
is obtained. </p></div></div></div><div class="section"><a
name="N2981"></a><div class="titlepage"><div><h2 class="title" style="clear: all"><a
name="N2981"></a><span class="title">External JNDI Configuration and JNDI
Viewing</span></h2></div></div><p>
Author:
<span class="author">Scott Stark</span>
<tt><<a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>></tt>
</p><div class="section"><a name="N2991"></a><div class="titlepage"><div><h3
class="title"><a name="N2991"></a><span class="title">How To Use the JNDI
ExternalContext and JNDIView MBeans</span></h3></div></div><p>The ExternalContext JNDI
MBean allows one to federate external
JNDI contexts into the JBoss server JNDI namespace. This allows one
to incorporate LDAP servers, Filesystem directories, DNS servers, etc.
even if the JNDI providers root context is not Serializable.
</p><p>
The JNDIView MBean allows one to view the JNDI namespace tree as it exists
in the JBoss server using the JMX agent view interface.
</p></div><div class="section"><a name="N299d"></a><div class="titlepage"><div><h3
class="title"><a name="N299d"></a><span class="title">Preparation of the
ExternalContext MBean</span></h3></div></div><p>
First you have to add the ExternalContext service to the jboss.jcml
in order to load the service. The folloing jboss.jcml fragment shows
the setup for an LDAP server and a local filesystem directory:
<div class="literallayout"><br>
<!-- Bind a remote LDAP server --><br>
<mbean code="org.jboss.naming.ExternalContext" name="DefaultDomain:service=ExternalContext/ldap/dscape" ><br>
<attribute name="JndiName">external/ldap/dscape</attribute><br>
<attribute name="Properties">dscape.ldap</attribute><br>
<attribute name="InitialContext">javax.naming.ldap.InitialLdapContext</attribute><br>
</mbean><br>
<!-- Bind the /Scott filesystem directory --><br>
<mbean code="org.jboss.naming.ExternalContext" name="DefaultDomain:service=ExternalContext/fs/Scott" ><br>
<attribute name="JndiName">external/fs/Scott</attribute><br>
<attribute name="Properties">scott_fs.props</attribute><br>
<attribute name="InitialContext">javax.naming.InitialContext</attribute><br>
</mbean><br>
<br>
</div>
where:
<div class="itemizedlist"><ul><li><a
name="N29ad"></a><p>code="org.jboss.naming.ExternalContext" specifies the class that
impliments the
external context mbean.
</p></li><li><a
name="N29b1"></a><p>name="DefaultDomain:service=ExternalContext/ldap/dscape" assigns
the name of the
mbean. This is using a convention that appends the unique portion of the jndi
name to the JMX name so that multiple external context mbeans are easily
distiguishable in the JMX agent view.
</p></li><li><a name="N29b5"></a><p>JndiName is the name with which the external
context is bound into the JBoss JNDI namespace
</p></li><li><a name="N29b9"></a><p>Properties is URL string to a jndi.properties
style of file for the JNDI provider whose
context is to be created. This can be any url for which there is a handler or a
simple
string in which case it is treated as a resource that can be loaded via the current
thread's context class loader.
</p></li><li><a name="N29bd"></a><p>InitialContext is the class name of the
InitialContext class to create. Should be one
of javax.naming.InitialContext, javax.naming.directory.InitialDirContext, or
javax.naming.ldap.InitialLdapContext. In the case of the InitialLdapContext, a null
Controls array is used.
</p></li></ul></div>
</p><p>
This example is binding an external LDAP context into the JBoss JNDI namespace under
the name "external/ldap/dscape". An example dscape.ldap properties file is:
<div class="literallayout"><br>
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory<br>
java.naming.provider.url=ldap://ldaphost.displayscape.com:389/o=displayscape.com<br>
java.naming.security.principal=cn=Directory Manager<br>
java.naming.security.authentication=simple<br>
java.naming.security.credentials=secret<br>
</div>
With this mbean loaded, you can access the external LDAP context located at
"ldap://ldaphost.displayscape.com:389/o=displayscape.com"
from within the JBoss VM using the following code fragment:
<pre class="programlisting">
InitialContext iniCtx = new InitialContext();
Context ldapCtx = iniCtx.lookup("external/ldap/dscape");
...
</pre>
Using the same code fragment outside of the JBoss server VM will not work
because the ObjectFactory used to handle the Reference to the LDAP context
is designed to only work within a single VM. Future versions of the ExternalContext
mbean will provide support for enabling remote access to the federated context if
desired.
</p></div><div class="section"><a name="N29d3"></a><div class="titlepage"><div><h3
class="title"><a name="N29d3"></a><span class="title">Preparation of the JNDIView
MBean</span></h3></div></div><p>
All that is required to use the JNDIView service is to add it to jboss.jcml
The mbean tag looks like this:
<div class="literallayout"><br>
<mbean code="org.jboss.naming.JNDIView" name="DefaultDomain:service=JNDIView" ><br>
</mbean><br>
<br>
</div>
There are no configurable attributes. This simply loads the mbean into the JBoss
server VM so that it can be used via the JMX MBean View.
</p></div><div class="section"><a name="N29e3"></a><div class="titlepage"><div><h3
class="title"><a name="N29e3"></a><span class="title">Using the JNDIView
MBean</span></h3></div></div><p>
To view the JBoss JNDI namespace using the JNDIView mbean, you connect to the
JMX Agent View using the http interface. The default settings put this at
<a href="http://localhost:8082/" target="_top">http://localhost:8082/</a>. On this
page you will see a section that lists the registered MBeans by domain. It
should look something like this:
<pre class="screen">
<img src="images/agent_view.jpg">
</pre>
</p><p>
This is showing two registered ExternalContext mbeans(ExternalContext/fs/Scott[a
filesystem] and
ExternalContext/ldap/dscape[an ldap server]) mbeans as well as the JNDIView
mbean. Selecting the service=JNDIView link takes you to the JNDIView MBean
View which will have a list of MBean operations section similar to:
<pre class="screen">
<img src="images/jndiview_ops.jpg">
</pre>
</p><p>
Invoking the list operation creates a dump of the JBoss JNDI namespace that
includes the federated external contexts. As an example, this is the dump
with the filesystem and ldap contexts. The following image displays the
start of the global JNDI namespace and includes the external/fs/Scott
local filesystem directory contents.
<pre class="screen">
<img src="images/jndiview_list.jpg">
</pre>
</p></div></div></div></div></body></html>