I'm circling back to this after a few months.  I am building on a Windows 10 box with 9.0.52 TC.  But I'm running on an AWS Linux2 with 8.5.72.  This has never caused any problems so far, or at least as far as I can tell.  But I'm hitting something strange with this relatively new BasicDataSource.restart() method.   My reference to restart() builds fine.  But when I run it on the 8.5.72 server I get:  java.lang.NoSuchMethodError: 'void org.apache.tomcat.dbcp.dbcp2.BasicDataSource.restart()'

Rémy mentioned that it should be in TC 8.5.58+.   This is a relatively clean EC2 on AWS, not running much other than Tomcat. And I have not done in backdoor (non yum) installs of TC that might have left old jar files around.   I noticed that there are 2 dbcp2 jar files in TC's lib.  One is from the java install.  But the error message above is a tomcat path.  So I'm assuming it's tomcat's dbcp2 jar that's being referenced.  I exploded the jar hoping there would be some version numbers somewhere inside telling me if I somehow have a backlevel jar.  But I couldn't find anything.  All I know is it's date is 2/25/2021 and it's 286,358 bytes.

Any other ideas come to mind why it's telling me the restart() method doesn't exist?

Thx as always.

Jerry


On 9/7/2021 2:49 PM, Jerry Malcolm wrote:

On 9/7/2021 2:35 PM, Christopher Schultz wrote:
Jerry, Rémy,

On 9/3/21 07:15, Rémy Maucherat wrote:
On Fri, Sep 3, 2021 at 2:46 AM Jerry Malcolm <techst...@malcolms.com> wrote:

I have a requirement to start a new log database on the first of every
month.  I still need to have access to older monthly log databases.   I
do not want to create a bunch of hardcoded manually configured
individual datasources, one for each month.  I have a dynamic datasource
solution that is completely implemented and working except for one
little thing.

I access the BasicDataSource implementation class for the datasource.  I
have an algorithm that substitutes yyyy_MM at the appropriate spot in
the configured URL and then updates the url in the datasource.   All of this works great.  I can live with the fact that the datasource can only
point to one database at a time.  My concern is that once I transition
to another database, there are existing connections in the pool that are
already attached to the old database.  I need to clear those out and
start over.  But I don't have the luxury of bouncing tomcat to clean it up.

The apache commons BasicDataSource has a restart() method. But
unfortunately that method is omitted from the Tomcat version. There is a
close() method on the BasicDataSource.  But I don't see anything that
will re-open it after closing.  I thought about changing maxActive to 0,
and waiting for it to drain, then setting it back to the original
value.  None of these sound like an ideal solution.  Without a restart()
method, is there any other way to force all existing connections to
close and start clean?

The code is kept in sync with DBCP (with a bit of lag maybe), so these
lifecycle methods were also added to Tomcat one year ago (9.0.38+ and
8.5.58+).

We are using this at $work to bounce our database connection pools after TLS client certificate changes. This is the code we are using to reload the pool:

  try
  {
      Context ctx = new InitialContext();

      DataSource ds = (DataSource)ctx.lookup(getJNDIPath());

      if(null == ds)
          throw new ServiceException("Cannot obtain DataSource");

      if(isInstanceOf(ds, "org.apache.tomcat.dbcp.dbcp2.BasicDataSource")          || isInstanceOf(ds, "org.apache.commons.dbcp2.BasicDataSource")) {

          return call(ds, "restart");
      }
  } catch (Exception e) {
org.apache.log4j.Logger.getLogger(this.getClass()).error("Failed to reload DataSource " + getJNDIPath());
  }

The call() method simply encapsulates all of the work to make a reflective method call to BasicDataSource.restart().

As Rémy points out, it requires a Tomcat version 9.0.38+ or 8.5.58+.

Hope that helps,
-chris

Chris,

I'll definitely try this.  But I'm curious about the restart method.  Is it some sort of a hidden method that's only available to reflection?  Seems it would be a lot more straightforward to just make the restart method public like it is in the apache version of BasicDataSource.  I'm not complaining.  If this works, then fine.  Just curious.

Thx

Jerry


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to