diff --git a/be/src/vec/exec/vjdbc_connector.cpp b/be/src/vec/exec/vjdbc_connector.cpp index 63116889f893b6..9924df7b3607a1 100644 --- a/be/src/vec/exec/vjdbc_connector.cpp +++ b/be/src/vec/exec/vjdbc_connector.cpp @@ -70,23 +70,51 @@ JdbcConnector::~JdbcConnector() { Status JdbcConnector::close(Status /*unused*/) { SCOPED_RAW_TIMER(&_jdbc_statistic._connector_close_timer); - _closed = true; + if (_closed) { + return Status::OK(); + } if (!_is_open) { + _closed = true; return Status::OK(); } + + JNIEnv* env = nullptr; + Status status = JniUtil::GetJNIEnv(&env); + if (!status.ok() || env == nullptr) { + LOG(WARNING) << "Failed to get JNIEnv in close(): " << status.to_string(); + _closed = true; + return status; + } + + // Try to abort transaction and call Java close(), but don't block cleanup if (_is_in_transaction) { - RETURN_IF_ERROR(abort_trans()); + Status abort_status = abort_trans(); + if (!abort_status.ok()) { + LOG(WARNING) << "Failed to abort transaction: " << abort_status.to_string(); + } } - JNIEnv* env = nullptr; - RETURN_IF_ERROR(JniUtil::GetJNIEnv(&env)); + env->CallNonvirtualVoidMethod(_executor_obj, _executor_clazz, _executor_close_id); - RETURN_ERROR_IF_EXC(env); - env->DeleteGlobalRef(_executor_factory_clazz); - RETURN_ERROR_IF_EXC(env); - env->DeleteGlobalRef(_executor_clazz); - RETURN_IF_ERROR(JniUtil::GetJniExceptionMsg(env)); - env->DeleteGlobalRef(_executor_obj); - RETURN_ERROR_IF_EXC(env); + if (env->ExceptionCheck()) { + LOG(WARNING) << "Java close() failed: " << JniUtil::GetJniExceptionMsg(env).to_string(); + env->ExceptionClear(); + } + + // Always delete Global References to allow Java GC + if (_executor_factory_clazz != nullptr) { + env->DeleteGlobalRef(_executor_factory_clazz); + _executor_factory_clazz = nullptr; + } + if (_executor_clazz != nullptr) { + env->DeleteGlobalRef(_executor_clazz); + _executor_clazz = nullptr; + } + if (_executor_obj != nullptr) { + env->DeleteGlobalRef(_executor_obj); + _executor_obj = nullptr; + } + + _closed = true; return Status::OK(); } diff --git a/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java b/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java index 0ef1f646d93537..3160ff6fd0f291 100644 --- a/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java +++ b/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java @@ -127,7 +127,11 @@ public BaseJdbcExecutor(byte[] thriftParams) throws Exception { public void close() throws Exception { if (outputTable != null) { - outputTable.close(); + try { + outputTable.close(); + } finally { + outputTable = null; + } } try { if (stmt != null && !stmt.isClosed()) { @@ -143,10 +147,17 @@ public void close() throws Exception { } } finally { closeResources(resultSet, stmt, conn); + // Always clear references to help GC, even if close() failed + resultSet = null; + stmt = null; + conn = null; if (config.getConnectionPoolMinSize() == 0 && hikariDataSource != null) { - hikariDataSource.close(); - JdbcDataSource.getDataSource().getSourcesMap().remove(config.createCacheKey()); - hikariDataSource = null; + try { + hikariDataSource.close(); + JdbcDataSource.getDataSource().getSourcesMap().remove(config.createCacheKey()); + } finally { + hikariDataSource = null; + } } } }