Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 66740 invoked from network); 6 Oct 2004 12:15:40 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 6 Oct 2004 12:15:40 -0000 Received: (qmail 38599 invoked by uid 500); 6 Oct 2004 12:15:08 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 38516 invoked by uid 500); 6 Oct 2004 12:15:06 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 38499 invoked by uid 99); 6 Oct 2004 12:15:06 -0000 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: pass (hermes.apache.org: local policy includes SPF record at spf.trusted-forwarder.org) Received: from [66.163.170.6] (HELO smtp108.mail.sc5.yahoo.com) (66.163.170.6) by apache.org (qpsmtpd/0.28) with SMTP; Wed, 06 Oct 2004 05:15:05 -0700 Received: from unknown (HELO auburn) (jmitchtx@209.101.199.82 with login) by smtp108.mail.sc5.yahoo.com with SMTP; 6 Oct 2004 12:15:01 -0000 Message-ID: <011f01c4ab9e$0c6059c0$34000a0a@auburn> From: "James Mitchell" To: "Jakarta Commons Developers List" References: <4163E01B.2040705@btinternet.com> Subject: Re: [configuration] handling exceptions in AbstractConfiguration implementations Date: Wed, 6 Oct 2004 08:14:36 -0400 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2741.2600 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2742.200 X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Problem with having Hibernate implementations is that the license is incompatible with the ASL. So you'll need to keep any incompatible code somewhere else....like I do with commons-resources at sf.net. -- James Mitchell Software Engineer / Open Source Evangelist EdgeTech, Inc. 678.910.8017 AIM: jmitchtx ----- Original Message ----- From: "Ricardo Gladwell" To: "Jakarta Commons Developers List" Sent: Wednesday, October 06, 2004 8:07 AM Subject: Re: [configuration] handling exceptions in AbstractConfiguration implementations > Eric Pugh wrote: > > Hi Ricardo.. Sounds like you are working on something I've been wanting for > > a long time! > > Of course, I was going to release it anyway so please find the > source-code attached. Not sure it belongs in commons-configration API; > probably better contributed to the hibernate project. If you can think > of any improvements please mail the patches back to me for my own project :) > > > In otherwords, say I am using a Configuration object in my code, and I do > > configuration.getDouble("key");. If getDouble throws an exception then I am > > going to have these try/catch cluases all over the place, cluttering the > > code. and, I really except getDouble() to allows work. If it doesn't, my > > application will just pass it on,not have some sort of fancy if getDouble > > fails, then try getString or something weird. > > Good point, although I'm still dubious about throwing RuntimeExceptions > - those things shoot straight through everything like a silver bullet > and can even crash some servlet engines. > > From my perspective, I'm not bothered if the Configuration object > throws exceptions: I wouldn't catch such exceptions in my web > application, instead letting them fly all the way to the exception > screen. This way, I can see them occuring as I test my application > through the browser. > > Obviously, sometimes when configuring your application you just want > your configuration to work or keep on working untill if it encounters an > errors. However, simply allowing your application to ignore exceptions > until they create new exception elsewhere seems like a good way to > create hard-to-fix bugs. Surely, it would be better to relay the errors > and let the application decide what to do with them? > > > I think what you can do is just wrap your HibernateException in a > > ConfiguratoinRuntimeException and toss that. JDBCConfiguration should > > probably be doning the same thing. > > Another alternative would be to have a getExceptions() method for all > Configurations which stores exceptions occuring and stores them for > later reporting. A good comprimise would be to allow all Configuration > objects to have two modes: one where exceptions are thrown as soon as > they occur and another one which stores exceptions as I suggested. > > Kind regards, > -- Ricardo Gladwell > > >>-----Original Message----- > >>From: Ricardo Gladwell [mailto:ricardo.gladwell@btinternet.com] > >>Sent: Wednesday, October 06, 2004 12:56 PM > >>To: Jakarta Commons Developers List > >>Subject: [configuration] handling exceptions in AbstractConfiguration > >>implementations > >> > >> > >>Hi All, > >> > >>I'm currently developing a sub-class of the AbstractConfiguration > >>classthat uses Hibernate to access configuration properties > >>(unimaginatively called Hibernate Configuration). I'm slightly concerned > >>about the way sub-classes are suposed to handle exceptions: > >> > >>All the abstract method are defined as not throwing exceptions. All > >>calls to hibernate, however, throw HibernateExceptions. So, for example, > >>my implementation of getPropertyDirect calls the hibernate Session.get() > >>method which can throw an exception. > >> > >>Looking at your implementation of the DatabaseConfiguration I can see > >>that it simply consumes SQLExceptions thrown from the JDBC API, logging > >>the stack trace. However, what if you want to be warned of exceptions > >>being thrown by the underlying implementation of Configuration? > >> > >>I notice you already have a nestable ConfigurationException implemented. > >>Surely, all Configuration methods should indicate they will throw this > >>exception if they are expected to read/write data? > >> > >>Also, the AbstractConfiguration class does not describe this contract > >>(logging all errors throw by underlying framework) or what should be > >>returned in the event of an error? I assume you should return null > >>values but this is not described anywhere. > >> > >>Kind regards, > >>-- Ricardo Gladwell > ---------------------------------------------------------------------------- ---- > package net.sf.jexus.server.components; > > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; > > import java.util.Iterator; > import java.util.List; > > import net.sf.hibernate.HibernateException; > import net.sf.hibernate.Session; > import net.sf.hibernate.Transaction; > import net.sf.jexus.server.data.object.ConfigurationProperty; > > import org.apache.commons.beanutils.ConvertUtils; > import org.apache.commons.configuration.AbstractConfiguration; > > /** > *

Hibernate configuation class. Reads configuration infomation from a > * database through the Hibernate > * O/R mapping API. Data is stored as name-value pairs, along with the class > * information of data stored, using the mapping* defined by the > * {@link ConfigurationProperty} POJO hibernate xdoclet directives. Values are > * converted to and from strings using > * {@link org.apache.commons.beanutils.ConvertUtils}.

> * > * @author Ricardo Gladwell > */ > public class HibernateConfiguration extends AbstractConfiguration { > > /** > * Logger for this class > */ > private static final Log log = LogFactory.getLog(HibernateConfiguration.class); > > /** > * Reference to the session factory. > */ > Session session; > > /** > * > */ > class KeyIterator implements Iterator { > > Iterator iterator; > String last; > > public KeyIterator(Iterator iterator) throws HibernateException { > this.iterator = iterator; > } > > /** > * @see java.util.Iterator#hasNext() > */ > public boolean hasNext() { > return iterator.hasNext(); > } > > /** > * @see java.util.Iterator#next() > */ > public Object next() { > ConfigurationProperty config = (ConfigurationProperty)iterator.next(); > String key = config.getName(); > last = key; > return key; > } > > /** > * @see java.util.Iterator#remove() > */ > public void remove() { > clearProperty(last); > } > > } > > /** > * > */ > public HibernateConfiguration(Session session) { > super(); > if(log.isTraceEnabled()) log.trace("HibernateConfiguration()"); > this.session = session; > } > > /** > * @see org.apache.commons.configuration.AbstractConfiguration#getPropertyDirect(jav a.lang.String) > */ > protected Object getPropertyDirect(String key) { > if(log.isTraceEnabled()) log.trace("getPropertyDirect("+key+")"); > ConfigurationProperty config = null; > try { > config = (ConfigurationProperty) session.get(ConfigurationProperty.class,key); > } catch(HibernateException e) { > log.error("Error reading congfiguration property=["+key+"]",e); > return null; > } > try { > Class clazz = getClass().getClassLoader().loadClass(config.getType()); > return ConvertUtils.convert(config.getValue(), clazz); > } catch(ClassNotFoundException e) { > log.warn("Cannot find class=["+config.getType()+"] for property=["+key+"]",e); > } > return config.getValue(); > } > > /** > * @see org.apache.commons.configuration.AbstractConfiguration#addPropertyDirect(jav a.lang.String, java.lang.Object) > */ > protected void addPropertyDirect(String key, Object value) { > if(log.isTraceEnabled()) log.trace("addPropertyDirect("+key+","+value+")"); > ConfigurationProperty config = new ConfigurationProperty(); > config.setName(key); > config.setValue(ConvertUtils.convert(value)); > config.setType(value.getClass().getName()); > try { > Transaction transaction = session.beginTransaction(); > session.save(config); > transaction.commit(); > } catch(HibernateException e) { > log.error("Error adding congfiguration property=["+key+"]",e); > } > } > > /** > * @see org.apache.commons.configuration.Configuration#isEmpty() > */ > public boolean isEmpty() { > if(log.isTraceEnabled()) log.trace("isEmpty()"); > try { > List list = session.find("from Configuration"); > return list.isEmpty(); > } catch(HibernateException e) { > log.error("Error reading keys.",e); > return true; > } > } > > /*** > * @see org.apache.commons.configuration.Configuration#containsKey(java.lang.String) > */ > public boolean containsKey(String key) { > if(log.isTraceEnabled()) log.trace("containsKey("+key+")"); > return (getPropertyDirect(key) != null); > } > > /** > * @see org.apache.commons.configuration.Configuration#clearProperty(java.lang.Strin g) > */ > public void clearProperty(String key) { > if(log.isTraceEnabled()) log.trace("clearProperty("+key+")"); > ConfigurationProperty config = new ConfigurationProperty(); > config.setName(key); > try { > Transaction transaction = session.beginTransaction(); > session.delete(config); > transaction.commit(); > } catch(HibernateException e) { > log.error("Error clearing congfiguration property=["+key+"]",e); > } > } > > /** > * @see org.apache.commons.configuration.Configuration#getKeys() > */ > public Iterator getKeys() { > if(log.isTraceEnabled()) log.trace("getKeys()"); > try { > List list = session.find("from Configuration"); > return new KeyIterator(list.iterator()); > } catch(HibernateException e) { > log.error("Error reading keys.",e); > return null; > } > } > > } > ---------------------------------------------------------------------------- ---- > /* > * Copyright 2004 Ricardo Gladwell > * > * 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 net.sf.jexus.server.data.object; > > /** > * Hibernate persistance JavaBean encapsulating information about > * a configuration property. > * > * @hibernate.class > * table="configuration" > * > * @todo Create JUnit test cases. > * @author Ricardo Gladwell > * @version $Revision: 1.1 $, $Date: 2004/10/05 14:03:55 $ > */ > public class ConfigurationProperty { > > /** > * Name of this configuration property. > */ > String name; > > /** > * String representation of the valye of this configuration property. > */ > String value; > > /** > * Fully qualified class for this configuration property's type. > */ > String type; > > /** > * Returns the key name for this configuration property. > * > * @hibernate.id > * generator-class="assigned" > * > * @return Returns the name. > */ > public String getName() { > return name; > } > > /** > * Sets the key name for this configuration property. > * @param name The name to set. > */ > public void setName(String name) { > this.name = name; > } > > /** > * Returns the value of this property. > * > * @hibernate.property > * > * @return Returns the value. > */ > public String getValue() { > return value; > } > > /** > * Sets the value of this property. > * @param value The value to set. > */ > public void setValue(String value) { > this.value = value; > } > > /** > * Returns the fully qualified class name for the type > * of the value for this configuration property. > * > * @hibernate.property > * > * @return Returns the type. > */ > public String getType() { > return type; > } > > /** > * Sets the fully qualified class name for the type > * of the value for this configuration property. > * @param type The type to set. > */ > public void setType(String type) { > this.type = type; > } > } > > ---------------------------------------------------------------------------- ---- > --------------------------------------------------------------------- > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org > For additional commands, e-mail: commons-dev-help@jakarta.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org