public T borrowObject()

in src/main/java/org/apache/commons/pool3/impl/GenericObjectPool.java [282:369]


    public T borrowObject(final Duration maxWaitDuration) throws E {
        assertOpen();
        final Instant startInstant = Instant.now();
        final boolean negativeDuration = maxWaitDuration.isNegative();
        Duration remainingWaitDuration = maxWaitDuration;
        final AbandonedConfig ac = this.abandonedConfig;
        if (ac != null && ac.getRemoveAbandonedOnBorrow() && getNumIdle() < 2 && getNumActive() > getMaxTotal() - 3) {
            removeAbandoned(ac);
        }
        PooledObject<T> p = null;
        // Get local copy of current config so it is consistent for entire
        // method execution
        final boolean blockWhenExhausted = getBlockWhenExhausted();
        boolean create;
        while (p == null) {
            remainingWaitDuration = maxWaitDuration.minus(durationSince(startInstant));
            create = false;
            p = idleObjects.pollFirst();
            if (p == null) {
                p = create(remainingWaitDuration);
                if (!PooledObject.isNull(p)) {
                    create = true;
                }
            }
            if (blockWhenExhausted) {
                if (PooledObject.isNull(p)) {
                    try {
                        remainingWaitDuration = maxWaitDuration.minus(durationSince(startInstant));
                        p = negativeDuration ? idleObjects.takeFirst() : idleObjects.pollFirst(maxWaitDuration);
                    } catch (final InterruptedException e) {
                        // Don't surface exception type of internal locking mechanism.
                        throw cast(e);
                    }
                }
                if (PooledObject.isNull(p)) {
                    throw new NoSuchElementException(appendStats("Timeout waiting for idle object, borrowMaxWaitDuration=" + remainingWaitDuration));
                }
            } else if (PooledObject.isNull(p)) {
                throw new NoSuchElementException(appendStats("Pool exhausted"));
            }
            if (!p.allocate()) {
                p = null;
            }
            if (!PooledObject.isNull(p)) {
                try {
                    factory.activateObject(p);
                } catch (final Exception e) {
                    try {
                        destroy(p, DestroyMode.NORMAL);
                    } catch (final Exception ignored) {
                        // ignored - activation failure is more important
                    }
                    p = null;
                    if (create) {
                        final NoSuchElementException nsee = new NoSuchElementException(appendStats("Unable to activate object"));
                        nsee.initCause(e);
                        throw nsee;
                    }
                }
                if (!PooledObject.isNull(p) && getTestOnBorrow()) {
                    boolean validate = false;
                    Throwable validationThrowable = null;
                    try {
                        validate = factory.validateObject(p);
                    } catch (final Throwable t) {
                        PoolUtils.checkRethrow(t);
                        validationThrowable = t;
                    }
                    if (!validate) {
                        try {
                            destroy(p, DestroyMode.NORMAL);
                            destroyedByBorrowValidationCount.incrementAndGet();
                        } catch (final Exception ignored) {
                            // ignored - validation failure is more important
                        }
                        p = null;
                        if (create) {
                            final NoSuchElementException nsee = new NoSuchElementException(appendStats("Unable to validate object"));
                            nsee.initCause(validationThrowable);
                            throw nsee;
                        }
                    }
                }
            }
        }
        updateStatsBorrow(p, durationSince(startInstant));
        return p.getObject();
    }