User: mulder  
  Date: 00/08/31 12:08:49

  Modified:    src/main/org/jboss/minerva minerva.html
  Log:
  Updates to Minerva documentation.
  
  Revision  Changes    Path
  1.2       +552 -236  jboss/src/main/org/jboss/minerva/minerva.html
  
  Index: minerva.html
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/minerva/minerva.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- minerva.html      2000/06/02 13:48:40     1.1
  +++ minerva.html      2000/08/31 19:08:49     1.2
  @@ -1,241 +1,557 @@
   <HTML>
  -<HEAD>
  -<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
  -<TITLE>JBuilder Project minerva.jpr</TITLE>
  -</HEAD>
  -<BODY>
  -<H1>Minerva Object/Database Pools</H1>
  -<HR>
  -<P><FONT SIZE=+1>
  -<STRONG>Project: </STRONG>Minerva Object Pools<BR>
  -<STRONG>Author: </STRONG><A HREF="mailto:[EMAIL PROTECTED]">Aaron
  -                     Mulder</A><BR>
  -<STRONG>Description: </STRONG> Generic object pools, and specifically, JDBC
  - connection pools.<BR>
  -<STRONG>Release: </STRONG> 0.95
  -<BR><STRONG>Download Minerva JAR:</STRONG>
  -   <A HREF="minerva.jar">minerva.jar</A> - not necessary for jBoss
  -<BR><STRONG>Download Test Bean:</STRONG>
  -   <A HREF="SQLTest.jar">SQLTest.jar</A> - includes jBoss 2.0 XML files
  -<BR><STRONG>Download Test Client JAR:</STRONG>
  -   <A HREF="SQLClient.jar">SQLClient.jar</A> - put in jboss/dist/client
  -   and run with <CODE>java -jar SQLClient.jar</CODE>
  -</FONT></P>
  -<OL>
  -  <LI><A HREF="#drivers">JDBC 1.0 drivers vs. JDBC 2.0 drivers</A></LI>
  -  <LI><A HREF="#using">Using the JDBC Connection Pools in jBoss 2.0</A></LI>
  -  <LI><A HREF="#client">Using the JDBC Connection Pool test EJB and client in jBoss 
2.0</A></LI>
  -  <LI><A HREF="#bugs">Outstanding Features/Bugs</A></LI>
  -</OL>
  -<HR>
  -
  -<H3><A NAME="drivers">JDBC 1.0 drivers vs. JDBC 2.0 drivers</A></H3>
  -<P>The database drivers for JDBC 1.0 cannot participate in two-phase commits,
  -  which is generally assumed to be used in a J2EE server.  It is possible for
  -  the server to use a one-phase commit protocol, but only if it can establish
  -  that it's safe.  JDBC 2.0 drivers may provide the appropriate support - which
  -  is part of the optional JDBC 2.0 Standard Extension.</P>
  -<P>This package can be used to pool either kind of connection - normal JDBC
  -  1.0 or 2.0 one-phase commit connections, or JDBC 2.0 two-phase commit
  -  connections.  For normal operation of a J2EE server, you must use the latter.
  -  There is a set of wrappers for JDBC 1 drivers to operate in the two-phase
  -  commit environment, under certain restrictions.  For example, if you request
  -  several connection from the pool within the scope of one Transaction, you
  -  will get the same connection every time.  Also, a connection is not returned
  -  to the pool until you commit or rollback the transaction.  Finally, these
  -  wrappers are not truly two-phase aware, and you will experience heuristic
  -  commits or rollbacks (only a problem if one data source attemps to commit
  -  while another attempts to rollback, etc.).</P>
  -<P>If your driver supports one-phase commit, you would use it in the traditional
  -  JDBC way - use the DriverManager to get a Connection.  You supply those
  -  parameters to the pool configuration.  For two=phase commit, you must specify
  -  the name of a vendor class (or the Minerva wrapper class) that implements
  -  javax.sql.XADataSource, so there's no DriverManager interaction, though you
  -  still provide certain connection parameters (which may or may not be the same
  -  - see your vendor's documentation).  For the Minerva wrapper class, specify
  -  the parameters as if you were using DriverManager (which is what the wrapper
  -  classes do!).</P>
  -
  -<HR>
  -
  -<H3><A NAME="using">Using the JDBC Connection Pools in jBoss 2.0</A></H3>
  -<P>There are four things you need to do:</P>
  -<OL>
  -  <LI>If you are building jBoss from source, the minerva packages are included.
  -    If you are using a binary, they are not yet included, so you should include
  -    the minerva.jar archive in your jBoss libraries</LI>
  -  <LI>Include an MLET entry in your jboss.conf for each pool</LI>
  -  <LI>Specify a Resource Manager in your jBoss configuration for each
  -    EJB JAR</LI>
  -  <LI>Specify a Resource Reference in your EJB configuration for each
  -    EJB (two places)</LI>
  -</OL>
  -
  -<H4>Including the JAR</H4>
  -<P>If you're using a binary distribution, copy minerva.jar to
  -  jboss/lib/ext/minerva.jar.</P>
  -
  -<H4>Add MLET entries for the MBeans</H4>
  -<P>In the future, the MBeans will be included in the jBoss distribution, but
  -  for now they live in the Minerva JAR.  Edit your jboss.conf to include a
  -  section like the example below.  For a JDBC 2.0 pool (which participates in
  -  Transactions), use the parameters in the table below.  The URL, username, 
password,
  -  and Properties are used to connect to your underlying database.  So if you
  -  had an Oracle database with JDBC 1.0 drivers that you wanted to pool, you'd
  -  specify the Minerva 1.0 wrapper data source, and the Oracle URL and username
  -  and password and properties (any you don't need should be included but left
  -  blank).</P>
  -<TABLE BORDER="1">
  -  <TR><TH>Position</TH><TH>Type</TH><TH>Value</TH></TR>
  -  <TR><TD>1</TD><TD>java.lang.String</TD><TD>Pool Name</TD></TR>
  -  <TR><TD>2</TD><TD>java.lang.String</TD><TD>XADataSource class name (use 
org.jboss.minerva.xa.XADataSource for the JDBC 1.0 wrapper)</TD></TR>
  -  <TR><TD>3</TD><TD>java.lang.String</TD><TD>JDBC Connection URL</TD></TR>
  -  <TR><TD>4</TD><TD>java.lang.String</TD><TD>JDBC Connection user name</TD></TR>
  -  <TR><TD>5</TD><TD>java.lang.String</TD><TD>JDBC Connection password</TD></TR>
  -  <TR><TD>6</TD><TD>java.lang.String</TD><TD>JDBC Connection properties (in the 
format name=value;name=value;name=value)</TD></TR>
  -  <TR><TD>7</TD><TD>java.lang.Integer</TD><TD>Pool minimum size (pool starts at 0, 
but never shrinks below this)</TD></TR>
  -  <TR><TD>8</TD><TD>java.lang.Integer</TD><TD>Pool maximum size (exceptions once 
it's full)</TD></TR>
  -  <TR><TD>9</TD><TD>java.lang.String</TD><TD><I>Optional!</I> Advanced Pool 
parameters (in the format name=value;name=value;name=value)</TD></TR>
  -</TABLE>
  -<P>Here are the valid properties for the pool parameters (case sensitive).  You
  -  may include any or all of these in whatever order you prefer:</P>
  -<TABLE BORDER="1">
  -  <TR><TH>Name</TH><TH>Type</TH><TH>Description</TH><TH>Default</TH></TR>
  -  <TR><TD>Blocking</TD><TD>boolean</TD><TD>Whether the pool should block if there's 
no connection available, or return null</TD><TD>false</TD></TR>
  -  <TR><TD>GCEnabled</TD><TD>boolean</TD><TD>Whether the pool should attempt to 
return connections to the pool after a period of inactivity</TD><TD>false</TD></TR>
  -  <TR><TD>GCInterval</TD><TD>long</TD><TD>How often (in ms) garbage collection 
and/or shrinking should run</TD><TD>120000</TD></TR>
  -  <TR><TD>GCMinIdleTime</TD><TD>long</TD><TD>How long a connection must be unused 
(in ms) before being returned to the pool</TD><TD>1200000</TD></TR>
  -  <TR><TD>ShrinkingEnabled</TD><TD>boolean</TD><TD>Whether the pool should shrink 
if some connections haven't been used recently</TD><TD>false</TD></TR>
  -  <TR><TD>ShrinkMinIdleTime</TD><TD>long</TD><TD>How long a connection must be 
unused (in ms) in the pool before its eligible for shrinking</TD><TD>600000</TD></TR>
  -  <TR><TD>ShrinkPercent</TD><TD>float (0-1)</TD><TD>How many of the eligible 
connections will be released</TD><TD>0.33</TD></TR>
  -  <TR><TD>TimestampUsed</TD><TD>boolean</TD><TD>Whether to track last used times on 
SQL events (queries, cursor movements, etc.) (true) or just pool checkin and checkout 
(false)</TD><TD>false</TD></TR>
  -</TABLE>
  -
  -<P>Here's an example with a JDBC 1.0 Oracle driver using the wrapper classes,
  -  and custom configuring the pool paramters:</P>
  -<PRE>
  -&lt;MLET CODE = "org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar,minerva.jar" 
CODEBASE="../lib/ext/"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE="TestOraclePool"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE="org.jboss.minerva.xa.XADataSourceImpl"&gt;
  -   &lt;ARG TYPE="java.lang.String" 
VALUE="jdbc:oracle:thin:@host.domain.com:1521:instance"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE="user"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE="password"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE=""&gt;
  -   &lt;ARG TYPE="java.lang.Integer" VALUE="2"&gt;
  -   &lt;ARG TYPE="java.lang.Integer" VALUE="5"&gt;
  -   &lt;ARG TYPE="java.lang.String" 
VALUE="GCEnabled=true;ShrinkingEnabled=true;GCMinIdleTime=30000;GCInterval=10000;ShrinkMinIdleTime=30000"&gt;
  +  <HEAD>
  +    <TITLE>Minerva Database Pools 0.98</TITLE>
  +  </HEAD>
  +  <BODY>
  +    <H1>Minerva Database Pools 0.98</H1>
  +    <P>This is the documentation for the Minerva pools.  It is aimed
  +      at both developers and users, so be selective.  I suggest everyone read
  +      the section on
  +      <A HREF="#jdbc">JDBC vs the JDBC Standard Extension</A>, since a lot of
  +      the rest may be pretty muddled without it.  You don't need a very
  +      thorough understanding to use the JDBC Standard Extension pools - all the
  +      tricky stuff is done under the covers.  Just be aware of the advantages
  +      and limitations.</P>
  +    <UL>
  +      <LI><A HREF="#intro">Introduction to Minerva</A></LI>
  +      <LI><A HREF="#jdbc">JDBC 1/2 vs the JDBC Standard Extension</A>
  +        <UL>
  +          <LI>Concepts</LI>
  +          <LI>Reality</LI>
  +        </UL></LI>
  +      <LI><A HREF="#j1pools">Using Minerva JDBC 1/2 Pools</A></LI>
  +      <LI><A HREF="#j2epools">Using Minerva JDBC 2 Standard Extension Pools</A></LI>
  +      <LI><A HREF="#jboss">Using Minerva JDBC Pools with jBoss 2.0</A></LI>
  +      <LI><A HREF="#j2ee">Using Minerva JDBC Pools with Other J2EE 
Containers</A></LI>
  +      <LI><A HREF="#obpools">Using Minerva Object pools</A></LI>
  +      <LI><A HREF="#arch">Minerva Architecture</A></LI>
  +      <LI><A HREF="#examples">Minerva Examples</A>
  +        <UL>
  +          <LI><A HREF="#ex1">Creating a JDBC Pool</A></LI>
  +          <LI><A HREF="#ex2">Getting a JDBC Pool connection directly</A></LI>
  +          <LI><A HREF="#ex3">Getting a JDBC Pool connection from JNDI</A></LI>
  +          <LI><A HREF="#ex4">Getting a JDBC Pool connection from the 
DriverManager</A></LI>
  +          <LI><A HREF="#ex5">Creating a JDBC Standard Extension (<B>S.E.</B>) 
Pool</A></LI>
  +          <LI><A HREF="#ex6">Getting a JDBC S.E. Pool connection directly</A></LI>
  +          <LI><A HREF="#ex7">Getting a JDBC S.E. Pool connection from JNDI</A></LI>
  +          <LI><A HREF="#ex8">Getting a JDBC S.E. Pool connection from the 
DriverManager</A></LI>
  +          <LI><A HREF="#ex9">Configuring a JDBC S.E. Pool with jBoss and a JDBC 
S.E. Driver</A></LI>
  +          <LI><A HREF="#ex10">Configuring a JDBC S.E. Pool with jBoss and a JDBC 
1/2 Driver</A></LI>
  +          <LI><A HREF="#ex11">Configuring an Enterprise Java Bean with a 
DataSource</A></LI>
  +          <LI><A HREF="#ex12">Linking the EJB DataSource to a Minerva Pool with 
jBoss</A></LI>
  +          <LI><A HREF="#ex13">Getting a connection in an EJB implementation</A></LI>
  +          <LI><A HREF="#ex14">Creating a pool for a generic Object type</A></LI>
  +          <LI><A HREF="#ex15">Getting and returning Objects</A></LI>
  +          <LI><A HREF="#ex16">Getting and returning PooledObjects</A></LI>
  +        </UL></LI>
  +      <LI><A HREF="#nyi">Outstanding Features</A></LI>
  +    </UL>
  +
  +    <HR><BR>
  +    <H2><A NAME="intro">Introduction to Minerva</A></H2>
  +    <P>The Minerva library is a multi-layered set of classes that can manage
  +      pools of Java objects.  At the lowest level, this can be any type of Java
  +      object.  At a higher level, it provides implementations for database
  +      connections.  It is part of the jBoss project (an open-source J2EE server),
  +      but does not depend on jBoss - it can be used independently in any Java 2
  +      environment.  You will need the JDBC 2 Standard Extension, JNDI, and JTA
  +      to take full advantage of the J2EE JDBC features, but you can ignore all
  +      that if you just want a simple object or database pool (you may still need
  +      the jdbc 2 standard extension and JNDI jars at runtime, but you won't have
  +      to use them directly).</P>
  +    <P>The rest of this document is devoted to the different uses of the
  +      Minerva pools - J2EE connections, plain JDBC connections, objects, etc.
  +      There's a section on integrating the Minerva pools with jBoss, which you
  +      should read if you're using jBoss, and skip if you're not.</P>
  +
  +    <HR><BR>
  +    <H2><A NAME="jdbc">JDBC 1/2 vs the JDBC Standard Extension</A></H2>
  +    <H3>Concepts</H3>
  +    <P>JDBC 1 was part of Java 1, and JDBC 2 is part of Java 2.  So most of you
  +      probably have a pretty clear understanding of JDBC.  However, the JDBC 2
  +      Standard Extension brings a whole new set of concepts to the table.</P>
  +    <P>In "normal" JDBC, there's a very tight coupling between transactions
  +      and connections.  Every transaction is attached to exactly one connection
  +      (even if auto-commit is on - whereupon they're just very <I>short</I>
  +      transactions).  Though there may be many transactions over the life of
  +      one connection, the reverse is not true - there cannot be more than one
  +      connection associated with a single transaction.  As soon as you create a
  +      new connection, you've created a new transaction too.  Additionally, you
  +      cannot start a new transaction on a connection until the last one is
  +      complete.  There is no concept of more than one set of "pending work" for
  +      a connection. Once you start doing things, the only way to get a new
  +      transaction on the same connection is to commit or rollback, and at that
  +      time a new transaction is automatically started.</P>
  +    <P>To quote a little green guy, "you must un-learn what you have learned" in
  +      order to work with the JDBC 2 Standard Extension.  Here, connections and
  +      transactions are completely independent.  You may use many connections in
  +      the scope of a single transaction, and you may do work on many uncommitted
  +      transactions with a single connection.  A connection is just a way for
  +      you to communicate with the database - it's up to you and the database to
  +      decide what you're talking about (which transaction, etc).</P>
  +    <P>The primary advantage of this is that you can do work across many
  +      databases, or indeed many data <I>sources</I>, and commit it all together
  +      or roll it back all together.  One way to do this is known as "two-phase
  +      commit."  In the first phase, you ask all your data sources whether they
  +      can commit, and then in the second phase, based on the responses, you tell
  +      everything to either commit or rollback.  And it may be that some of these
  +      data sources are legacy systems, message queues, or something else
  +      altogether.  Another advantage is that it makes it easy and efficient to
  +      pool database connections - the connection can be returned to the pool
  +      immediately, even if it will be a while before the work is committed.</P>
  +    <P>So a J2EE server needs to support the JDBC standard extension, diverse
  +      data sources, and transaction management.  If you see me refer to a
  +      "transactional" or "XA" connection, I'm talking about a JDBC 2 Standard
  +      Extension connection, which can participate in JTA transactions.  JDBC 1
  +      or JDBC 2 connections can't, since they don't support two-phase commit,
  +      and they can't separate a connection from a transaction.</P>
  +    <H3>Reality</H3>
  +    <P>Unfortunately, most database vendors do not yet support the JDBC Standard
  +      Extension.  And those that do generally don't have very robust support yet.
  +      This presents a problem, since most J2EE users want to use databases.</P>
  +    <P>The solution to this is a set of wrapper classes for plain JDBC 1 or JDBC
  +      2 connections.  This allows them to participate in JTA transactions, though
  +      in a somewhat limited fashion.  First, you can only use one connection per
  +      data source per transaction.  Second, if the connection cannot commit,
  +      it won't tell you during the first inquiry phase when it's supposed to -
  +      it will fail during the commit phase, which may mean some data sources
  +      get committed and others rolled back.  That's clearly undesirable, which
  +      is why we want all vendors to provide good JDBC 2 Standard Extension
  +      implementation.  Take this moment you bother your vendor's support line.
  +      Third, a connection cannot be closed or returned to a connection pool
  +      untle the pending work is either committed or rolled back - you wouldn't
  +      want someone else adding work to the transaction <I>before</I> you
  +      commit it!</P>
  +
  +    <HR><BR>
  +    <H2><A NAME="j1pools">Using Minerva JDBC 1/2 Pools</A></H2>
  +    <P>In order to create normal JDBC pools, you should interact with the class
  +      org.jboss.minerva.datasource.JDBCPoolDataSource.  It's pretty
  +      straightforward - create it, set all the JDBC properties (URL, user,
  +      password, etc.) and pool properties (name, min size, max size, whether it
  +      blocks, shrinks, etc.) that you need, and then initialize() it.  It
  +      implements the DataSource interface from the JDBC 2 Standard Extension,
  +      so you can just call getConnection() to get a connection.  When you're
  +      done with the connection, close() it, and it will get returned to the
  +      pool.  When you're done with the pool, call close() on the data source
  +      and it will close all the connections in the pool and shut everything
  +      down.
  +    <P>If you want to make your pools more accessible, you can do that in two
  +      ways.  The first is to call setJNDIName to register the pool in JNDI.
  +      The second is to use the JDBC driver org.jboss.minerva.datasource.PoolDriver
  +      and a URL of the form "jdbc:minerva:<I>PoolName</I>".  In this way, you
  +      get pooled database connections in the same way you'd normally get
  +      connections - DriverManager.getConnection(url).  There's no need to supply
  +      a user, password, or any properties - all that is set by the pool itself.
  +      </P>
  +
  +<P>Finally, if you want to interact with the pool directly rather than using the
  +  DataSource or DriverManager interfaces, you can use the Object pools with the
  +  object factory org.jboss.minerva.factories.JDBCConnectionFactory. Take a look
  +  at the source code for JDBCPoolDataSource if it's not clear.</P>
  +
  +    <HR><BR>
  +    <H2><A NAME="j2epools">Using Minerva JDBC 2 Standard Extension Pools</A></H2>
  +    <P>In order to create JDBC 2 Standard Extension pools, you should interact
  +      with the class org.jboss.minerva.datasource.XAPoolDataSource.  This also
  +      implements the DataSource interface.  All the transactional-ness is
  +      handled under the covers.  You'll need to set some additional properties,
  +      but you will still get a normal java.sql.Connection, and close it when
  +      you're done to return it to the pool.  You don't have to know anything
  +      about the inner mechanics of transactions or
  +      It's pretty
  +      straightforward - create it, set all the JDBC properties (URL, user,
  +      password, etc.) and pool properties (name, min size, max size, whether it
  +      blocks, shrinks, etc.) that you need, and then initialize() it.  It
  +      implements the DataSource interface from the JDBC 2 Standard Extension,
  +      so you can just call getConnection() to get a connection.  When you're
  +      done with the connection, close() it, and it will get returned to the
  +      pool.  When you're done with the pool, call close() on the data source
  +      and it will close all the connections in the pool and shut everything
  +      down.
  +    <P>If you want to make your pools more accessible, you can do that in two
  +      ways.  The first is to call setJNDIName to register the pool in JNDI.
  +      The second is to use the JDBC driver org.jboss.minerva.datasource.PoolDriver
  +      and a URL of the form "jdbc:minervaxa:<I>PoolName</I>".  In this way, you
  +      get pooled database connections in the same way you'd normally get
  +      connections - DriverManager.getConnection(url).  There's no need to supply
  +      a user, password, or any properties - all that is set by the pool itself.
  +      </P>
  +
  +<P>Finally, if you want to interact with the pool directly rather than using the
  +  DataSource or DriverManager interfaces, you can use the Object pools with the
  +  object factory org.jboss.minerva.factories.XAConnectionFactory. Take a look
  +  at the source code for XAPoolDataSource if it's not clear.</P>
  +
  +    <HR><BR>
  +    <H2><A NAME="jboss">Using Minerva JDBC Pools with jBoss 2.0</A></H2>
  +    <P>There are several steps required to use Minerva pools with jBoss 2.0:</P>
  +    <OL>
  +      <LI>Add your database driver to jboss.properties
  +        <BLOCKQUOTE>Add or update a line with the driver class names 
(comma-separated) like:<BR>
  +          <CODE>jdbc.drivers=oracle.jdbc.driver.OracleDriver</CODE>
  +        </BLOCKQUOTE>
  +      </LI>
  +      <LI>Add a Minerva pool entry to jboss.conf
  +        <BLOCKQUOTE>See the example below for
  +          <A HREF="#ex9">Standard Extension drivers</A> or
  +          <A HREF="#ex10">JDBC 1/2 drivers</A>.</BLOCKQUOTE>
  +      </LI>
  +      <LI>Add the pool's specific configuration to jboss.jcml
  +        <BLOCKQUOTE>See the example below for
  +          <A HREF="#ex9">Standard Extension drivers</A> or
  +          <A HREF="#ex10">JDBC 1/2 drivers</A>.</BLOCKQUOTE>
  +      </LI>
  +      <LI>Add a resource reference to your EJB's ejb-jar.xml (not jBoss specific)
  +        <BLOCKQUOTE>See the <A HREF="#ex11">example below</A>.</BLOCKQUOTE>
  +      </LI>
  +      <LI>Add a resource manager to your EJB's jboss.xml
  +        <BLOCKQUOTE>See the <A HREF="#ex12">example below</A>.</BLOCKQUOTE>
  +      </LI>
  +    </OL>
  +    <P>You can use more than one Minerva pool at the same time, and even from
  +      the same bean.  You'd have to repeat all the steps for each one, unless
  +      they use the same drivers (only add it once to jboss.properties).  Once
  +      you have a pool set up, you can refer to it from additional beans by
  +      repeating the last 2 steps for each bean.
  +
  +    <HR><BR>
  +    <H2><A NAME="j2ee">Using Minerva JDBC Pools with Other J2EE Containers</A></H2>
  +    <P>The only real requirement here is that the TransactionManager for the
  +      container must be in JNDI, so the pools can find it and register
  +      connections as they are used.  You'll need to find out how to start a
  +      service for the container, and probably provide a skeletal class that
  +      lets the user set all the configuration parameters.  You can use the
  +      JMX classes to load Minerva pools in jBoss as a reference (see
  +      org.jboss.jdbc.*).  There would be a different way to link an EJB
  +      DataSource reference to the actual DataSource implementation, but the
  +      container vendor probably has a GUI tool for deployment like EJX.
  +
  +    <HR><BR>
  +    <H2><A NAME="obpools">Using Minerva Object pools</A></H2>
  +    <P>If you want to pool something other than JDBC connections, you can do
  +      that with the classes org.jboss.minerva.pools.ObjectPool and
  +      org.jboss.minerva.pool.PoolObjectFactory.  ObjectPool has all the logic,
  +      so you just need to implement a custom subclass of PoolObjectFactory.
  +      The only method you need to implement is createObject(), though you can
  +      customize the object handling more than that.  You can manipulate each
  +      object as it is created, destroyed, given out by the pool, returned to
  +      the pool, etc.  You can even make the pool give out objects other than
  +      the actual instances in the pool, as long as there's a one-to-one mapping
  +      (some kind of wrapper, etc.).</P>
  +    <P>You can use any kind of Object for a custom pool.  However, you may
  +      choose to use objects that implement org.minerva.jboss.pools.PooledObject.
  +      If you do this, the pool will handle close and error events generated by
  +      your objects, so you would not need to explicitly return objects to the
  +      pool.  It will also handle last-used events to automatically track the
  +      usage of pooled object for garbage-collection purposes.</P>
  +    <P>There are several example below of Object Pool usage, but I encourage you
  +      to visit the JavaDoc for ObjectPool, PoolObjectFactory, and PooledObject.
  +      </P>
  +
  +    <HR><BR>
  +    <H2><A NAME="arch">Minerva Architecture</A></H2>
  +    <P>All the Minerva classes have JavaDoc comments, and you can see the
  +      JavaDoc output online on the
  +      <A HREF="http://www.jboss.org/Jaws.htm">jBoss JAWS page</A>.</P>
  +
  +    <H3>Overview</H3>
  +    <P>There are five packages under minerva:</P>
  +    <TABLE BORDER="1">
  +      <TR><TD>pools</TD><TD>Pool implementation</TD></TR>
  +      <TR><TD>jdbc</TD><TD>Support classes for JDBC pools</TD></TR>
  +      <TR><TD>factories</TD><TD>Default object factories for JDBC 1/2 and XA
  +         connections</TD></TR>
  +      <TR><TD>datasource</TD><TD>Client interface for JDBC 1/2 and XA 
pools</TD></TR>
  +      <TR><TD>xa</TD><TD>Wrapper classes for JDBC 1/2 drivers in an XA 
environment</TD></TR>
  +    </TABLE>
  +    <P>So, you'll want to look in a different place depending on what you want
  +      to do.  If you want to change the way to pools work, look in pools
  +      (specifically, ObjectPool).  If you want to create an implementation to
  +      pool something other than database connections, add a PoolObjectFactory
  +      to factories.  If you want to change the timestamping or other
  +      characteristics of the connections that are given out from the pool, look
  +      in jdbc.  The logic around XA connections is split between xa (for the
  +      JDBC 1/2 wrappers) and the XA factory in factories (which registers with
  +      the current transaction, etc.).</P>
  +
  +    <H3>Object Pools</H3>
  +    <P>At heart, Minerva is a pooling scheme for any type of objects.  The
  +      problem was, JDBC 1/2 pools need to pool java.sql.Connections, while
  +      XA pools need to pool javax.sql.XAConnections.  Even though in the end,
  +      you get a Connection either way.  (See the JDBC 2 Standard Extension
  +      document section 7.3.1)</P>
  +    <P>The easiest way to implement this is as a generic Object pool.  So
  +      there's a class that can pool anything, and an abstract base class for an
  +      Object Factory that creates (and destroys) the object for the pool.  The
  +      factory turns out to be fairly complex if you override all the methods --
  +      you don't have to actually return the exact object in the pool, you can
  +      process things going in and out, etc.  But for a basic implementation, all
  +      you have to do is override createObject and return whatever kind of
  +      objects you want to pool.</P>
  +    <P>There's also an interface (PooledObject) that an object in the pool can
  +      implement to activate some additional functionality.  For example, when
  +      a PooledObject sends a close or error event, the pool will automatically
  +      take the correct action.  Otherwise, you have to return things to the
  +      pool by hand, manually update last-used times, etc.  You can do the same
  +      things either way, it's just a matter of what works best for the specific
  +      objects you're pooling.</P>
  +    <P>So to create a pool, you need the class of the instances you're going to
  +      pool, and a factory to create those instances.  Plug the factory in to the
  +      ObjectPool, set some parameters (size, etc.), and voila!  You have a pool.</P>
  +
  +    <H3>Pool Parameters</H3>
  +
  +<P>I was about to rewrite descriptions of all the pool parameters, but it's already
  +  in the JavaDoc for ObjectPool. Just look at all the setters.</P>
  +
  +    <H3>JDBC Helpers</H3>
  +    <P>The JDBC class has wrapper classes that manage things like: returning a
  +      connection to the pool when it's closed, updating the last-used timestamp
  +      when a connection or child object is used, sending notifications when a
  +      SQLException crops up, etc.  It has been suggested that these could be
  +      proxies instead of full-blown classes, but there are a fair number of
  +      methods overridden...</P>
  +
  +    <H3>JDBC 1/2 Wrappers for XAConnections</H3>
  +    <P>The xa package holds the things that make a JDBC 1/2 connection look like
  +      an XAConnection.  There are implementations of all the XA classes, hooks
  +      into the JDBC wrappers mentioned above, and so on.  However, note that
  +      some of the logic dealing directly with pools lives in the pooled object
  +      factory for XAConnections.</P>
  +    <P>Basically, each java.sql.Connection gets wrapped by an XAConnection and
  +      XAResource, which stay with it for as long as it's in the pool.  They make
  +      one-off java.sql.Connection instances each time the client requests one,
  +      which die when they are closed by the client (so the client can't hook
  +      into a connection after closing it by just stashing the reference
  +      somewhere).  The factory registers the XAResource with the
  +      TransactionManager when it's given out from the pool, and deregisters it
  +      when it's returned.  The XAResource explodes if you try to use it for a
  +      new transaction before the old one has been committed or rolled back
  +      (since the underlying connections don't support that).</P>
  +
  +    <HR><BR>
  +    <H2><A NAME="examples">Minerva Examples</A></H2>
  +
  +    <H4><A NAME="ex1">Creating a JDBC Pool</A></H4>
  +    <PRE>
  +JDBCPoolDataSource source = new JDBCPoolDataSource();
  +source.setPoolName(poolName);
  +source.setJDBCURL(url);
  +source.setJDBCUser(username);
  +source.setJDBCPassword(password);
  +source.setMinSize(minSize);
  +source.setMaxSize(maxSize);
  +source.initialize();
  +    </PRE>
  +
  +    <H4><A NAME="ex2">Getting a JDBC Pool connection directly</A></H4>
  +    <PRE>
  +JDBCPoolDataSource source = ...
  +Connection con = source.getConnection();
  +    </PRE>
  +
  +    <H4><A NAME="ex3">Getting a JDBC Pool connection from JNDI</A></H4>
  +    <PRE>
  +JDBCPoolDataSource source = ...
  +source.setJNDIName("jdbc/pool-"+source.getPoolName());
  +source.initialize();
  +...
  +DataSource ds = (DataSource)context.lookup("jdbc/pool-PoolName");
  +Connection con = ds.getConnection();
  +    </PRE>
  +
  +    <H4><A NAME="ex4">Getting a JDBC Pool connection from the DriverManager</A></H4>
  +    <PRE>
  +JDBCPoolDataSource source = ...
  +Connection con = DriverManager.getConnection("jdbc:minerva:PoolName");
  +    </PRE>
  +
  +    <H4><A NAME="ex5">Creating a JDBC Standard Extension (<B>S.E.</B>) Pool</A></H4>
  +    <PRE>
  +XADataSource vendorSource = ... // Could use org.jboss.minerva.xa.XADataSourceImpl
  +XAPoolDataSource = new XAPoolDataSource();
  +source.setPoolName(poolName);
  +source.setDataSource(vendorSource);
  +source.setJDBCUser(username);
  +source.setJDBCPassword(password);
  +source.setMinSize(minSize.intValue());
  +source.setMaxSize(maxSize.intValue());
  +source.setTransactionManagerJNDIName("TransactionManager");
  +source.initialize();                 //  ^^^  Name depends on your container
  +    </PRE>
  +
  +    <H4><A NAME="ex6">Getting a JDBC S.E. Pool connection directly</A></H4>
  +    <PRE>
  +XAPoolDataSource = ...
  +Connection con = source.getConnection();
  +    </PRE>
  +
  +    <H4><A NAME="ex7">Getting a JDBC S.E. Pool connection from JNDI</A></H4>
  +    <PRE>
  +XAPoolDataSource = ...
  +source.setJNDIName("jdbc/xapool-"+source.getPoolName());
  +source.initialize();
  +...
  +DataSource ds = (DataSource)context.lookup("jdbc/xapool-PoolName");
  +Connection con = ds.getConnection();
  +    </PRE>
  +
  +    <H4><A NAME="ex8">Getting a JDBC S.E. Pool connection from the 
DriverManager</A></H4>
  +    <PRE>
  +XAPoolDataSource = ...
  +Connection con = DriverManager.getConnection("jdbc:minervaxa:PoolName");
  +    </PRE>
  +
  +    <H4><A NAME="ex9">Configuring a JDBC S.E. Pool with jBoss and a JDBC S.E. 
Driver</A></H4>
  +    <P>This will result in the pool's DataSource living in JNDI under the name
  +      <B>xa.PoolName</B>.</P>
  +    <P>In <B>jboss.conf</B>:</P>
  +    <PRE>
  +&lt;MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar,vendor.jar" 
CODEBASE="../lib/ext/"&gt;
  +    &lt;ARG TYPE="java.lang.String" VALUE="PoolName"&gt;
  +    &lt;ARG TYPE="java.lang.String" VALUE="VendorXADataSourceClassName"&gt;
   &lt;/MLET&gt;
  -</PRE>
  -<P>And here's the same thing (without pool parameters) using the native Oracle
  -  XADataSource driver.  Note this is not recommended with the 8.1.6.0.1 release,
  -  as the driver does not generate connection error events, so the connections
  -  are never returned to the pool if there's a SQLException.  You still need to
  -  provide connection parameters for the vendor pool implementation.</P>
  -<PRE>
  -&lt;MLET CODE = "org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar,minerva.jar" 
CODEBASE="../lib/ext/"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE="TestOraclePool"&gt;
  -   &lt;ARG TYPE="java.lang.String" 
VALUE="oracle.jdbc.xa.client.OracleXADataSource"&gt;
  -   &lt;ARG TYPE="java.lang.String" 
VALUE="jdbc:oracle:thin:@host.domain.com:1521:instance"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE="user"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE="password"&gt;
  -   &lt;ARG TYPE="java.lang.String" VALUE=""&gt;
  -   &lt;ARG TYPE="java.lang.Integer" VALUE="2"&gt;
  -   &lt;ARG TYPE="java.lang.Integer" VALUE="5"&gt;
  +    </PRE>
  +    <P>In <B>jboss.jcml</B>:</P>
  +    <PRE>
  +&lt;mbean name="DefaultDomain:service=XADataSource,name=PoolName"&gt;
  +    &lt;attribute name="URL"&gt;jdbc:VendorURL&lt;/attribute&gt;
  +    &lt;attribute name="JDBCUser"&gt;user&lt;/attribute&gt;
  +    &lt;attribute name="Password"&gt;password&lt;/attribute&gt;
  +&lt;/mbean&gt;
  +    </PRE>
  +    <P>You'll notice that after you run jBoss with a jboss.jcml like the one
  +      above, it will update your jboss.jcml to list all the available
  +      properties for the XADataSource, with their default values.  If the
  +      vendor uses properties other than URL, username, and password to configure
  +      their XADataSource, you'll have to use the "properties" attribute to
  +      list them (in the form "name=value;name=value" etc.).</P>
  +
  +    <H4><A NAME="ex10">Configuring a JDBC S.E. Pool with jBoss and a JDBC 1/2 
Driver</A></H4>
  +    <P>This will result in the pool's DataSource living in JNDI under the name
  +      <B>xa.PoolName</B>.</P>
  +    <P>In <B>jboss.conf</B>:</P>
  +    <PRE>
  +&lt;MLET CODE="org.jboss.jdbc.XADataSourceLoader" ARCHIVE="jboss.jar,vendor.jar" 
CODEBASE="../lib/ext/"&gt;
  +    &lt;ARG TYPE="java.lang.String" VALUE="PoolName"&gt;
  +    &lt;ARG TYPE="java.lang.String" 
VALUE="org.jboss.minerva.xa.XADataSourceImpl"&gt;
   &lt;/MLET&gt;
  -</PRE>
  +    </PRE>
  +    <P>In <B>jboss.jcml</B>:</P>
  +    <PRE>
  +&lt;mbean name="DefaultDomain:service=XADataSource,name=PoolName"&gt;
  +    &lt;attribute name="URL"&gt;jdbc:JDBC1/2URL&lt;/attribute&gt;
  +    &lt;attribute name="JDBCUser"&gt;user&lt;/attribute&gt;
  +    &lt;attribute name="Password"&gt;password&lt;/attribute&gt;
  +&lt;/mbean&gt;
  +    </PRE>
  +    <P>You'll notice that after you run jBoss with a jboss.jcml like the one
  +      above, it will update your jboss.jcml to list all the available
  +      properties for the XADataSource, with their default values.  If the
  +      JDBC 1/2 driver uses properties other than URL, username, and password to
  +      connect, you'll have to use the "properties" attribute to list them (in
  +      the form "name=value;name=value" etc.).</P>
  +
  +    <H4><A NAME="ex11">Configuring an Enterprise Java Bean with a 
DataSource</A></H4>
  +    <P>You need to add a resource reference to your ejb-jar.xml file.  The
  +      requirement and XML syntax is standard across all containers - but each
  +      container has a different GUI for configuring this if you don't do it
  +      manually.  The key parts here are that you specify a resource reference
  +      of type <B>javax.sql.DataSource</B>, and you give it the name you expect
  +      to see in JNDI.  So, in the example below, if you call it <B>TestDB</B>,
  +      it will be in JNDI under <B>java:comp/env/TestDB</B>.  However, you'll
  +      need to do something container-specific to match this up with a specific
  +      database pool.</P>
  +    <PRE>
  +&lt;resource-ref&gt;
  +    &lt;description&gt;Test Database&lt;/description&gt;
  +    &lt;res-ref-name&gt;TestDB&lt;/res-ref-name&gt;
  +    &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
  +    &lt;res-auth&gt;Container&lt;/res-auth&gt;
  +&lt;/resource-ref&gt;
  +    </PRE>
  +
  +    <H4><A NAME="ex12">Linking the EJB DataSource to a Minerva Pool with 
jBoss</A></H4>
  +    <P>The easiest way to do this is to use EJX.  You need to add a resource
  +      manager that links the EJB ref-name (<A HREF="#ex11">see example above</A>)
  +      to the database pool JNDI name (<A HREF="#ex9">see example above</A>).
  +      Since the database pool JNDI name is <I>xa.PoolName</I> that should be
  +      your resource jndi name, and the name in ejb-jar.xml should be the
  +      resource name.</P>
  +    <P>If you don't use EJX, you will need to add the reference manually in two
  +      places - first at the top level of jboss.xml, and then again at the bean
  +      level for each bean that uses the resource.  Technically you can give the
  +      resource manager a different name that the bean expects, and use the
  +      bean-specific name with the resource manager name in the bean-level entry.
  +      This is only recommended if you have multiple beans in the JAR that have
  +      different resource names but can all be served by the same database pool.
  +      </P>
  +    <PRE>
  +&lt;resource-managers&gt;
  +    &lt;resource-manager res-class="org.jboss.ejb.deployment.JDBCResource"&gt;
  +        &lt;res-name&gt;TestDB&lt;/res-name&gt;
  +        &lt;res-jndi-name&gt;xa.TestPool&lt;/res-jndi-name&gt;
  +    &lt;/resource-manager&gt;
  +&lt;/resource-managers&gt;
  +
  +&lt;enterprise-beans&gt;
  +    &lt;session&gt;
  +        &lt;resource-ref&gt;
  +            &lt;res-ref-name&gt;TestDB&lt;/res-ref-name&gt;
  +            &lt;resource-name&gt;TestDB&lt;/resource-name&gt;
  +        &lt;/resource-ref&gt;
  +    ...
  +    &lt;session&gt;
  +        &lt;resource-ref&gt;
  +            &lt;res-ref-name&gt;OtherDB&lt;/res-ref-name&gt;
  +            &lt;resource-name&gt;TestDB&lt;/resource-name&gt;
  +        &lt;/resource-ref&gt;
  +    ...
  +    </PRE>
  +
  +    <H4><A NAME="ex13">Getting a connection in an EJB implementation</A></H4>
  +    <PRE>
  +Context naming = new InitialContext();
  +DataSource ds = (DataSource)naming.lookup("java:comp/env/"+poolName);
  +Connection con = ds.getConnection();
  +    </PRE>
  +
  +    <H4><A NAME="ex14">Creating a pool for a generic Object type</A></H4>
  +    <PRE>
  +PoolObjectFactory myFactory = new MyPoolObjectFactory();
  +... // Configure Factory
  +ObjectPool pool = new ObjectPool(myFactory, "MyPoolName");
  +... // Configure Pool
  +pool.initialize();
  +    </PRE>
  +
  +    <H4><A NAME="ex15">Getting and returning Objects</A></H4>
  +    <PRE>
  +ObjectPool pool = ...
  +MyObject o = (MyObject)pool.getObject();
  +...
  +pool.releaseObject(o);
  +    </PRE>
  +
  +    <H4><A NAME="ex16">Getting and returning PooledObjects</A></H4>
  +    <PRE>
  +ObjectPool pool = ...
  +MyObject o = (MyObject)pool.getObject();
  +...
  +o.close();  // Assumes that a PoolEvent(o, PoolEvent.OBJECT_CLOSED) is sent
  +    </PRE>
  +
  +    <HR><BR>
  +    <H2><A NAME="nyi">Outstanding Features</A></H2>
  +    <UL>
  +      <LI>The JDBC 1/2 XA wrapper expects that a connection will be closed
  +        before the transaction is rolled back or committed.  Though this works
  +        well for a container-demarcated transaction environment, it does not
  +        allow full client-demarcated transaction functionality.</LI>
  +      <LI>Last-used updates aren't passed through by JDBC 1/2 XA wrapper</LI>
  +      <LI>Last-used updates aren't implemented for CallableStatements</LI>
  +    </UL>
   
  -<H4>Specify Resource Managers</H4>
  -<P>The pools you configured are bound in JNDI to  "jdbc.<I>PoolName</I>" for
  -JDBC 1.0 pools (not described), or "xa.<I>PoolName</I>" for transactional pools
  -(described above).  <I>These names will probably change in the future!</I></P>
  -<P>You can add perform all of the following configuration in EJX, but I give
  -XML samples for completeness.</p>
  -<P>To create a ResourceManager, add an entry to <B>jboss.xml</B> that looks like
  -the following (just include the resource-manager if you already have the
  -resource-managers section!):</P>
  -<PRE>
  -     &lt;resource-managers&gt;
  -       &lt;resource-manager res-class="org.jboss.ejb.deployment.JDBCResource"&gt;
  -         &lt;res-name&gt;MyPooledDB&lt;/res-name&gt;
  -         &lt;res-jndi-name&gt;xa.<I>PoolName</I>&lt;/res-jndi-name&gt;
  -       &lt;/resource-manager&gt;
  -     &lt;/resource-managers&gt;
  -</PRE>
  -
  -<H4>Specify Resource for each Bean</H4>
  -<P>Also in <B>jboss.xml</B>, within the beans you would like to access this
  -pool, add a resource-ref entry.  The res-ref-name should match the res-name
  -specified above, and the resource-name is the name your bean will use to access
  -this resource.  Here's the sample (relevant addition in italics):</P>
  -<PRE>
  -     &lt;enterprise-beans&gt;
  -       &lt;session&gt;
  -         &lt;ejb-name&gt;SomeBean&lt;/ejb-name&gt;
  -         &lt;jndi-name&gt;SomeBean&lt;/jndi-name&gt;
  -         &lt;configuration-name&gt;Default Stateless 
SessionBean&lt;/configuration-name&gt;
  -         <I>&lt;resource-ref&gt;
  -           &lt;res-ref-name&gt;ResourceResName&lt;/res-ref-name&gt;
  -           &lt;resource-name&gt;BeansDBName&lt;/resource-name&gt;
  -         &lt;/resource-ref&gt;</I>
  -       &lt;/session&gt;
  -       &lt;secure&gt;true&lt;/secure&gt;
  -     &lt;/enterprise-beans&gt;
  -</PRE>
  -<P>Finally, within your <B>ejb-jar.xml</B> you need to add a resource reference
  -  for each bean that will use the pool:</P>
  -<PRE>
  -      &lt;resource-ref&gt;
  -        &lt;description&gt;Database&lt;/description&gt;
  -        &lt;res-ref-name&gt;ResourceResName&lt;/res-ref-name&gt;
  -        &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
  -        &lt;res-auth&gt;Container&lt;/res-auth&gt;
  -      &lt;/resource-ref&gt;
  -</PRE>
  -<P>Currently, the name used in ejb-jar.xml res-ref-name must match the name
  -  used in jboss.xml res-ref-name, and the name used in jboss.xml resource-name
  -  must match the name used in jboss.xml res-name.  The client sees the latter
  -  as the java:comp/env/ JNDI name, so it's easiest to make all 4 names
  -  match.  <I>This big was fixed recently, but may not be in the binary build
  -  yet - please make all 4 names match for now!</I></P>
  -
  -<HR>
  -
  -<H3><A NAME="client">Using the JDBC Connection Pool test EJB and client in jBoss 
2.0</A></H3>
  -<P>There is a SQLTest.jar and a SQLClient.jar included with this
  -package.  To run the tests, add an MLET tag for the test pool to your jboss.conf
  -and then put SQLTest.jar in your jBoss deployment directory.  If it deploys
  -correctly, add SQLClient.jar, jboss-client.jar, jnp-client.jar, ejb.jar, and
  -jndi.properties to your client classpath, and run com.mearaworks.sql.SQLClient.
  -Or take the easy route and put SQLClient.jar in you jboss/dist/client directory
  -and run it with "java -jar SQLClient.jar".  It will give you a SQL&gt; propmt,
  -from which you may execute multi-line SQL queries against the connections in the
  -pool.  It is fairly simple-minded - anything that starts with "select" is
  -executed as a query, otherwise as an update, and any SQL errors will cause it to
  -exit.  But if you can successfully run simple queries, your pool is working!</P>
  -<P><I>A note on names:</I> You must either name your pool "TestPool" or update
  -the jboss.xml distributed in SQLTest.jar to make the Resource "TestDB" map to
  -your pool name for the SQLTest bean.</P>
  -
  -<HR>
  -
  -<H3><A NAME="bugs">Outstanding Features/Bugs</A></H3>
  -<UL>
  -<LI>Last-used updates aren't implemented for prepared statements and callable
  -  statements.</LI>
  -<LI>Last-used updates aren't passed through by XAClientConnection even if
  -  they're activated for the pool.</LI>
  -<LI>JDBC 1.0 wrappers for XAConnections don't provide error notification on
  -  ResultSet, PreparedStatement, or CallableStatement operations.</LI>
  -<LI>JDBC 1.0 wrappers for XAConnections don't return the same connection for
  -  every getXAConnection request for a particular transaction (Xid).</LI>
  -<LI>MBeans for jBoss have an awfully unintuitive interface</LI>
  -<LI>Document JDBC 1 interface and generic Object Pool interface</LI>
  -<LI>Exception-handling does not yet follow the spec - on a recognized
  -  SQLException, the connection is automatically returned to the pool.  This will
  -  likely cause errors with SQLExceptions in the midst of a rollback or commit
  -  (since then the connection will be returned twice!)</LI>
  -<LI>Connections are not removed from the pool in the case of a failure during
  -  commit or rollback (JDBC 1 and JDBC 2 wrappers).</LI>
  -</UL>
  -</BODY>
  +  </BODY>
   </HTML>
  
  
  

Reply via email to