commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rsi...@apache.org
Subject cvs commit: jakarta-commons/discovery best-practices.html STATUS.html
Date Thu, 18 Jul 2002 18:31:37 GMT
rsitze      2002/07/18 11:31:37

  Added:       discovery best-practices.html STATUS.html
  Log:
  Documents for discovery
  
  Revision  Changes    Path
  1.1                  jakarta-commons/discovery/best-practices.html
  
  Index: best-practices.html
  ===================================================================
  <html>
  <head>
  <title>Best Practices for using Jakarta Commons "Discovery" Component</title>
  <head>
  <body bgcolor="white">
  
  
  <div align="center">
  <h1>Best Practices for using Jakarta Commons "Discovery" Component</h1>
  $Id$<br />
  <a href="#Introduction">[Introduction]</a>
  <a href="#Integrating into Factories : Wrapping">[Integrating into Factories : Wrapping]</a>
  <a href="#Calling Directly">[Calling Directly]</a>
  <a href="#Service Life Cycle Management">[Service Life Cycle Management]</a>
  <br /><br />
  </div>
  
  
  <a name="Introduction"></a>
  <h3>1.  INTRODUCTION</h3>
  
  Best-practices are discussed.
  See the javadoc for detail on the API,
  where service implementation overrides are looked for,
  the order in which those places are checked,
  which classloaders are used,
  and the order in which they are used.
  
  
  <a name="Integrating into Factories : Wrapping"></a>
  <h3>2.  INTEGRATING INTO FACTORIES : WRAPPING</h3>
  
  
  <p>In this example, a factory (such as is used in commons-logging)
  internalizes the discovery mechanism, passing appropriate defaults
  for a default properties file and a default implementation.
  In this case, the factory plays double duty as both the service
  to be discovered (abstract class), and the discovery mechanism.
  </p>
  
  <p>Note the javadoc in the example below which explains
  the parameters.</p>
  
  <ul>
  <code>
  import java.util.Properties;<br>
  import org.apache.commons.discovery.Discovery;<br>
  import org.apache.commons.discovery.DiscoveryException;<br>
  <br>
  public abstract class LogFactory<br>
  {<br>
  &nbsp;&nbsp;&nbsp;&nbsp;protected static final String FACTORY_DEFAULT =<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.apache.commons.logging.impl.DefaultLogFactory.class.getName();<br>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;protected static final String FACTORY_PROPERTIES
=<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"commons-logging.properties";<br>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * Protected constructor that is not available for
public use.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; */<br>
  &nbsp;&nbsp;&nbsp;&nbsp;protected LogFactory() { }<br>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * Locate and construct LogFactory using discovery
logic.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * The first parameter is the <code>rootFinderClass</code>
which is<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * the interface/class representing the wrapper/factory,
or this class.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * This allows <code>Discovery.find()</code>
to identify an appropriate<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * class loader where it can expect to find an implementation
(default<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * class loader at a minimum, in this case).<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * The second parameter is the <code>spi</code>
or service provider<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * interface for which an implementation is desired.
 In this case, both<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * the factory and spi are represented by the same
(abstract) class.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * The third parameter is the name of a properties
file which will be<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * loaded.  It may be used to attempt to find a
property specifying the<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * service implementation (property named <code>LogFactory.class.getName()</code>.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * The fourth parameter is the name of a default
implementation class.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * @exception DiscoveryException if the implementation
class is not<br>
  &nbsp;&nbsp;&nbsp;&nbsp; *            available or cannot be instantiated.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; */<br>
  &nbsp;&nbsp;&nbsp;&nbsp;public static LogFactory getFactory() throws ServiceException<br>
  &nbsp;&nbsp;&nbsp;&nbsp;{<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (LogFactory)Discovery.find(LogFactory.class,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.class,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FACTORY_PROPERTIES,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FACTORY_DEFAULT);<br>
  &nbsp;&nbsp;&nbsp;&nbsp;}<br>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * Locate and construct LogFactory using discovery
logic.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * @param properties use properties instead of FACTORY_PROPERTIES
default<br>
  &nbsp;&nbsp;&nbsp;&nbsp; *        for discovery.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * @exception DiscoveryException if the implementation
class is not<br>
  &nbsp;&nbsp;&nbsp;&nbsp; *            available or cannot be instantiated.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; */<br>
  &nbsp;&nbsp;&nbsp;&nbsp;public static LogFactory getFactory(Properties properties)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws ServiceException<br>
  &nbsp;&nbsp;&nbsp;&nbsp;{<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (LogFactory)Discovery.find(LogFactory.class,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.class,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;properties,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FACTORY_DEFAULT);<br>
  &nbsp;&nbsp;&nbsp;&nbsp;}<br>
  }<br>
  </code>
  </ul>
   
  <a name="Calling Directly"></a>
  <h3>3.  CALLING DIRECTLY</h3>
  
  
  <p>In these examples, the discovery is called directly a 'user'.
  </p>
  
  <ul>
  <code>
  &nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * Locate and construct LogFactory using discovery
logic.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * The first parameter is the <code>spi</code>
or service provider<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * interface for which an implementation is desired.
 In this case, both<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * the factory and spi are represented by the same
(abstract) class.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * The second parameter is the name of a properties
file which will be<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * loaded.  It may be used to attempt to find a
property specifying the<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * service implementation (property named <code>LogFactory.class.getName()</code>.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * The third parameter is the name of a default
implementation class.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; */<br>
  &nbsp;&nbsp;&nbsp;&nbsp;LogFactory factory = (LogFactory)Discovery.find(LogFactory.class,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;LogFactory.FACTORY_PROPERTIES,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;LogFactory.FACTORY_DEFAULT);<br>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * Locate and construct LogFactory using discovery
logic.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * <br>
  &nbsp;&nbsp;&nbsp;&nbsp; * Use <code>properties</code> instead
of FACTORY_PROPERTIES default<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * for discovery.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; */<br>
  &nbsp;&nbsp;&nbsp;&nbsp;LogFactory factory = (LogFactory)Discovery.find(LogFactory.class,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;properties,<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFactory.FACTORY_DEFAULT);<br>
  </code>
  </ul>
  
  <a name="Service Life Cycle Management"></a>
  <h3>4.  SERVICE LIFE CYCLE MANAGEMENT</h3>
  
  <p>Discovery supports life-cycle management through the <code>Service</code>
interface.
  If service implementation implements
  the <code>Service</code> interface then an <code>init(Properties)</code>
  method is invoked when the class in created by Discovery.
  Likewise, a <code>release()</code> method is invoked when Discovery
  removes the service from it's internal cache.
  </p>
  
  <p>Our example LogFactory (acting as both a factory and an SPI)
  might be extended as follows:
  
  <ul>
  <code>
  <b>import org.apache.commons.discovery.Service;</b><br>
  <br>
  public abstract class LogFactory <b>implements Service</b><br>
  {<br>
  &nbsp;&nbsp;&nbsp;&nbsp;. . .<br>
  &nbsp;&nbsp;&nbsp;&nbsp;<b>public abstract void init(Properties properties);<br>
  &nbsp;&nbsp;&nbsp;&nbsp;public abstract void release();<br>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;/**<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * Release any internal references to previously
created {@link LogFactory}<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * instances, after calling the instance method
<code>release()</code> on<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * each of them.  This is useful environments like
servlet containers,<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * which implement application reloading by throwing
away a ClassLoader.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * Dangling references to objects in that class
loader would prevent<br>
  &nbsp;&nbsp;&nbsp;&nbsp; * garbage collection.<br>
  &nbsp;&nbsp;&nbsp;&nbsp; */<br>
  &nbsp;&nbsp;&nbsp;&nbsp;public static void releaseAll() {<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Discovery.releaseAll(LogFactory.class);<br>
  &nbsp;&nbsp;&nbsp;&nbsp;}</b><br>
  }<br>
  </code>
  </ul>
  
  <p>An example of how the properties might be used:
  </p>
  <ul>
  <code>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;public void init(Properties properties) {<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (properties
!= null) {<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enumeration
names = properties.propertyNames();<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while
(names.hasMoreElements()) {<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String
name = (String)names.nextElement();<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setAttribute(name,
properties.getProperty(name));<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
  &nbsp;&nbsp;&nbsp;&nbsp;}<br>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;public abstract void setAttribute(String name, Object
value);<br>
  &nbsp;&nbsp;&nbsp;&nbsp;public abstract Object getAttribute(String name);<br>
  </code>
  </ul>
  
  
  </body>
  </html>
  
  
  
  1.1                  jakarta-commons/discovery/STATUS.html
  
  Index: STATUS.html
  ===================================================================
  <html>
  <head>
  <title>Status File for Jakarta Commons "Discovery" Component</title>
  <head>
  <body bgcolor="white">
  
  
  <div align="center">
  <h1>The Jakarta Commons <em>Discovery</em> Component</h1>
  $Id$<br />
  <a href="#Introduction">[Introduction]</a>
  <a href="#Dependencies">[Dependencies]</a>
  <a href="#Release Info">[Release Info]</a>
  <a href="#Committers">[Committers]</a>
  <a href="#Action Items">[Action Items]</a>
  <br /><br />
  </div>
  
  
  <a name="Introduction"></a>
  <h3>1.  INTRODUCTION</h3>
  
  
  <p> The commons-discovery package provides best-practice algorithms for
  discovering (locating) implementations of Java interfaces.
  It includes support for locating/loading properties files,
  caching-by-classloaders, and attempts using various classloaders.
  </p>
  
  <p>commons-discovery was heavily influenced by code originally
  integrated into commons-logging, which was likely to have been based
  on experience/projects related to the committers of that component.
  </p>
  
  <p>
  Goals:
  <ul>
  <li>Portable: JDK 1.1.8+</li>
  <li>Represent Best-Practices for locating & loading Classes and Resources in non-trivial
environments (non-trivial classloader hierarchies).</li>
  <li>Functional in standalone Java runtime environments</li>
  <li>Functional within a J2EE environment.</li>
  </ul>
  </p>
   
  <p>
  Non-goals:
  <ul>
  <li>Replacing J2EE container managed services.  This means: middleware solutions
  (commons-logging, axis, etc) that need to discover interface implementations
  are encouraged to use this as they must remain independent of J2EE,
  yet it is expected that these may be packaged as part of a
  Web Application (WAR/EAR/JAR).
  Applications/solutions developed for a J2EE managed environment should
  NOT use commons-discovery.</li>
  </ul>
  </p>
   
  
  <a name="Dependencies"></a>
  <h3>2.  DEPENDENCIES</h3>
  
  <p>The <em>Discovery</em> component is dependent upon the following external
  components for compilation:</p>
  <ul>
  <li><a href="http://java.sun.com/j2se">Java Development Kit</a>
      (Version 1.1.8 or later)</li>
  </ul>
  
  <p>The user must ensure that any service that they wish
  to discover (use) are 'discoverable' by the application environments classloaders
  (in the classpath, war/ear/jar file, etc) when they use this component.</p>
  
  <a name="Release Info"></a>
  <h3>3.  RELEASE INFO</h3>
  
  <p>Current Release:  <strong>Unreleased, CVS Repository Only</strong></p>
  
  <p>Planned Next Release:  TBD</p>
  
  <a name="Committers"></a>
  <h3>4.  COMMITTERS</h3>
  
  <p>The following individuals are the primary developers and maintainers of this
  component.  Developers who plan to use <em>Discovery</em> in their own
  projects are encouraged to collaborate on the future development of this
  component to ensure that it continues to meet a variety of needs.</p>
  <ul>
    <li>Richard A. Sitze</li>
    <li>Costin M.</li>
    <li>Craig R. McClanahan</li>
  </ul>
  
  
  <a name="Action Items"></a>
  <h3>5.  ACTION ITEMS</h3>
  
  <p>TO DO List:</p>
  
  <table border="1">
    <tr>
      <th width="80%">Action Item</th>
      <th width="20%">Volunteer</th>
    </tr>
  </table>
  
  </body>
  </html>
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message