pglezen 01/06/03 23:15:22
Modified: src/java/org/apache/log4j/examples/appserver
AppServerCategory.java
AppServerCategoryFactory.java package.html
Removed: src/java/org/apache/log4j/examples/appserver
AppServerPropConfigurator.java
Log:
These changes are the result of a belated understanding of
Anders' PropertySetter class. About 100 lines of configuration
voodoo was replaced by adding a few lines to PropertyConfigurator
and some other minor adjustments. One should now be able to
change from using Category to AppServerCategory with NO changes
in source code; only the property file needs to change.
1. AppServerCategory - static init was removed. The Category
static init does the job now.
2. AppServerCategoryFactory - added default constructor and
overloaded the setMessageBundle to allow the PropertySetter
introspector to set the message bundle.
3. AppServerPropConfigurator - removed since PropertyConfigurator
does its job now.
4. package.html - revised docs. (Look Ceki. No javadoc warnings!)
Revision Changes Path
1.8 +16 -62
jakarta-log4j/src/java/org/apache/log4j/examples/appserver/AppServerCategory.java
Index: AppServerCategory.java
===================================================================
RCS file:
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/examples/appserver/AppServerCategory.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- AppServerCategory.java 2001/06/02 09:49:43 1.7
+++ AppServerCategory.java 2001/06/04 06:15:21 1.8
@@ -41,29 +41,28 @@
*
* <p>Rather than set all these attributes for each
* <code>AppServerCategory</code> instance, it is usually more
- * convenient to set them on <code>AppServerCategoryFactory</code>
- * and associate this factory statically with
- * <code>AppServerCategory</code> using the static
- * <code>setFactory</code> method. The
- * <code>AppServerCategory.getInstance(String)</code> method can then
- * be used to create <code>AppServerCategory</code> instances.
-
- * <p> A special {@link AppServerPropConfigurator} subclass of {@link
- * org.apache.log4j.PropertyConfigurator PropertyConfigurator} is
- * provided to facilitate complete factory configuration at class
- * load time. This is useful in application server environments
- * where a variety of entry points may exist for an application.
- * Check the package level documentation for details on how to set
- * this up. <p>
+ * convenient to set them once on {@link AppServerCategoryFactory}.
+ * The factory can then be associated with the
+ * <code>AppServerCategory</code> class via {@link #setFactory}
+ * or with the entire hierarchy via
+ * {@link org.apache.log4j.Hierarchy#setCategoryFactory}. In the
+ * former case, you should use {@link AppServerCategory#getInstance}
+ * to create new categories. In the latter case, you would use
+ * {@link org.apache.log4j.Category#getInstance(String)}. The former
+ * method allows finer granularity of control; the latter is more
+ * convenient. Reliance on the
+ * {@link org.apache.log4j.PropertyConfigurator} will employ the
+ * latter.
+ *
+ * <p>More convenient still is to rely on the
+ * {@link org.apache.log4j.Category} static initializer. See the
+ * package level documention for details.
*
* @author Paul Glezen */
public class AppServerCategory extends Category {
private static String FQCN = AppServerCategory.class.getName();
- public static final String APPSERVER_INIT_OVERRIDE_KEY =
- "log4j.appserverInitOverride";
-
/** The name of the component using this category. */
protected String component;
@@ -82,51 +81,6 @@
instances. */
private static CategoryFactory factory = new AppServerCategoryFactory(null, null,
null);
- /**
- * This static initializer will configure over the one used by
- * <code>Category</code> if the <code>log4j.appserver.factory</code>
- * property is defined in the configuration file (and the default
- * init override key is not set to true).
- */
- static {
- String override =OptionConverter.getSystemProperty(
- APPSERVER_INIT_OVERRIDE_KEY,
- null);
-
- // If there is no appserver init override, then get the resource
- // specified by the user or the default config file.
- if(override == null || "false".equalsIgnoreCase(override)) {
- String resource = OptionConverter.getSystemProperty(
- DEFAULT_CONFIGURATION_KEY,
- DEFAULT_CONFIGURATION_FILE);
- LogLog.debug("Running AppserverDefaultInit");
- URL url = null;
- try {
- url = new URL(resource);
- } catch (MalformedURLException ex) {
- // So resource is not a URL; attempt to get the resource
- // from the classpath
- url = ClassLoader.getSystemResource(resource);
- if(url == null) {
- // Is it under anywhere in the classpath?
- url = Category.class.getResource("/" + resource);
- }
- if(url == null) {
- // Is it under org/apache/log4j somewhere in the classpath?
- url = Category.class.getResource(resource);
- }
- }
- // If we have a non-null url, then delegate the rest of the
- // configuration to the AppServerPropConfigurator class.
- if(url != null) {
- LogLog.debug("Configuring with AppServerPropConfigurator");
- new AppServerPropConfigurator().doConfigure(url, defaultHierarchy);
- } else {
- LogLog.debug("Could not find resource: ["+resource+"].");
- }
- }
- }
-
/**
* Construct a new AppServerCategory with the provided
* attributes. The constructor is protected because the only
1.5 +31 -0
jakarta-log4j/src/java/org/apache/log4j/examples/appserver/AppServerCategoryFactory.java
Index: AppServerCategoryFactory.java
===================================================================
RCS file:
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/examples/appserver/AppServerCategoryFactory.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- AppServerCategoryFactory.java 2001/03/05 04:52:39 1.4
+++ AppServerCategoryFactory.java 2001/06/04 06:15:21 1.5
@@ -1,9 +1,11 @@
package org.apache.log4j.examples.appserver;
import java.util.ResourceBundle;
+import java.util.MissingResourceException;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.Category;
import org.apache.log4j.spi.CategoryFactory;
@@ -71,6 +73,15 @@
component = componentName;
version = versionName;
}
+
+ /**
+ * The default constructor merely calls the three-argument
+ * constructor with null values.
+ */
+ public AppServerCategoryFactory()
+ {
+ this(null, null, null);
+ }
/**
* Get the name of the component for which this category is logging.
@@ -152,6 +163,26 @@
*/
public void setMessageBundle(ResourceBundle bundle) {
messageBundle = bundle;
+ }
+
+ /**
+ * Set the message bundle using the bundle filename. This name
+ * should not include the "<code>.properties</code>" extension.
+ * Care should be taken to ensure the bundle file is somewhere
+ * in the system classpath or loadable by this class's class
+ * loader.
+ *
+ * @param filename name of the bundle file
+ */
+ public void setMessageBundle(String filename)
+ {
+ try {
+ messageBundle = ResourceBundle.getBundle(filename);
+ LogLog.debug("Message bundle [" + filename + "] retrieved.");
+ }
+ catch(MissingResourceException mre) {
+ LogLog.warn("Failed to find [" + filename + "] message bundle.");
+ }
}
/**
1.5 +69 -93
jakarta-log4j/src/java/org/apache/log4j/examples/appserver/package.html
Index: package.html
===================================================================
RCS file:
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/examples/appserver/package.html,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- package.html 2001/06/02 09:49:43 1.4
+++ package.html 2001/06/04 06:15:22 1.5
@@ -13,81 +13,57 @@
</ol>
<p>
<h2>Configuration</h2>
-Using this package in your programs differs little from using the
-corresponding classes in <code>org.apache.log4j</code>. Because of some
-internal difference in the initialization sequence, this package
-contains its own property configurator. A static initializer is also
-provided in the category subclass that works in much the same way as
-the <code>Category</code> static initializer. In this initial version,
+Using this package in your programs differs little from using
+{@link org.apache.log4j.Category}. In this initial version,
only property file initialization is supported.
-<p>
-The following properties serve to configure the
-<code>AppServerCategoryFactory</code>.
+
+<h3>Automatic Configuration</h3>
+The following properties serve to configure the {@link
+org.apache.log4j.examples.appserver.AppServerCategoryFactory}.
<p>
<table border=1>
<tr><th>Property<th>Description
-<tr><td><code><b>log4j.appserver.factory</b></code>
- <td>The fully qualified class name of the factory implementation.
-<tr><td><code><b>log4j.appserver.factory.server</b></code>
+<tr><td><code><b>log4j.categoryFactory</b></code>
+ <td>The {@link org.apache.log4j.spi.CategoryFactory}
+ implementation to use.
+<tr><td><code><b>log4j.factory.server</b></code>
<td>The value assigned to the server attribute.
-<tr><td><code><b>log4j.appserver.factory.component</b></code>
+<tr><td><code><b>log4j.factory.component</b></code>
<td>The value assigned to the component attribute.
-<tr><td><code><b>log4j.appserver.factory.version</b></code>
+<tr><td><code><b>log4j.factory.version</b></code>
<td>The value assigned to the version attribute.
-<tr><td><code><b>log4j.appserver.factory.msgfile</b></code>
+<tr><td><code><b>log4j.factory.messageBundle</b></code>
<td>The name of bundle file to populate the message
<code>ResourceBundle</code>. Because the
<code>ResourceBundle.getBundle</code> method is used to load
the message file, the <code>".properties"</code> extension
should <b>not</b> be included as part of this property.
</table>
-<p>
-The property names are defined in {@link
-org.apache.log4j.examples.appserver.AppServerPropConfigurator}.
-<p>
-<h3>Automatic Configuration</h3>
-In application servers, it is difficult to predict which code
-will be the first to run. There is no <code>main</code> method
-the application programmer can grab hold of and populate with
-initialization method calls. This complicates the initialization
-of a log4j hierarchy, an essentially static structure, by various
-transient objects such as servlets, EJBs or CORBA objects.
-<p>
-The simplest way to achieve the log4j configuration is to allow
-the configuration to occur at class load time of the
-<code>AppServerCategory</code>. The static initializer of
-<code>AppServerCategory</code> is very similar to that of its
-parent class, <code>Category</code>.
-<p>
-For the static <code>AppServerCategory</code> to perform properly,
-it is best to disable the configuration attempted by the
-<code>Category</code> static initializer. This is done by defining
-the system property <code>log4j.defaultInitOverride</code> to be
-<code>true</code> (or anything else but <code>false</code>). If
-you run your program from the command line, you do this with the
-<code>-D</code> option; as in
-<p>
-<center>
-<code>java -Dlog4j.defaultInitOverride=true my.class.with.main</code>
-</center>
-<p>
-If you are logging from an application server, you will need to
-consult the vendor's documentation on how to set system properties.
-<p>
-Like the <code>Category</code> static initializer, the
-<code>AppServerCategory</code> static initializer expects to find
-the name of the property file in a system property called
-<code>log4j.configuration</code>. If this system property is not
-defined, an attempt is made to load <b>log4j.properties</b>.
-<p>
-Since all the actions described above are triggered by the loading
-of the <code>AppServerCategory</code> class, they will likely
-happen at the first occurence of a statement like
<p>
-<code>Category cat = AppServerCategory.getInstance("some.cat");</code>
+A sample configuration might look like this.
<p>
-There is no need to take special measures to ensure the appropriate
-configurator was run beforehand.
+<table border=1>
+<tr><td><pre>
+log4j.categoryFactory=org.apache.log4j.examples.appserver.AppServerCategoryFactory
+log4j.factory.server=TestServer
+log4j.factory.component=TestComponent
+log4j.factory.version=SomeVersion
+log4j.factory.messageBundle=app_messages
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.examples.appserver.AppServerPatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%h:%s:%b:%v] %m%n
+</pre></table>
+<p>
+There is <b>no</b> need to change your source code to go from using
+<code>Category</code> to <code>AppServerCategory</code> if you are
+using property files to configure your logging infrastructure.
+Simply specifying the <code>AppServerCategoryFactory</code>
+as the {@link org.apache.log4j.spi.CategoryFactory} implementation
+does the trick. It installs the factory
+as the default factory for the hierarchy so that
+{@link org.apache.log4j.Category#getInstance(String)} always returns
+the proper <code>Category</code> subclass.
<h3>Manual Configuration</h3>
You can manually invoke the configuration much like the static
@@ -96,13 +72,12 @@
<table border=1>
<tr><td><pre>
import org.apache.log4j.Category;
-import org.apache.log4j.examples.appserver.AppServerCategory;
-import org.apache.log4j.examples.appserver.AppServerPropConfigurator;
+import org.apache.log4j.PropertyConfigurator;
...
-AppServerPropConfigurator.configure("test.properties");
-Category cat = AppServerCategory.getInstance("some.cat");
+PropertyConfigurator.configure("test.properties");
+Category cat = Category.getInstance("some.cat");
...
@@ -111,16 +86,19 @@
<p>
<h3>Very Manual Configuration</h3>
If you want complete control over the configuration process, you
-can leave <code>AppServerPropConfigurator</code> out of it all
-together.
+can leave <code>PropertyConfigurator</code> out of it all
+together. This could be useful if you want only some of your
+categories to be <code>AppServerCategory</code> instances.
<p>
After creating an appropriate <code>AppServerCategoryFactory</code>
-instance, set a static reference to it using the
-<a href="AppServerCategory.html#setFactory">
-<code>AppServerCategory.setFactory</code></a> method. This
-sets everything up for acquiring an
-<a href="AppServerCategory.html"><code>AppServerCategory</code></a>
-reference whenever you need one.
+instance, set a static reference to it using {@link
+org.apache.log4j.examples.appserver.AppServerCategory#setFactory}.
+This sets everything up for acquiring an <code>AppServerCategory</code>
+reference whenever you need one. When you use this method of
+configuration, the hierarchy's default factory is left alone. So
+you should use {@link
+org.apache.log4j.examples.appserver.AppServerCategory#getInstance(String)}
+to acquire a reference to an <code>AppServerCategory</code> instance.
<p>
<table border=1>
<tr><td><pre>
@@ -142,20 +120,28 @@
</pre>
</table>
<p>
+Do <b>not</b> use {@link
+org.apache.log4j.examples.appserver.AppServerCategory#getInstance(String)}
+to acquire an <code>AppServerCategory</code> instance if you used
+<code>PropertyConfigurator</code> to do the configuration. While the
+introspection mechanism used by <code>PropertyConfigurator</code> is good,
+it doesn't know to set a link from <code>AppServerCategory</code> to
+the factory. Misusing the <code>getInstance</code> method in this manner
+will result in categories produced that have host name defined but all
+other attributes set to null.
+<p>
<h4>A Note on Configurators</h4>
-Using <code>AppServerCategory</code> with
-<a href="../../PropertyConfigurator.html">
-<code>PropertyConfigurator</code></a> or
-<a href="../../xml/DOMConfigurator.html">
-<code>DOMConfigurator</code></a>
-requires a note of caution. By default these configurators
-do not know that
-<a href="../../Category.html"><code>Category</code></a>
-has been subclassed. Upon
+Using the <i>very manual</i> approach to configure
+<code>AppServerCategory</code> with
+<code>PropertyConfigurator</code> or <code>DOMConfigurator</code>
+requires a note of caution. Since the <i>very manual</i> method
+does not provide the <code>log4j.categoryFactory</code> property,
+these configurators do not know that <code>Category</code> has
+been subclassed. Upon
constructing a configuration from a set of properties, it will
construct <code>Category</code> instances rather than instances
-of the desired subclass. There at least two ways to work around
-this.
+of the desired subclass. One way to around this is decribed
+below.
<p>
By instanciating any anticipated <code>AppServerCategory</code>
instances before calling a configurator, the configurator will
@@ -165,16 +151,6 @@
dynamic nature is the reason for externalizing their configuration
in the first place. This drawback is limited to category names
explicitly defined in the configuration.
-<p>
-Another work-around is to take advantage of a recently added feature
-allowing you to specify the type of factory used for creating
-<code>Category</code> instances to a <code>DOMConfigurator</code>
-or a <code>PropertyConfigurator</code>. The consequence
-is that only the default constructor is used to create
-the factory instance. For <code>AppServerCategoryFactory</code>,
-this will only populate the hostname attribute. The server name,
-component name and version name will be blank. For many cases
-this may be satisfactory.
<p>
<h2>Remote Usage</h2>
Including attributes such as hostname and server are only relevant
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]