Exemple #1
0
  static {
    classNamesToConnectionTesters.put(
        C3P0Defaults.connectionTesterClassName(), C3P0Defaults.connectionTester());

    String userManagementCoordinator = C3P0ConfigUtils.getPropsFileConfigProperty(MC_PARAM);
    if (userManagementCoordinator != null) {
      try {
        mc = (ManagementCoordinator) Class.forName(userManagementCoordinator).newInstance();
      } catch (Exception e) {
        if (logger.isLoggable(MLevel.WARNING))
          logger.log(
              MLevel.WARNING,
              "Could not instantiate user-specified ManagementCoordinator "
                  + userManagementCoordinator
                  + ". Using NullManagementCoordinator (c3p0 JMX management disabled!)",
              e);
        mc = new NullManagementCoordinator();
      }
    } else {
      try {
        Class.forName("java.lang.management.ManagementFactory");

        mc =
            (ManagementCoordinator)
                Class.forName("com.mchange.v2.c3p0.management.ActiveManagementCoordinator")
                    .newInstance();
      } catch (Exception e) {
        if (logger.isLoggable(MLevel.INFO))
          logger.log(
              MLevel.INFO, "jdk1.5 management interfaces unavailable... JMX support disabled.", e);
        mc = new NullManagementCoordinator();
      }
    }
  }
  public void addStatementEventListener(StatementEventListener sel) {
    if (logger.isLoggable(MLevel.INFO))
      logger.info(
          "Per the JDBC4 spec, "
              + this.getClass().getName()
              + " accepts StatementListeners, but for now there is no circumstance under which they are notified!");

    ses.addStatementEventListener(sel);
  }
Exemple #3
0
 // must be called from a static sync'ed method
 private static void banner() {
   if (!banner_printed) {
     if (logger.isLoggable(MLevel.INFO))
       logger.info(
           "Initializing c3p0-"
               + C3P0Substitutions.VERSION
               + " [built "
               + C3P0Substitutions.TIMESTAMP
               + "; debug? "
               + C3P0Substitutions.DEBUG
               + "; trace: "
               + C3P0Substitutions.TRACE
               + ']');
     banner_printed = true;
   }
 }
  boolean closeAndRemoveResourcesInSet(Set s, Method closeMethod) {
    boolean okay = true;

    Set temp;
    synchronized (s) {
      temp = new HashSet(s);
    }

    for (Iterator ii = temp.iterator(); ii.hasNext(); ) {
      Object rsrc = ii.next();
      try {
        closeMethod.invoke(rsrc, CLOSE_ARGS);
      } catch (Exception e) {
        Throwable t = e;
        if (t instanceof InvocationTargetException)
          t = ((InvocationTargetException) e).getTargetException();
        logger.log(MLevel.WARNING, "An exception occurred while cleaning up a resource.", t);
        // t.printStackTrace();
        okay = false;
      } finally {
        s.remove(rsrc);
      }
    }

    // We had to abandon the idea of simply iterating over s directly, because
    // our resource close methods sometimes try to remove the resource from
    // its parent Set. This is important (when the user closes the resources
    // directly), but leads to ConcurrenModificationExceptions while we are
    // iterating over the Set to close. So, now we iterate over a copy, but remove
    // from the original Set. Since removal is idempotent, it don't matter if
    // the close method already provoked a remove. Sucks that we have to copy
    // the set though.
    //
    // Original (direct iteration) version:
    //
    //  	synchronized (s)
    //  	    {
    //  		for (Iterator ii = s.iterator(); ii.hasNext(); )
    //  		    {
    //  			Object rsrc = ii.next();
    //  			try
    //  			    { closeMethod.invoke(rsrc, CLOSE_ARGS); }
    //  			catch (Exception e)
    //  			    {
    //  				Throwable t = e;
    //  				if (t instanceof InvocationTargetException)
    //  				    t = ((InvocationTargetException) e).getTargetException();
    //  				t.printStackTrace();
    //  				okay = false;
    //  			    }
    //  			finally
    //  			    { ii.remove(); }
    //  		    }
    //  	    }

    return okay;
  }
Exemple #5
0
 public static ConnectionTester getConnectionTester(String className) {
   try {
     ConnectionTester out = (ConnectionTester) classNamesToConnectionTesters.get(className);
     if (out == null) {
       out = (ConnectionTester) Class.forName(className).newInstance();
       classNamesToConnectionTesters.put(className, out);
     }
     return out;
   } catch (Exception e) {
     if (logger.isLoggable(MLevel.WARNING))
       logger.log(
           MLevel.WARNING,
           "Could not create for find ConnectionTester with class name '"
               + className
               + "'. Using default.",
           e);
     return C3P0Defaults.connectionTester();
   }
 }
 synchronized void closeMaybeCheckedOut(boolean checked_out) throws SQLException {
   if (checked_out) {
     // reset transaction state
     try {
       C3P0ImplUtils.resetTxnState(
           physicalConnection, forceIgnoreUnresolvedTransactions, autoCommitOnClose, false);
     } catch (Exception e) {
       if (logger.isLoggable(MLevel.FINER))
         logger.log(
             MLevel.FINER,
             "Failed to reset the transaction state of  "
                 + physicalConnection
                 + "just prior to close(). "
                 + "Only relevant at all if this was a Connection being forced close()ed midtransaction.",
             e);
     }
   }
   close(false);
 }
  private void reset(boolean known_resolved_txn) throws SQLException {
    ensureOkay();
    C3P0ImplUtils.resetTxnState(
        physicalConnection,
        forceIgnoreUnresolvedTransactions,
        autoCommitOnClose,
        known_resolved_txn);
    if (isolation_lvl_nondefault) {
      physicalConnection.setTransactionIsolation(dflt_txn_isolation);
      isolation_lvl_nondefault = false;
    }
    if (catalog_nondefault) {
      physicalConnection.setCatalog(dflt_catalog);
      catalog_nondefault = false;
    }
    if (holdability_nondefault) // we don't test if holdability is supported, 'cuz it can never go
                                // nondefault if it's not.
    {
      physicalConnection.setHoldability(dflt_holdability);
      holdability_nondefault = false;
    }

    try {
      physicalConnection.setReadOnly(false);
    } catch (Throwable t) {
      if (logger.isLoggable(MLevel.FINE))
        logger.log(
            MLevel.FINE,
            "A Throwable occurred while trying to reset the readOnly property of our Connection to false!",
            t);
    }

    try {
      if (supports_setTypeMap) physicalConnection.setTypeMap(Collections.EMPTY_MAP);
    } catch (Throwable t) {
      if (logger.isLoggable(MLevel.FINE))
        logger.log(
            MLevel.FINE,
            "A Throwable occurred while trying to reset the typeMap property of our Connection to Collections.EMPTY_MAP!",
            t);
    }
  }
  // must be called from sync'ed method
  private void doBadUpdate(int new_status) {
    this.connection_status = new_status;
    try {
      this.close(true);
    } catch (SQLException e) {
      // 		System.err.print("Broken Connection Close Error: ");
      // 		e.printStackTrace();

      logger.log(MLevel.WARNING, "Broken Connection Close Error. ", e);
    }
  }
Exemple #9
0
 public static ConnectionCustomizer getConnectionCustomizer(String className) throws SQLException {
   if (className == null) return null;
   else {
     try {
       ConnectionCustomizer out =
           (ConnectionCustomizer) classNamesToConnectionCustomizers.get(className);
       if (out == null) {
         out = (ConnectionCustomizer) Class.forName(className).newInstance();
         classNamesToConnectionCustomizers.put(className, out);
       }
       return out;
     } catch (Exception e) {
       if (logger.isLoggable(MLevel.WARNING))
         logger.log(
             MLevel.WARNING,
             "Could not create for find ConnectionCustomizer with class name '" + className + "'.",
             e);
       throw SqlUtils.toSQLException(e);
     }
   }
 }
 boolean closeAndRemoveResultSets(Set rsSet) {
   boolean okay = true;
   synchronized (rsSet) {
     for (Iterator ii = rsSet.iterator(); ii.hasNext(); ) {
       ResultSet rs = (ResultSet) ii.next();
       try {
         rs.close();
       } catch (SQLException e) {
         if (Debug.DEBUG)
           logger.log(MLevel.WARNING, "An exception occurred while cleaning up a ResultSet.", e);
         // e.printStackTrace();
         okay = false;
       } finally {
         ii.remove();
       }
     }
   }
   return okay;
 }
  // must be called from sync'ed method to protecte
  // exposedProxy
  private Connection getCreateNewConnection() throws SQLException {
    try {
      // DEBUG
      // origGet = new Exception("[DOUBLE_GET_TESTER] -- Orig Get");

      ensureOkay();
      /*
       * we reset the physical connection when we close an exposed proxy
       * no need to do it again when we create one
       */
      // reset();
      return (exposedProxy = createProxyConnection());
    } catch (SQLException e) {
      throw e;
    } catch (Exception e) {
      // e.printStackTrace();
      logger.log(MLevel.WARNING, "Failed to acquire connection!", e);
      throw new SQLException("Failed to acquire connection!");
    }
  }
  // synchronized to protect exposedProxy
  public synchronized Connection getConnection() throws SQLException {
    if (exposedProxy != null) {
      // DEBUG
      // System.err.println("[DOUBLE_GET_TESTER] -- double getting a Connection from " + this );
      // new Exception("[DOUBLE_GET_TESTER] -- Double-Get Stack Trace").printStackTrace();
      // origGet.printStackTrace();

      // 		System.err.println("c3p0 -- Uh oh... getConnection() was called on a PooledConnection
      // when " +
      // 				   "it had already provided a client with a Connection that has not yet been " +
      // 				   "closed. This probably indicates a bug in the connection pool!!!");

      logger.warning(
          "c3p0 -- Uh oh... getConnection() was called on a PooledConnection when "
              + "it had already provided a client with a Connection that has not yet been "
              + "closed. This probably indicates a bug in the connection pool!!!");

      return exposedProxy;
    } else {
      return getCreateNewConnection();
    }
  }
  static {
    try {
      CON_PROXY_CTOR = createProxyConstructor(ProxyConnection.class);

      Class[] argClasses = new Class[0];
      RS_CLOSE_METHOD = ResultSet.class.getMethod("close", argClasses);
      STMT_CLOSE_METHOD = Statement.class.getMethod("close", argClasses);

      CLOSE_ARGS = new Object[0];

      OBJECT_METHODS =
          Collections.unmodifiableSet(new HashSet(Arrays.asList(Object.class.getMethods())));
    } catch (Exception e) {
      // e.printStackTrace();
      logger.log(
          MLevel.SEVERE,
          "An Exception occurred in static initializer of" + C3P0PooledConnection.class.getName(),
          e);
      throw new InternalError(
          "Something is very wrong, or this is a pre 1.3 JVM."
              + "We cannot set up dynamic proxies and/or methods!");
    }
  }
  public Reference createReference(Object bean) throws NamingException {
    try {
      BeanInfo bi = Introspector.getBeanInfo(bean.getClass());
      PropertyDescriptor[] pds = bi.getPropertyDescriptors();
      List refAddrs = new ArrayList();
      String factoryClassLocation = defaultFactoryClassLocation;

      boolean using_ref_props = referenceProperties.size() > 0;

      // we only include this so that on dereference we are not surprised to find some properties
      // missing
      if (using_ref_props)
        refAddrs.add(
            new BinaryRefAddr(REF_PROPS_KEY, SerializableUtils.toByteArray(referenceProperties)));

      for (int i = 0, len = pds.length; i < len; ++i) {
        PropertyDescriptor pd = pds[i];
        String propertyName = pd.getName();
        // System.err.println("Making Reference: " + propertyName);

        if (using_ref_props && !referenceProperties.contains(propertyName)) {
          // System.err.println("Not a ref_prop -- continuing.");
          continue;
        }

        Class propertyType = pd.getPropertyType();
        Method getter = pd.getReadMethod();
        Method setter = pd.getWriteMethod();
        if (getter != null
            && setter != null) // only use properties that are both readable and writable
        {
          Object val = getter.invoke(bean, EMPTY_ARGS);
          // System.err.println( "val: " + val );
          if (propertyName.equals("factoryClassLocation")) {
            if (String.class != propertyType)
              throw new NamingException(
                  this.getClass().getName()
                      + " requires a factoryClassLocation property to be a string, "
                      + propertyType.getName()
                      + " is not valid.");
            factoryClassLocation = (String) val;
          }

          if (val == null) {
            RefAddr addMe = new BinaryRefAddr(propertyName, NULL_TOKEN_BYTES);
            refAddrs.add(addMe);
          } else if (Coerce.canCoerce(propertyType)) {
            RefAddr addMe = new StringRefAddr(propertyName, String.valueOf(val));
            refAddrs.add(addMe);
          } else // other Object properties
          {
            RefAddr addMe = null;
            PropertyEditor pe = BeansUtils.findPropertyEditor(pd);
            if (pe != null) {
              pe.setValue(val);
              String textValue = pe.getAsText();
              if (textValue != null) addMe = new StringRefAddr(propertyName, textValue);
            }
            if (addMe == null) // property editor approach failed
            addMe =
                  new BinaryRefAddr(
                      propertyName,
                      SerializableUtils.toByteArray(
                          val, indirector, IndirectPolicy.INDIRECT_ON_EXCEPTION));
            refAddrs.add(addMe);
          }
        } else {
          // 				System.err.println(this.getClass().getName() +
          // 						   ": Skipping " + propertyName + " because it is " + (setter == null ?
          // "read-only." : "write-only."));

          if (logger.isLoggable(MLevel.WARNING))
            logger.warning(
                this.getClass().getName()
                    + ": Skipping "
                    + propertyName
                    + " because it is "
                    + (setter == null ? "read-only." : "write-only."));
        }
      }
      Reference out =
          new Reference(bean.getClass().getName(), factoryClassName, factoryClassLocation);
      for (Iterator ii = refAddrs.iterator(); ii.hasNext(); ) out.add((RefAddr) ii.next());
      return out;
    } catch (Exception e) {
      // e.printStackTrace();
      if (Debug.DEBUG && logger.isLoggable(MLevel.FINE))
        logger.log(MLevel.FINE, "Exception trying to create Reference.", e);

      throw new NamingException("Could not create reference from bean: " + e.toString());
    }
  }
  /*
   * TODO: factor all this convolution out into
   *       C3P0Statement
   */
  Statement createProxyStatement( // final Method cachedStmtProducingMethod,
      // final Object[] cachedStmtProducingMethodArgs,
      final boolean inner_is_cached,
      final Statement innerStmt)
      throws Exception {
    final Set activeResultSets = Collections.synchronizedSet(new HashSet());
    final Connection parentConnection = exposedProxy;

    if (Debug.DEBUG && parentConnection == null) {
      // 		System.err.print("PROBABLE C3P0 BUG -- ");
      // 		System.err.println(this + ": created a proxy Statement when there is no active, exposed
      // proxy Connection???");

      logger.warning(
          "PROBABLE C3P0 BUG -- "
              + this
              + ": created a proxy Statement when there is no active, exposed proxy Connection???");
    }

    // we can use this one wrapper under all circumstances
    // except jdbc3 CallableStatement multiple open ResultSets...
    // avoid object allocation in statement methods where possible.
    final StatementProxyingSetManagedResultSet mainResultSet =
        new StatementProxyingSetManagedResultSet(activeResultSets);

    class WrapperStatementHelper {
      Statement wrapperStmt;
      Statement nakedInner;

      public WrapperStatementHelper(Statement wrapperStmt, Statement nakedInner) {
        this.wrapperStmt = wrapperStmt;
        this.nakedInner = nakedInner;

        if (!inner_is_cached) uncachedActiveStatements.add(wrapperStmt);
      }

      private boolean closeAndRemoveActiveResultSets() {
        return closeAndRemoveResultSets(activeResultSets);
      }

      public ResultSet wrap(ResultSet rs) {
        if (mainResultSet.getInner() == null) {
          mainResultSet.setInner(rs);
          mainResultSet.setProxyStatement(wrapperStmt);
          return mainResultSet;
        } else {
          // for the case of multiple open ResultSets
          StatementProxyingSetManagedResultSet out =
              new StatementProxyingSetManagedResultSet(activeResultSets);
          out.setInner(rs);
          out.setProxyStatement(wrapperStmt);
          return out;
        }
      }

      public void doClose() throws SQLException {
        boolean okay = closeAndRemoveActiveResultSets();

        if (inner_is_cached) // this statement was cached
        scache.checkinStatement(innerStmt);
        else {
          innerStmt.close();
          uncachedActiveStatements.remove(wrapperStmt);
        }

        if (!okay) throw new SQLException("Failed to close an orphaned ResultSet properly.");
      }

      public Object doRawStatementOperation(Method m, Object target, Object[] args)
          throws IllegalAccessException, InvocationTargetException, SQLException {
        if (target == C3P0ProxyStatement.RAW_STATEMENT) target = nakedInner;
        for (int i = 0, len = args.length; i < len; ++i)
          if (args[i] == C3P0ProxyStatement.RAW_STATEMENT) args[i] = nakedInner;

        Object out = m.invoke(target, args);

        if (out instanceof ResultSet) out = wrap((ResultSet) out);

        return out;
      }
    }

    if (innerStmt instanceof CallableStatement) {
      class ProxyCallableStatement extends FilterCallableStatement implements C3P0ProxyStatement {
        WrapperStatementHelper wsh;

        ProxyCallableStatement(CallableStatement is) {
          super(is);
          this.wsh = new WrapperStatementHelper(this, is);
        }

        public Connection getConnection() {
          return parentConnection;
        }

        public ResultSet getResultSet() throws SQLException {
          return wsh.wrap(super.getResultSet());
        }

        public ResultSet getGeneratedKeys() throws SQLException {
          return wsh.wrap(super.getGeneratedKeys());
        }

        public ResultSet executeQuery(String sql) throws SQLException {
          return wsh.wrap(super.executeQuery(sql));
        }

        public ResultSet executeQuery() throws SQLException {
          return wsh.wrap(super.executeQuery());
        }

        public Object rawStatementOperation(Method m, Object target, Object[] args)
            throws IllegalAccessException, InvocationTargetException, SQLException {
          return wsh.doRawStatementOperation(m, target, args);
        }

        public void close() throws SQLException {
          wsh.doClose();
        }
      }

      return new ProxyCallableStatement((CallableStatement) innerStmt);
    } else if (innerStmt instanceof PreparedStatement) {
      class ProxyPreparedStatement extends FilterPreparedStatement implements C3P0ProxyStatement {
        WrapperStatementHelper wsh;

        ProxyPreparedStatement(PreparedStatement ps) {
          super(ps);
          this.wsh = new WrapperStatementHelper(this, ps);
        }

        public Connection getConnection() {
          return parentConnection;
        }

        public ResultSet getResultSet() throws SQLException {
          return wsh.wrap(super.getResultSet());
        }

        public ResultSet getGeneratedKeys() throws SQLException {
          return wsh.wrap(super.getGeneratedKeys());
        }

        public ResultSet executeQuery(String sql) throws SQLException {
          return wsh.wrap(super.executeQuery(sql));
        }

        public ResultSet executeQuery() throws SQLException {
          return wsh.wrap(super.executeQuery());
        }

        public Object rawStatementOperation(Method m, Object target, Object[] args)
            throws IllegalAccessException, InvocationTargetException, SQLException {
          return wsh.doRawStatementOperation(m, target, args);
        }

        public void close() throws SQLException {
          wsh.doClose();
        }
      }

      return new ProxyPreparedStatement((PreparedStatement) innerStmt);
    } else {
      class ProxyStatement extends FilterStatement implements C3P0ProxyStatement {
        WrapperStatementHelper wsh;

        ProxyStatement(Statement s) {
          super(s);
          this.wsh = new WrapperStatementHelper(this, s);
        }

        public Connection getConnection() {
          return parentConnection;
        }

        public ResultSet getResultSet() throws SQLException {
          return wsh.wrap(super.getResultSet());
        }

        public ResultSet getGeneratedKeys() throws SQLException {
          return wsh.wrap(super.getGeneratedKeys());
        }

        public ResultSet executeQuery(String sql) throws SQLException {
          return wsh.wrap(super.executeQuery(sql));
        }

        public Object rawStatementOperation(Method m, Object target, Object[] args)
            throws IllegalAccessException, InvocationTargetException, SQLException {
          return wsh.doRawStatementOperation(m, target, args);
        }

        public void close() throws SQLException {
          wsh.doClose();
        }
      }

      return new ProxyStatement(innerStmt);
    }
  }
  // TODO: factor out repetitive debugging code
  private synchronized void close(boolean known_invalid) throws SQLException {
    // System.err.println("Closing " + this);
    if (physicalConnection != null) {
      try {
        StringBuffer debugOnlyLog = null;
        if (Debug.DEBUG && known_invalid) {
          debugOnlyLog = new StringBuffer();
          debugOnlyLog.append("[ exceptions: ");
        }

        Exception exc = cleanupUncachedActiveStatements();
        if (Debug.DEBUG && exc != null) {
          if (known_invalid) debugOnlyLog.append(exc.toString() + ' ');
          else
            logger.log(
                MLevel.WARNING,
                "An exception occurred while cleaning up uncached active Statements.",
                exc);
          // exc.printStackTrace();
        }

        try {
          // we've got to use silentClose() rather than close() here,
          // 'cuz if there's still an exposedProxy (say a user forgot to
          // close his Connection) before we close, and we use regular (loud)
          // close, we will try to check this dead or dying PooledConnection
          // back into the pool. We only want to do this when close is called
          // on user proxies, and the underlying PooledConnection might still
          // be good. The PooledConnection itself should only be closed by the
          // pool.
          if (exposedProxy != null) exposedProxy.silentClose(known_invalid);
        } catch (Exception e) {
          if (Debug.DEBUG) {
            if (known_invalid) debugOnlyLog.append(e.toString() + ' ');
            else logger.log(MLevel.WARNING, "An exception occurred.", exc);
            // e.printStackTrace();
          }
          exc = e;
        }
        try {
          this.closeAll();
        } catch (Exception e) {
          if (Debug.DEBUG) {
            if (known_invalid) debugOnlyLog.append(e.toString() + ' ');
            else logger.log(MLevel.WARNING, "An exception occurred.", exc);
            // e.printStackTrace();
          }
          exc = e;
        }

        try {
          physicalConnection.close();
        } catch (Exception e) {
          if (Debug.DEBUG) {
            if (known_invalid) debugOnlyLog.append(e.toString() + ' ');
            else logger.log(MLevel.WARNING, "An exception occurred.", exc);
            e.printStackTrace();
          }
          exc = e;
        }

        if (exc != null) {
          if (known_invalid) {
            debugOnlyLog.append(" ]");
            if (Debug.DEBUG) {
              // 						System.err.print("[DEBUG]" + this + ": while closing a PooledConnection known
              // to be invalid, ");
              // 						System.err.println("  some exceptions occurred. This is probably not a
              // problem:");
              // 						System.err.println( debugOnlyLog.toString() );

              logger.fine(
                  this
                      + ": while closing a PooledConnection known to be invalid, "
                      + "  some exceptions occurred. This is probably not a problem: "
                      + debugOnlyLog.toString());
            }
          } else
            throw new SQLException(
                "At least one error occurred while attempting "
                    + "to close() the PooledConnection: "
                    + exc);
        }
        if (Debug.TRACE == Debug.TRACE_MAX)
          logger.fine("C3P0PooledConnection closed. [" + this + ']');
        // System.err.println("C3P0PooledConnection closed. [" + this + ']');
      } finally {
        physicalConnection = null;
      }
    }
  }