avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Alexander \"Stiefel\" Müller" <stie...@stiefelnet.de>
Subject RE: Bug in Excalibur Datasource package
Date Fri, 25 Jan 2002 13:34:16 GMT

hey,

i implemented this as follows (i needed fast solution), may be
you can use something:

the xml looks like this:
	<components>
 		<jdbc1 logger="system.database">
			<pool-controller min="3" max="20" 
				connection-class="org.apache.avalon.excalibur.datasource.JdbcConnection">
				<!--
					attributes: perform=true/false: perform keep-alive select specified as value
							frequence=time-value: if perform=true, only do if older than xx millis,
										    valid time-values: Xs, Xm, Xh, Xd or X (millis)
							max-age=time-value: check for max-age, values: see frequence, set -1 to disable age-checking
				-->
				<keep-alive perform="false" frequence="10s" max-age="-1">SELECT bla FROM blub</keep-alive>
			</pool-controller>
			<driver>COM.ibm.db2.jdbc.net.DB2Driver</driver>
	...

now changes to the files:
- everywhere: removed already deprecated constructors
- AbstractJdbcConnection:
new members:
    protected long				 m_maxAge;
    protected long				 m_pingFrq;
extend constructor:
    public AbstractJdbcConnection( final Connection connection, final String keepAlive,
    							   final long maxAge, final long pingFrq ) 
	...
        m_maxAge = maxAge;
        m_pingFrq = pingFrq;
	...
extend isClosed():
	...
        long age = System.currentTimeMillis() - m_lastUsed;
        if ( m_maxAge > 0 )  	  // perform max-age-check?
        {
	        if ( age > m_maxAge ) // over max-age?	
	...
        if (m_testStatement != null && age > m_pingFrq) // over xx seconds ago
	...
- JdbcConnection and JdbcConnection:
extend constructor:	
    public Jdbc3Connection( final Connection connection, final String keepAlive, final long
maxAge, final long pingFrq )
    {
        super( connection, keepAlive, maxAge, pingFrq );
    }

- JdbcConnectionFactory:
new members:
    private final long m_maxAge;
    private final long m_pingFrq;
extend constructor:
   public JdbcConnectionFactory( final String url,
                                 final String username,
                                 final String password,
                                 final boolean autoCommit,
                                 final String keepAlive,
                                 final String connectionClass,
                                 final long maxAge,
                                 final long pingFrq )
	...
        this.m_autoCommit = autoCommit;
        // this resolves NullPointerException during Reflection
        if ( keepAlive == null )
        	this.m_keepAlive = "";
        else
        	this.m_keepAlive = keepAlive;
        this.m_maxAge = maxAge;
        this.m_pingFrq = pingFrq;

        Class clazz = null;
	...
        if ( null != this.m_class )
        {
            try
            {
                Class[] paramTypes = new Class[] { Connection.class, String.class, long.class,
long.class };
                Object[] params = new Object[] { connection, this.m_keepAlive, new Long( this.m_maxAge
), new Long( this.m_pingFrq ) };

                Constructor constructor = m_class.getConstructor( paramTypes );
                jdbcConnection = (AbstractJdbcConnection) constructor.newInstance( params
);
            }
            catch ( Exception e )
            {
                
                /* disable "old" constructors
                try
                {
                    Class[] paramTypes = new Class[] { Connection.class, boolean.class };
                    Object[] params = new Object[] { connection, new Boolean( this.m_keepAlive.equalsIgnoreCase(JdbcConnectionFactory.ORACLE_KEEPALIVE)
) };

                    Constructor constructor = m_class.getConstructor( paramTypes );
                    jdbcConnection = (AbstractJdbcConnection) constructor.newInstance( params
);
                }
                catch ( Exception ie )
                {
                    if ( getLogger().isDebugEnabled() )
                    {
                        getLogger().debug("Exception in JdbcConnectionFactory.newInstance:",
ie);
                    }*/

                    throw new NoValidConnectionException(e.getMessage());
                //}
	...

- JdbcDataSource:
extend configure():
	...
            final Configuration controller = configuration.getChild( "pool-controller" );
            String keepAlive = controller.getChild( "keep-alive" ).getValue(null);
            final boolean perform = controller.getChild( "keep-alive" ).getAttributeAsBoolean(
"perform", true);
            if ( !perform )
            	keepAlive = null;
            String smaxage = controller.getChild( "keep-alive" ).getAttribute( "max-age",
"1h");
            final long maxage = timeValue( smaxage );
            String spingfrq = controller.getChild( "keep-alive" ).getAttribute( "frequence",
"5s");
            final long pingfrq = timeValue( spingfrq );

            final int min = controller.getAttributeAsInteger( "min", 1 );
	...
            if (oradb)
            {
                keepAlive = "SELECT 1 FROM DUAL";

                if (getLogger().isWarnEnabled())
                {
                    getLogger().warn("The oradb attribute is deprecated, please use the" +
                                     "keep-alive element instead.");
                }
            }
            else
            {
            	//let the user config this
                //keepAlive = "SELECT 1";
            }

            final JdbcConnectionFactory factory =
                    new JdbcConnectionFactory( dburl, user, passwd, autoCommit, 
                    						   keepAlive, connectionClass, 
                    						   maxage, pingfrq );
a new method: (is there a better/existing way??):
    private long timeValue( String value )
    	throws ConfigurationException 
    {
    	if ( value == null || value.length() == 0) // not present -> default -1
    		return -1;
    	
    	try {
	    	char measure = value.charAt(value.length()-1);
	    	long l1 = -1;
	    	switch ( measure ) {
	    		case 's':	// seconds
	    			l1 = Long.parseLong(value.substring(0, value.length()-1)) * 1000;
	    			break;
	    		case 'm':	// minutes
	    			l1 = Long.parseLong(value.substring(0, value.length()-1)) * 1000 * 60;
	    			break;
	    		case 'h':	// hours
	    			l1 = Long.parseLong(value.substring(0, value.length()-1)) * 1000 * 60 * 60;
	    			break;
	    		case 'd':	// days
	    			l1 = Long.parseLong(value.substring(0, value.length()-1)) * 1000 * 60 * 60 * 24;
	    			break;
	    		default:	// millis (no measure) or bullshit (handled by catch)
	    			l1 = Long.parseLong(value);
	    			break;
	    	}
	    	return l1;
    	}
    	catch ( Exception e ) {
    		throw new ConfigurationException("Unable to extract time-value: " + e.getMessage(),
e);
    	}

o.k. that's it

Mit freundlichen Grüßen / Best Regards,

Alexander "Stiefel" Müller
Geschäftsführer

stiefelnet e-Solver GmbH
Friedensplatz 4; D-01309 Dresden
www.stiefelnet.de

fon    +49 (0)3 51 - 31 25 41 0
fax    +49 (0)3 51 - 31 25 41 7
mobil  +49 (0)1 71 - 48 10 96 9
e-mail stiefel@stiefelnet.de

> -----Original Message-----
> From: Leif Mortenson [mailto:leif@silveregg.co.jp]
> Sent: Friday, January 25, 2002 3:06 AM
> To: Avalon Developers List
> Subject: Re: Bug in Excalibur Datasource package
> 
> 
> I was looking into fixing this and have run into a problem.  How do we 
> want to tell the JdbcDataSouce not to perform keep-alive pings?
> 
> Currently, we are defaulting to "SELECT 1" if a <keep-alive> node is not 
> specified.  The problem is how to specify that we want to disable it.
> 
> The following will all return null for:  controller.getChild( 
> "keep-alive" ).getValue( null );
>      <pool-controller min="5" max="10" 
> connection-class="my.overrided.ConnectionClass">
>        <keep-alive></keep-alive>
>      </pool-controller>
> 
>      <pool-controller min="5" max="10" 
> connection-class="my.overrided.ConnectionClass">
>        <keep-alive/>
>      </pool-controller>
> 
>       <pool-controller min="5" max="10" 
> connection-class="my.overrided.ConnectionClass"/>
> 
> I was thinking of modifying the code so that it looked like this:
> String keepAlive;
> Configuration keepAliveConf = controller.getChild( "keep-alive", false );
> if ( null != keepAliveConf )
> {
>     keepAlive = keepAliveConf.getValue( null );
> }
> else
> {
>     keepAlive = "SELECT 1";
> }
> 
> This way, you would get the following results:
>      <pool-controller min="5" max="10" 
> connection-class="my.overrided.ConnectionClass">
>        <keep-alive>CUSTOM QUERY</keep-alive>
>      </pool-controller>
> => keepAlive = "CUSTOM QUERY"
> 
>      <pool-controller min="5" max="10" 
> connection-class="my.overrided.ConnectionClass">
>        <keep-alive></keep-alive>
>      </pool-controller>
> => keepAlive = null
> 
>      <pool-controller min="5" max="10" 
> connection-class="my.overrided.ConnectionClass">
>        <keep-alive/>
>      </pool-controller>
> => keepAlive = null
> 
>       <pool-controller min="5" max="10" 
> connection-class="my.overrided.ConnectionClass"/>
> => keepAlive = "SELECT 1"
> 
> Another option would be to add an attribute to the pool-controller to 
> disable pinging
>       <pool-controller min="5" max="10" 
> connection-class="my.overrided.ConnectionClass" keep-alive="no"/>
> 
> Any opinions.  I think that this last option of adding an attribute 
> would be the least likely to cause problems.
> 
> Once this is resolved, I can move on to fix the NPE that Alexander was 
> encountering.
> 
> Thanks
> Leif
> 
> Alexander \"Stiefel\" Müller wrote:
> 
> >hello,
> >
> >my update was 2 days ago, for i was setting up eclipse,
> >i did a update right now, and the bug in JdbcDataSource is still there:
> >
> >            if (oradb)
> >            {
> >                keepAlive = "SELECT 1 FROM DUAL";
> >
> >                if (getLogger().isWarnEnabled())
> >                {
> >                    getLogger().warn("The oradb attribute is 
> deprecated, please use the" +
> >                                     "keep-alive element instead.");
> >                }
> >            }
> >            else
> >            {
> >                keepAlive = "SELECT 1"; <<<<<<<<<<<
you always set this
> >            }
> >
> >i see there's a new version of AbstractJdbcConnection, but 
> JdbcConnectionFactory still
> >does not allow m_keepAlive to be null:
> >
> >        if ( null != this.m_class )
> >        {
> >            try
> >            {
> >                Class[] paramTypes = new Class[] { Connection.class, 
> String.class };
> >                Object[] params = new Object[] { connection, 
> this.m_keepAlive };
> >
> >                Constructor constructor = m_class.getConstructor( 
> paramTypes );
> >                jdbcConnection = (AbstractJdbcConnection) 
> constructor.newInstance( params ); <<< fails with NullPointerException
> >            }
> >            catch ( Exception e )
> >            {
> >                try
> >                {
> >                    Class[] paramTypes = new Class[] { 
> Connection.class, boolean.class };
> >                    Object[] params = new Object[] { connection, new 
> Boolean( 
> this.m_keepAlive.equalsIgnoreCase(JdbcConnectionFactory.ORACLE_KEEPALI
> VE) ) }; <<< this too
> >
> >
> >
> >Mit freundlichen Grüßen / Best Regards,
> >
> >Alexander "Stiefel" Müller
> >Geschäftsführer
> >
> >stiefelnet e-Solver GmbH
> >Friedensplatz 4; D-01309 Dresden
> >www.stiefelnet.de
> >
> >fon    +49 (0)3 51 - 31 25 41 0
> >fax    +49 (0)3 51 - 31 25 41 7
> >mobil  +49 (0)1 71 - 48 10 96 9
> >e-mail stiefel@stiefelnet.de
> >
> >>-----Original Message-----
> >>From: Berin Loritsch [mailto:bloritsch@apache.org]
> >>Sent: Thursday, January 24, 2002 9:35 PM
> >>To: Avalon Developers List
> >>Subject: Re: Bug in Excalibur Datasource package
> >>
> >>
> >>Alexander \"Stiefel\" Müller wrote:
> >>
> >>>hi all,
> >>>
> >>>i'm using the excalibur datasource package to access a IBM DB2 database,
> >>>which does not support the default <keep-alive> SELECT 1
> >>>i did not find any similar in db2 (and for performace reasons) i 
> >>>
> >>removed the <keep-alive> config.
> >>
> >>>now i got errors during startup, which are "bugs" in some of the files.
> >>>somebody may commit this to cvs. i used a cvs-checkout a few days ago.
> >>>i subscribed to this list today, so i do not know if this is a 
> >>>
> >>"known bug" (or a feature??)
> >>
> >>
> >>When was the last time you got a snapshot from Avalon Excalibur?
> >>
> >>The current CVS addressed alot of issues including the one you have here.
> >>Let me know if it is still broken.
> >>
> >>
> >>BTW, we are currently renewing effort on releasing Excalibur 4.1 RSN.
> >>
> >>
> >>
> >>-- 
> >>
> >>"They that give up essential liberty to obtain a little temporary safety
> >>  deserve neither liberty nor safety."
> >>                 - Benjamin Franklin
> >>
> >>
> >>--
> >>To unsubscribe, e-mail:   <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
> >>For additional commands, e-mail: <mailto:avalon-dev-help@jakarta.apache.or
> >>
> >g>
> >
> 
> 
> 
> --
> To unsubscribe, e-mail:   <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: <mailto:avalon-dev-help@jakarta.apache.org>
Mime
View raw message