You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by "Durfee, Bernard" <Be...@suny.edu> on 2005/01/05 22:00:34 UTC
Bug Fix - Sort of...
Hello,
This is my first post to the list, so I am not sure of the protocol for
making contributions to the project. I had some problems getting a data
source configured in Tomcat 5. My data source factory was not being
used. After some struggle I found that I needed to put the factory name
as an attribute on the Resource> element. So the
ResourceParams> element seems to be ignored.
HOWEVER! In the process of pulling out my hair to figure out what was
going on I 'fixed' the org.apache.naming.factory.ResourceFactory by
refactoring, commenting, and enhancing the exception messages to spit
out some information instead of just a one liner! These modifications
are below. I also added some comments to the code so that future
developers can figure out what the heck is going on. I would love to
contribute this to the project, I've read about 10 other threads on
various web-sites of people frustrated by the lack of error messages
related to this bug.
==============================
/*
* Copyright 1999,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.naming.factory;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
/**
* Object factory for Resources.
*
* @author Remy Maucherat
* @version $Revision: 1.3 $ $Date: 2004/02/27 14:58:54 $
*/
public class ResourceFactory implements ObjectFactory {
// -----------------------------------------------------------
Constructors
// --------------------------------------------------------------
Constants
private static final String DATASOURCE = "javax.sql.DataSource";
private static final String MAIL_SESSION = "javax.mail.Session";
private static final String DATASOURCE_FACTORY_PROPERTY =
"javax.sql.DataSource.Factory";
private static final String MAIL_SESSION_FACTORY_PROPERTY =
"javax.mail.Session.Factory";
private static final String MAIL_SESSION_FACTORY =
"org.apache.naming.factory.MailSessionFactory";
// ----------------------------------------------------- Instance
Variables
// --------------------------------------------------------- Public
Methods
// -------------------------------------------------- ObjectFactory
Methods
/**
* Creates a new object using the specified factory
*
* <ol>
* <li>The factory class name is determined</li>
* <ol>
* <li>The class name is retrieved from the Reference object</li>
* <li>If the class name is not found, a default factory is
created for the desired object</li>
* <li>If the class name is still not found, an exception is
thrown</li>
* </ol>
* </li>
* <li>Once the factory class name is determined, an instance is
created and used to create the desired object</li>
* </ol>
*
* @param resourceRefObject The reference object describing the
DataSource
* @param name Passed to factory
* @param nameCtx Passed to factory
* @param environment Passed to factory
* @return The object instance; null if the 'referenceObject'
parameter is not an instance of Reference
* @throws NamingException When the factory could not be created
* @throws Exception When the factory could not create the obect
*/
public Object getObjectInstance(Object referenceObject, Name name,
Context nameCtx, Hashtable environment)
throws Exception {
// Make sure the Reference was passed in
if(!(referenceObject instanceof Reference)) {
return null;
}
// Cast the incoming resource reference
Reference reference = (Reference) referenceObject;
// We need to create the factory class
final Class factoryClass;
// First check to see if a factory name has been supplied with the
reference
RefAddr factoryRefAddr = reference.get(Constants.FACTORY);
if(factoryRefAddr != null) {
// If so, get the classname of the specified factory
String factoryClassName = factoryRefAddr.getContent().toString();
// Get the context class loader; may not be available
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
if(tcl != null) {
// Use the context class loader
try {
factoryClass = tcl.loadClass(factoryClassName);
}
catch(ClassNotFoundException exception) {
NamingException namingException = new NamingException("Could
not load resource factory class '"
+ factoryClassName + "' using the context class loader,
ClassNotFoundException:" + exception.getMessage());
namingException.setRootCause(exception);
throw namingException;
}
}
else {
// No context class loader; so try the standard class loader
try {
factoryClass = Class.forName(factoryClassName);
}
catch(ClassNotFoundException exception) {
NamingException namingException = new NamingException("Could
not load resource factory class '"
+ factoryClassName + "' using the JVM class loader,
ClassNotFoundException:" + exception.getMessage());
namingException.setRootCause(exception);
throw namingException;
}
}
}
else {
// Determine the requested class name
String objectClassName = reference.getClassName();
// No factory classname was supplied, so check to see if we know
of the default factory
final String factoryClassName;
if(objectClassName.equals(DATASOURCE)) {
factoryClassName =
System.getProperty(DATASOURCE_FACTORY_PROPERTY,
Constants.DBCP_DATASOURCE_FACTORY);
}
else if(objectClassName.equals(MAIL_SESSION)) {
factoryClassName =
System.getProperty(MAIL_SESSION_FACTORY_PROPERTY, MAIL_SESSION_FACTORY);
}
else {
throw new NamingException(
"Unable to determine class name of factory for objects of
type '"
+ objectClassName
+ "', the factory class name was not defined in the
resource reference. Default factories are only known for objects of type
["
+ DATASOURCE + ", " + MAIL_SESSION + "]");
}
// Instantiate the default factory
try {
factoryClass = Class.forName(factoryClassName);
}
catch(Throwable throwable) {
NamingException namingException = new NamingException("Could not
instantiate factory class '"
+ factoryClassName + "': " + throwable.getMessage());
namingException.setRootCause(throwable);
throw namingException;
}
}
// Create an instance of the factory
final ObjectFactory factory;
try {
factory = (ObjectFactory) factoryClass.newInstance();
}
catch(Throwable throwable) {
NamingException namingException = new NamingException("Could not
instantiate factory class '"
+ factoryClass.toString() + "': " + throwable.getMessage());
namingException.setRootCause(throwable);
throw namingException;
}
// Use the factory to create the desired object
Object newObject = factory.getObjectInstance(reference, name,
nameCtx, environment);
return newObject;
}
}
===============================
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org