1 <!doctype html>
   2 <html lang="en">
   3 <head>
   4 
   5   <meta http-equiv="Content-Type"
   6  content="text/html; charset=iso-8859-1">
   7 
   8   <meta name="GENERATOR"
   9  content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
  10 <!--
  11 Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  12 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  13 
  14 This code is free software; you can redistribute it and/or modify it
  15 under the terms of the GNU General Public License version 2 only, as
  16 published by the Free Software Foundation.  Oracle designates this
  17 particular file as subject to the "Classpath" exception as provided
  18 by Oracle in the LICENSE file that accompanied this code.
  19 
  20 This code is distributed in the hope that it will be useful, but WITHOUT
  21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  22 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  23 version 2 for more details (a copy is included in the LICENSE file that
  24 accompanied this code).
  25 
  26 You should have received a copy of the GNU General Public License version
  27 2 along with this work; if not, write to the Free Software Foundation,
  28 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  29 
  30 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  31 or visit www.oracle.com if you need additional information or have any
  32 questions.
  33 -->
  34   <title>javax.sql.rowset.spi</title>
  35 
  36 </head>
  37   <body>
  38 
  39 The standard classes and interfaces that a third party vendor has to
  40 use in its implementation of a synchronization provider. These classes and
  41 interfaces are referred to as the Service Provider Interface (SPI).  To make it possible
  42 for a <code>RowSet</code> object to use an implementation, the vendor must register
  43 it with the <code>SyncFactory</code> singleton. (See the class comment for
  44 <code>SyncProvider</code> for a full explanation of the registration process and
  45 the naming convention to be used.)
  46 
  47 <h2>Table of Contents</h2>
  48 <ul>
  49 <li><a href="#pkgspec">1.0 Package Specification</a>
  50 <li><a href="#arch">2.0 Service Provider Architecture</a>
  51 <li><a href="#impl">3.0 Implementer's Guide</a>
  52 <li><a href="#resolving">4.0 Resolving Synchronization Conflicts</a>
  53 <li><a href="#relspec">5.0 Related Specifications</a>
  54 <li><a href="#reldocs">6.0 Related Documentation</a>
  55 </ul>
  56 
  57 <h3><a id="pkgspec">1.0 Package Specification</a></h3>
  58 <P>
  59 The following classes and interfaces make up the <code>javax.sql.rowset.spi</code>
  60 package:
  61 <UL>
  62   <LI><code>SyncFactory</code>
  63   <LI><code>SyncProvider</code>
  64   <LI><code>SyncFactoryException</code>
  65   <LI><code>SyncProviderException</code>
  66   <LI><code>SyncResolver</code>
  67   <LI><code>XmlReader</code>
  68   <LI><code>XmlWriter</code>
  69   <LI><code>TransactionalWriter</code>
  70 </UL>
  71 The following interfaces, in the <code>javax.sql</code> package, are also part of the SPI:
  72 <UL>
  73   <LI><code>RowSetReader</code>
  74   <LI><code>RowSetWriter</code>
  75 </UL>
  76 <P>
  77 A <code>SyncProvider</code> implementation provides a disconnected <code>RowSet</code>
  78 object with the mechanisms for reading data into it and for writing data that has been
  79 modified in it
  80 back to the underlying data source.  A <i>reader</i>, a <code>RowSetReader</code> or
  81 <code>XMLReader</code> object, reads data into a <code>RowSet</code> object when the
  82 <code>CachedRowSet</code> methods <code>execute</code> or <code>populate</code>
  83 are called.  A <i>writer</i>, a <code>RowSetWriter</code> or <code>XMLWriter</code>
  84 object, writes changes back to the underlying data source when the
  85 <code>CachedRowSet</code> method <code>acceptChanges</code> is called.
  86 <P>
  87 The process of writing changes in a <code>RowSet</code> object to its data source
  88 is known as <i>synchronization</i>.  The <code>SyncProvider</code> implementation that a
  89 <code>RowSet</code> object is using determines the level of synchronization that the
  90 <code>RowSet</code> object's writer uses. The various levels of synchronization are
  91 referred to as <i>grades</i>.
  92 <P>
  93 The lower grades of synchronization are
  94 known as <i>optimistic</i> concurrency levels because they optimistically
  95 assume that there will be no conflicts or very few conflicts.  A conflict exists when
  96 the same data modified in the <code>RowSet</code> object has also been modified
  97 in the data source. Using the optimistic concurrency model means that if there
  98 is a conflict, modifications to either the data source or the <code>RowSet</code>
  99 object will be lost.
 100 <P>
 101 Higher grades of synchronization are called <i>pessimistic</i> because they assume
 102 that others will be accessing the data source and making modifications.  These
 103 grades set varying levels of locks to increase the chances that no conflicts
 104 occur.
 105 <P>
 106 The lowest level of synchronization is simply writing any changes made to the
 107 <code>RowSet</code> object to its underlying data source.  The writer does
 108 nothing to check for conflicts.
 109 If there is a conflict and the data
 110 source values are overwritten, the changes other parties have made by to the data
 111 source are lost.
 112 <P>
 113 The <code>RIXMLProvider</code> implementation uses the lowest level
 114 of synchronization and just writes <code>RowSet</code> changes to the data source.
 115 
 116 <P>
 117 For the next level up, the
 118 writer checks to see if there are any conflicts, and if there are,
 119 it does not write anything to the data source.  The problem with this concurrency
 120 level is that if another party has modified the corresponding data in the data source
 121 since the <code>RowSet</code> object got its data,
 122 the changes made to the <code>RowSet</code> object are lost. The
 123 <code>RIOptimisticProvider</code> implementation uses this level of synchronization.
 124 <P>
 125 At higher levels of synchronization, referred to as pessimistic concurrency,
 126 the writer take steps to avoid conflicts by setting locks. Setting locks
 127 can vary from setting a lock on a single row to setting a lock on a table
 128 or the entire data source. The level of synchronization is therefore a tradeoff
 129 between the ability of users to access the data source concurrently and the  ability
 130 of the writer to keep the data in the <code>RowSet</code> object and its data source
 131 synchronized.
 132 <P>
 133 It is a requirement that all disconnected <code>RowSet</code> objects
 134 (<code>CachedRowSet</code>, <code>FilteredRowSet</code>, <code>JoinRowSet</code>,
 135 and <code>WebRowSet</code> objects) obtain their <code>SyncProvider</code> objects
 136 from the <code>SyncFactory</code> mechanism.
 137 <P>
 138 The reference implementation (RI) provides two synchronization providers.
 139     <UL>
 140        <LI><b><code>RIOptimisticProvider</code></b> <br>
 141            The default provider that the <code>SyncFactory</code> instance will
 142            supply to a disconnected <code>RowSet</code> object when no provider
 143            implementation is specified.<BR>
 144            This synchronization provider uses an optimistic concurrency model,
 145            assuming that there will be few conflicts among users
 146            who are accessing the same data in a database.  It avoids
 147            using locks; rather, it checks to see if there is a conflict
 148            before trying to synchronize the <code>RowSet</code> object and the
 149            data source. If there is a conflict, it does nothing, meaning that
 150            changes to the <code>RowSet</code> object are not persisted to the data
 151            source.
 152        <LI><B><code>RIXMLProvider</code></B> <BR>
 153             A synchronization provider that can be used with a
 154             <code>WebRowSet</code> object, which is a rowset that can be written
 155             in XML format or read from XML format. The
 156             <code>RIXMLProvider</code> implementation does no checking at all for
 157             conflicts and simply writes any updated data in the
 158             <code>WebRowSet</code> object to the underlying data source.
 159             <code>WebRowSet</code> objects use this provider when they are
 160             dealing with XML data.
 161     </UL>
 162 
 163 These <code>SyncProvider</code> implementations
 164 are bundled with the reference implementation, which makes them always available to
 165 <code>RowSet</code> implementations.
 166 <code>SyncProvider</code> implementations make themselves available by being
 167 registered with the <code>SyncFactory</code> singleton.  When a <code>RowSet</code>
 168 object requests a provider, by specifying it in the constructor or as an argument to the
 169 <code>CachedRowSet</code> method <code>setSyncProvider</code>,
 170 the <code>SyncFactory</code> singleton
 171 checks to see if the requested provider has been registered with it.
 172 If it has, the <code>SyncFactory</code> creates an instance of it and passes it to the
 173 requesting <code>RowSet</code> object.
 174 If the <code>SyncProvider</code> implementation that is specified has not been registered,
 175 the <code>SyncFactory</code> singleton causes a <code>SyncFactoryException</code> object
 176 to be thrown.  If no provider is specified,
 177 the <code>SyncFactory</code> singleton will create an instance of the default
 178 provider implementation, <code>RIOptimisticProvider</code>,
 179 and pass it to the requesting <code>RowSet</code> object.
 180 
 181 <P>
 182 If a <code>WebRowSet</code> object does not specify a provider in its constructor, the
 183 <code>SyncFactory</code> will give it an instance of <code>RIOptimisticProvider</code>.
 184 However, the constructor for <code>WebRowSet</code> is implemented to set the provider
 185 to the <code>RIXMLProvider</code>, which reads and writes a <code>RowSet</code> object
 186 in XML format.
 187 <P>
 188 See the <a href="SyncProvider.html">SyncProvider</a> class
 189 specification for further details.
 190 <p>
 191 Vendors may develop a <code>SyncProvider</code> implementation with any one of the possible
 192 levels of synchronization, thus giving <code>RowSet</code> objects a choice of
 193 synchronization mechanisms.
 194 
 195 <h3><a id="arch">2.0 Service Provider Interface Architecture</a></h3>
 196 <b>2.1 Overview</b>
 197 <p>
 198 The Service Provider Interface provides a pluggable mechanism by which
 199 <code>SyncProvider</code> implementations can be registered and then generated when
 200 required. The lazy reference mechanism employed by the <code>SyncFactory</code> limits
 201 unnecessary resource consumption by not creating an instance until it is
 202 required by a disconnected
 203 <code>RowSet</code> object. The <code>SyncFactory</code> class also provides
 204 a standard API to configure logging options and streams that <b>may</b> be provided
 205 by a particular <code>SyncProvider</code> implementation.
 206 <p>
 207 <b>2.2 Registering with the <code>SyncFactory</code></b>
 208 <p>
 209 A third party <code>SyncProvider</code> implementation must be registered with the
 210 <code>SyncFactory</code> in order for a disconnected <code>RowSet</code> object
 211 to obtain it and thereby use its <code>javax.sql.RowSetReader</code> and
 212 <code>javax.sql.RowSetWriter</code>
 213 implementations. The following registration mechanisms are available to all
 214 <code>SyncProvider</code> implementations:
 215 <ul>
 216 <li><b>System properties</b> - Properties set at the command line. These
 217 properties are set at run time and apply system-wide per invocation of the Java
 218 application. See the section <a href="#reldocs">"Related Documentation"</a>
 219 further related information.
 220 
 221 <li><b>Property Files</b> - Properties specified in a standard property file.
 222 This can be specified using a System Property or by modifying a standard
 223 property file located in the platform run-time. The
 224 reference implementation of this technology includes a standard property
 225 file than can be edited to add additional <code>SyncProvider</code> objects.
 226 
 227 <li><b>JNDI Context</b> - Available providers can be registered on a JNDI
 228 context. The <code>SyncFactory</code> will attempt to load <code>SyncProvider</code>
 229 objects bound to the context and register them with the factory. This
 230 context must be supplied to the <code>SyncFactory</code> for the mechanism to
 231 function correctly.
 232 </ul>
 233 <p>
 234 Details on how to specify the system properties or properties in a property file
 235 and how to configure the JNDI Context are explained in detail in the
 236 <a href="SyncFactory.html"><code>SyncFactory</code></a> class description.
 237 <p>
 238 <b>2.3 SyncFactory Provider Instance Generation Policies</b>
 239 <p>
 240 The <code>SyncFactory</code> generates a requested <code>SyncProvider</code>
 241 object if the provider has been correctly registered.  The
 242 following policies are adhered to when either a disconnected <code>RowSet</code> object
 243 is instantiated with a specified <code>SyncProvider</code> implementation or is
 244 reconfigured at runtime with an alternative <code>SyncProvider</code> object.
 245 <ul>
 246 <li> If a <code>SyncProvider</code> object is specified and the <code>SyncFactory</code>
 247 contains <i>no</i> reference to the provider, a <code>SyncFactoryException</code> is
 248 thrown.
 249 
 250 <li> If a <code>SyncProvider</code> object is specified and the <code>SyncFactory</code>
 251 contains a reference to the provider, the requested provider is supplied.
 252 
 253 <li> If no <code>SyncProvider</code> object is specified, the reference
 254 implementation provider <code>RIOptimisticProvider</code> is supplied.
 255 </ul>
 256 <p>
 257 These policies are explored in more detail in the <a href="SyncFactory.html">
 258 <code>SyncFactory</code></a> class.
 259 
 260 <h3><a id="impl">3.0 SyncProvider Implementer's Guide</a></h3>
 261 
 262 <b>3.1 Requirements</b>
 263 <p>
 264 A compliant <code>SyncProvider</code> implementation that is fully pluggable
 265 into the <code>SyncFactory</code> <b>must</b> extend and implement all
 266 abstract methods in the <a href="SyncProvider.html"><code>SyncProvider</code></a>
 267 class. In addition, an implementation <b>must</b> determine the
 268 grade, locking and updatable view capabilities defined in the
 269 <code>SyncProvider</code> class definition. One or more of the
 270 <code>SyncProvider</code> description criteria <b>must</b> be supported. It
 271 is expected that vendor implementations will offer a range of grade, locking, and
 272 updatable view capabilities.
 273 <p>
 274 Furthermore, the <code>SyncProvider</code> naming convention <b>must</b> be followed as
 275 detailed in the <a href="SyncProvider.html"><code>SyncProvider</code></a> class
 276 description.
 277 <p>
 278 <b>3.2 Grades</b>
 279 <p>
 280 JSR 114 defines a set of grades to describe the quality of synchronization
 281 a <code>SyncProvider</code> object can offer a disconnected <code>RowSet</code>
 282 object. These grades are listed from the lowest quality of service to the highest.
 283 <ul>
 284 <li><b>GRADE_NONE</b> - No synchronization with the originating data source is
 285 provided. A <code>SyncProvider</code> implementation returning this grade will simply
 286 attempt to write any data that has changed in the <code>RowSet</code> object to the
 287 underlying data source, overwriting whatever is there. No attempt is made to compare
 288 original values with current values to see if there is a conflict. The
 289 <code>RIXMLProvider</code> is implemented with this grade.
 290 
 291 <li><b>GRADE_CHECK_MODIFIED_AT_COMMIT</b> - A low grade of optimistic synchronization.
 292 A <code>SyncProvider</code> implementation returning this grade
 293 will check for conflicts in rows that have changed between the last synchronization
 294 and the current synchronization under way. Any changes in the originating data source
 295 that have been modified will not be reflected in the disconnected <code>RowSet</code>
 296 object. If there are no conflicts, changes in the <code>RowSet</code> object will be
 297 written to the data source. If there are conflicts, no changes are written.
 298 The <code>RIOptimisticProvider</code> implementation uses this grade.
 299 
 300 <li><b>GRADE_CHECK_ALL_AT_COMMIT</b> - A high grade of optimistic synchronization.
 301 A <code>SyncProvider</code> implementation   returning this grade
 302 will check all rows, including rows that have not changed in the disconnected
 303 <code>RowSet</code> object. In this way, any changes to rows in the underlying
 304 data source will be reflected in the disconnected <code>RowSet</code> object
 305 when the synchronization finishes successfully.
 306 
 307 <li><b>GRADE_LOCK_WHEN_MODIFIED</b> - A pessimistic grade of synchronization.
 308 <code>SyncProvider</code> implementations returning this grade will lock
 309 the row in the originating  data source that corresponds to the row being changed
 310 in the <code>RowSet</code> object to reduce the possibility of other
 311 processes modifying the same data in the data source.
 312 
 313 <li><b>GRADE_LOCK_WHEN_LOADED</b> - A higher pessimistic synchronization grade.
 314 A <code>SyncProvider</code> implementation returning this grade will lock
 315 the entire view and/or  table affected by the original query used to
 316 populate a <code>RowSet</code> object.
 317 </ul>
 318 <p>
 319 <b>3.3 Locks</b>
 320 <p>
 321 JSR 114 defines a set of constants that specify whether any locks have been
 322 placed on a <code>RowSet</code> object's underlying data source and, if so,
 323 on which constructs the locks are placed.  These locks will remain on the data
 324 source while the <code>RowSet</code> object is disconnected from the data source.
 325 <P>
 326 These constants <b>should</b> be considered complementary to the
 327 grade constants. The default setting for the majority of grade settings requires
 328 that no data source locks remain when a <code>RowSet</code> object is disconnected
 329 from its data source.
 330 The grades <code>GRADE_LOCK_WHEN_MODIFIED</code> and
 331 <code>GRADE_LOCK_WHEN_LOADED</code> allow a disconnected <code>RowSet</code> object
 332 to have a fine-grained control over the degree of locking.
 333 <ul>
 334 <li><b>DATASOURCE_NO_LOCK</b> - No locks remain on the originating data source.
 335 This is the default lock setting for all <code>SyncProvider</code> implementations
 336 unless otherwise directed by a <code>RowSet</code> object.
 337 
 338 <li><b>DATASOURCE_ROW_LOCK</b> - A lock is placed on the rows that are touched by
 339 the original SQL query used to populate the <code>RowSet</code> object.
 340 
 341 <li><b>DATASOURCE_TABLE_LOCK</b> - A lock is placed on all tables that are touched
 342 by the query that was used to populate the <code>RowSet</code> object.
 343 
 344 <li><b>DATASOURCE_DB_LOCK</b>
 345 A lock is placed on the entire data source that is used by the <code>RowSet</code>
 346 object.
 347 </ul>
 348 <p>
 349 <b>3.4 Updatable Views</b>
 350 <p>
 351 A <code>RowSet</code> object may be populated with data from an SQL <code>VIEW</code>.
 352 The following constants indicate whether a <code>SyncProvider</code> object can
 353 update data in the table or tables from which the <code>VIEW</code> was derived.
 354 <ul>
 355 <li><b>UPDATABLE_VIEW_SYNC</b>
 356 Indicates that a <code>SyncProvider</code> implementation  supports synchronization
 357 to the table or tables from which the SQL <code>VIEW</code> used to populate
 358 a <code>RowSet</code> object is derived.
 359 
 360 <li><b>NONUPDATABLE_VIEW_SYNC</b>
 361 Indicates that a <code>SyncProvider</code> implementation  does <b>not</b> support
 362 synchronization to the table or tables from which the SQL <code>VIEW</code>
 363 used to populate  a <code>RowSet</code> object is derived.
 364 </ul>
 365 <p>
 366 <b>3.5 Usage of <code>SyncProvider</code> Grading and Locking</b>
 367 <p>
 368 In the example below, the reference <code>CachedRowSetImpl</code> implementation
 369 reconfigures its current <code>SyncProvider</code> object by calling the
 370 <code>setSyncProvider</code> method.<br>
 371 
 372 <PRE>
 373     CachedRowSetImpl crs = new CachedRowSetImpl();
 374     crs.setSyncProvider("com.foo.bar.HASyncProvider");
 375 </PRE>
 376     An application can retrieve the <code>SyncProvider</code> object currently in use
 377 by a disconnected <code>RowSet</code> object. It can also retrieve the
 378 grade of synchronization with which the provider was implemented and the degree of
 379 locking currently in use.  In addition, an application has the flexibility to set
 380 the degree of locking to be used, which can increase the possibilities for successful
 381 synchronization.  These operation are shown in the following code fragment.
 382 <PRE>
 383     SyncProvider sync = crs.getSyncProvider();
 384 
 385     switch (sync.getProviderGrade()) {
 386     case: SyncProvider.GRADE_CHECK_ALL_AT_COMMIT
 387          //A high grade of optimistic synchronization
 388     break;
 389     case: SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT
 390          //A low grade of optimistic synchronization
 391     break;
 392     case: SyncProvider.GRADE_LOCK_WHEN_LOADED
 393          // A pessimistic synchronization grade
 394     break;
 395     case: SyncProvider.GRADE_LOCK_WHEN_MODIFIED
 396          // A pessimistic synchronization grade
 397     break;
 398     case: SyncProvider.GRADE_NONE
 399       // No synchronization with the originating data source provided
 400     break;
 401     }
 402 
 403     switch (sync.getDataSourcLock() {
 404       case: SyncProvider.DATASOURCE_DB_LOCK
 405        // A lock is placed on the entire datasource that is used by the
 406        // <code>RowSet</code> object
 407        break;
 408 
 409       case: SyncProvider.DATASOURCE_NO_LOCK
 410        // No locks remain on the  originating data source.
 411       break;
 412 
 413       case: SyncProvider.DATASOURCE_ROW_LOCK
 414        // A lock is placed on the rows that are  touched by the original
 415        // SQL statement used to populate
 416        // the RowSet object that is using the SyncProvider
 417        break;
 418 
 419       case: DATASOURCE_TABLE_LOCK
 420        // A lock is placed on  all tables that are touched by the original
 421        // SQL statement used to populated
 422        // the RowSet object that is using the SyncProvider
 423        break;
 424 
 425 </PRE>
 426     It is also possible using the static utility method in the
 427 <code>SyncFactory</code> class to determine the list of <code>SyncProvider</code>
 428 implementations currently registered with the <code>SyncFactory</code>.
 429 
 430 <pre>
 431        Enumeration e = SyncFactory.getRegisteredProviders();
 432 </pre>
 433 
 434 
 435 <h3><a id="resolving">4.0 Resolving Synchronization Conflicts</a></h3>
 436 
 437 The interface <code>SyncResolver</code> provides a way for an application to
 438 decide manually what to do when a conflict occurs. When the <code>CachedRowSet</code>
 439 method <code>acceptChanges</code> finishes and has detected one or more conflicts,
 440 it throws a <code>SyncProviderException</code> object.  An application can
 441 catch the exception and
 442 have it retrieve a <code>SyncResolver</code> object by calling the method
 443 <code>SyncProviderException.getSyncResolver()</code>.
 444 <P>
 445 A <code>SyncResolver</code> object, which is a special kind of
 446 <code>CachedRowSet</code> object or
 447 a <code>JdbcRowSet</code> object that has implemented the <code>SyncResolver</code>
 448 interface,  examines the conflicts row by row. It is a duplicate of the
 449 <code>RowSet</code> object being synchronized except that it contains only the data
 450 from the data source this is causing a conflict. All of the other column values are
 451 set to <code>null</code>. To navigate from one conflict value to another, a
 452 <code>SyncResolver</code> object provides the methods <code>nextConflict</code> and
 453 <code>previousConflict</code>.
 454 <P>
 455 The <code>SyncResolver</code> interface also
 456 provides methods for doing the following:
 457 <UL>
 458  <LI>finding out whether the conflict involved an update, a delete, or an insert
 459  <LI>getting the value in the data source that caused the conflict
 460  <LI>setting the value that should be in the data source if it needs to be changed
 461      or setting the value that should be in the <code>RowSet</code> object if it needs
 462      to be changed
 463 </UL>
 464 <P>
 465 When the <code>CachedRowSet</code> method <code>acceptChanges</code> is called, it
 466 delegates to the <code>RowSet</code> object's  <code>SyncProvider</code> object.
 467 How the writer provided by that <code>SyncProvider</code> object is implemented
 468 determines what level (grade) of checking for conflicts will be done.  After all
 469 checking for conflicts is completed and one or more conflicts has been found, the method
 470 <code>acceptChanges</code> throws a <code>SyncProviderException</code> object. The
 471 application can catch the exception and use it to obtain a <code>SyncResolver</code> object.
 472 <P>
 473 The application can then use <code>SyncResolver</code> methods to get information
 474 about each conflict and decide what to do.  If the application logic or the user
 475 decides that a value in the <code>RowSet</code> object should be the one to
 476 persist, the application or user can overwrite the data source value with it.
 477 <P>
 478 The comment for the <code>SyncResolver</code> interface has more detail.
 479 
 480 <h3><a id="relspec">5.0 Related Specifications</a></h3>
 481 <ul>
 482 <li><a href="http://docs.oracle.com/javase/jndi/tutorial/index.html">JNDI</a>
 483 <li><a href="{@docRoot}/java/util/logging/package-summary.html">Java Logging
 484 APIs</a>
 485 </ul>
 486 <h3><a id="reldocs">6.0 Related Documentation</a></h3>
 487 <ul>
 488 <li><a href="http://docs.oracle.com/javase/tutorial/jdbc/">DataSource for JDBC
 489 Connections</a>
 490 </ul>
 491 
 492 </body>
 493 </html>