db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Chris Giordano <giord...@more.net>
Subject OJB usability - part 2 of 5: defaulting data
Date Wed, 15 Oct 2003 14:50:44 GMT
OJB developers:

The following feedback intends to provide constructive comments to the
OJB developers to improve the project as a whole.  The experiences and
observations are meant to stimulate development of world class software.
An open source dB persistence layer solution is needed and OJB may be
positioned to provide this in the future.

Here are two examples of OJB setting/using default data from within
the API that leads to unexpected, if not buggy, program behavior.

Example #1:
In the class: PersistenceBrokerFactoryFactory.java, consider the following
code segment:

private static PersistenceBrokerFactoryIF init()
{
   <code ommited from here for brevity>

   Class pbfClass = null;
   try
   {
       <code ommited from here for brevity>

       pbfClass = config.getClass("PersistenceBrokerFactoryClass",
                                   
PersistenceBrokerFactoryDefaultImpl.class);

       PersistenceBrokerFactoryIF result =
           (PersistenceBrokerFactoryIF)pbfClass.newInstance();

       <code ommited here for brevity>
   }
   <code ommited from here for brevity>
}

The relevant code here is at the config.getClass() method.  This method will
load the default class: PersistenceBrokerFactoryDefaultImpl.class if the
pluggable, configured class was not found (as defined in 
OJB.properties).  But,
we chose to customize this implementation.  We configured OJB.properties 
to use
our custom class.  During a test run, OJB was not able to find our 
customized
class and, by design, proceeded to load the alternate default implementation
which was the wrong one.  We wasted time tracking down unexpected behavior
because our class was, in fact, not the one that got loaded.

If something is configurable and the configuration fails to load, 
something has
gone wrong.  We configured something different for a reason.  In this 
case, OJB
needs to just throw an Exception.

Example #2:
In the class: MetadataManager.java, consider the following code segment:

public DescriptorRepository getRepository()
{
    DescriptorRepository repository;
    if (enablePerThreadChanges)
    {
        repository = (DescriptorRepository) threadedRepository.get();
        if (repository == null)
        {
            repository = getGlobalRepository();
        }
        return repository;
    }
    else
    {
        return globalRepository;
    }
}

Again, more wasted time tracking down a bug that would have only taken 
minutes
had it not been for OJB's design of making a decision to return something
other than expected.  In this case, OJB doesn't even bother logging a
discrepancy between the intention to get the threaded repository
(enablePerThreadChanges is true) and the fact that a null value was found.

If isEnablePerThreadChanges() is true, OJB needs to return the value of the
threaded repository - even if it's a null value.  It is the developer's
decision to use the global repository in the event of a null value.  
Moreover,
if the intention is to use per thread repositories, and the value of that
repository is null, something most likely is wrong with the code that 
needs to
be resolved.

Both of these examples are meant to illustrate the API contract that OJB
is supposed to provide is violated.  In example 1, the concept of a 
pluggable
configuration is violated.  What is configured and intended for use may be
different than what is actually used.  In example 2, there is a violation
between the intention to use and receive a threaded repository and what may
actually be returned when calling getRepository().

Chris Giordano
giordano@more.net



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message