From ddfc612079184a85036ba7a5c8ab075deefd88fa Mon Sep 17 00:00:00 2001 From: David Li Date: Wed, 25 Dec 2024 22:28:36 -0500 Subject: [PATCH] feat(java/driver/jni): add JNI bindings to native driver manager Fixes #2027. --- c/driver_manager/adbc_driver_manager.cc | 2 +- java/CMakeLists.txt | 61 ++++++++ java/driver/flight-sql/pom.xml | 3 +- java/driver/jni/CMakeLists.txt | 38 +++++ java/driver/jni/pom.xml | 128 +++++++++++++++++ java/driver/jni/src/main/cpp/jni_wrapper.cc | 130 ++++++++++++++++++ .../arrow/adbc/driver/jni/JniDriver.java | 54 ++++++++ .../adbc/driver/jni/JniDriverFactory.java | 30 ++++ .../arrow/adbc/driver/jni/impl/JniLoader.java | 36 +++++ .../adbc/driver/jni/impl/NativeAdbc.java | 23 ++++ .../driver/jni/impl/NativeAdbcException.java | 31 +++++ .../adbc/driver/jni/impl/NativeDriver.java | 52 +++++++ .../arrow/adbc/driver/jni/package-info.java | 18 +++ ...arrow.adbc.drivermanager.AdbcDriverFactory | 18 +++ .../arrow/adbc/driver/jni/JniDriverTest.java | 38 +++++ java/pom.xml | 1 + 16 files changed, 660 insertions(+), 3 deletions(-) create mode 100644 java/CMakeLists.txt create mode 100644 java/driver/jni/CMakeLists.txt create mode 100644 java/driver/jni/pom.xml create mode 100644 java/driver/jni/src/main/cpp/jni_wrapper.cc create mode 100644 java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/JniDriver.java create mode 100644 java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/JniDriverFactory.java create mode 100644 java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/JniLoader.java create mode 100644 java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbc.java create mode 100644 java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbcException.java create mode 100644 java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeDriver.java create mode 100644 java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/package-info.java create mode 100644 java/driver/jni/src/main/resources/META-INF/services/org.apache.arrow.adbc.drivermanager.AdbcDriverFactory create mode 100644 java/driver/jni/src/test/java/org/apache/arrow/adbc/driver/jni/JniDriverTest.java diff --git a/c/driver_manager/adbc_driver_manager.cc b/c/driver_manager/adbc_driver_manager.cc index 0ce173a888..5e4a8b6dfe 100644 --- a/c/driver_manager/adbc_driver_manager.cc +++ b/c/driver_manager/adbc_driver_manager.cc @@ -173,7 +173,7 @@ struct ManagedLibrary { void* handle = dlopen(library, RTLD_NOW | RTLD_LOCAL); if (!handle) { - error_message = "[DriverManager] dlopen() failed: "; + error_message = "dlopen() failed: "; error_message += dlerror(); // If applicable, append the shared library prefix/extension and diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt new file mode 100644 index 0000000000..e4ae54ec38 --- /dev/null +++ b/java/CMakeLists.txt @@ -0,0 +1,61 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +cmake_minimum_required(VERSION 3.16) +message(STATUS "Building using CMake version: ${CMAKE_VERSION}") + +# find_package() uses _ROOT variables. +# https://cmake.org/cmake/help/latest/policy/CMP0074.html +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + +project(adbc-java) + +if("${CMAKE_CXX_STANDARD}" STREQUAL "") + set(CMAKE_CXX_STANDARD 17) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include(GNUInstallDirs) + +# Dependencies + +find_package(Java REQUIRED) +find_package(JNI REQUIRED) + +include(UseJava) + +# ADBC_ARCH_DIR is derived from the architecture. The user can override this +# variable if auto-detection fails. +if("${ADBC_ARCH_DIR}" STREQUAL "") + if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64") + set(ADBC_ARCH_DIR "aarch_64") + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i386") + set(ADBC_ARCH_DIR "x86_64") + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm64") + set(ADBC_ARCH_DIR "aarch_64") + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64") + set(ADBC_ARCH_DIR "x86_64") + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + set(ADBC_ARCH_DIR "x86_64") + else() + message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}") + endif() +endif() + +add_subdirectory(driver/jni) diff --git a/java/driver/flight-sql/pom.xml b/java/driver/flight-sql/pom.xml index 63ad83b11f..d9e8935adb 100644 --- a/java/driver/flight-sql/pom.xml +++ b/java/driver/flight-sql/pom.xml @@ -35,8 +35,7 @@ com.github.ben-manes.caffeine caffeine - - 2.9.3 + 3.1.8 com.google.protobuf diff --git a/java/driver/jni/CMakeLists.txt b/java/driver/jni/CMakeLists.txt new file mode 100644 index 0000000000..90e67f0872 --- /dev/null +++ b/java/driver/jni/CMakeLists.txt @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +find_package(AdbcDriverManager) + +add_jar(adbc_driver_jni_jar + SOURCES src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbc.java + src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbcException.java + src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeDriver.java + GENERATE_NATIVE_HEADERS + adbc_driver_jni_headers) + +add_library(adbc_driver_jni SHARED src/main/cpp/jni_wrapper.cc) +set_property(TARGET adbc_driver_jni PROPERTY OUTPUT_NAME "adbc_drvier_jni") +target_link_libraries(adbc_driver_jni adbc_driver_jni_headers JNI::JNI AdbcDriverManager::adbc_driver_manager_static) + +set(ARROW_JAVA_JNI_C_LIBDIR + "${CMAKE_INSTALL_PREFIX}/lib/adbc_driver_jni/${ADBC_ARCH_DIR}") +set(ADBC_DRIVER_JNI_C_BINDIR + "${CMAKE_INSTALL_PREFIX}/bin/adbc_driver_jni/${ADBC_ARCH_DIR}") + +install(TARGETS adbc_driver_jni + LIBRARY DESTINATION ${ADBC_DRIVER_JNI_C_LIBDIR} + RUNTIME DESTINATION ${ADBC_DRIVER_JNI_C_BINDIR}) diff --git a/java/driver/jni/pom.xml b/java/driver/jni/pom.xml new file mode 100644 index 0000000000..f6892d112a --- /dev/null +++ b/java/driver/jni/pom.xml @@ -0,0 +1,128 @@ + + + + 4.0.0 + + org.apache.arrow.adbc + arrow-adbc-java-root + 0.16.0-SNAPSHOT + ../../pom.xml + + + adbc-driver-jni + jar + Arrow ADBC Driver Native + An ADBC driver wrapping the native driver manager. + + + + com.github.ben-manes.caffeine + caffeine + + 2.9.3 + + + com.google.protobuf + protobuf-java + 4.29.2 + + + + + org.apache.arrow + arrow-memory-core + + + org.apache.arrow + arrow-vector + + + org.apache.arrow + flight-core + + + org.apache.arrow + flight-sql + + + + org.apache.arrow.adbc + adbc-core + + + org.apache.arrow.adbc + adbc-driver-manager + + + org.apache.arrow.adbc + adbc-sql + + + + + org.apache.arrow + flight-sql-jdbc-core + + + + + org.checkerframework + checker-qual + + + + + org.assertj + assertj-core + test + + + org.junit.jupiter + junit-jupiter + test + + + org.junit.vintage + junit-vintage-engine + test + + + org.apache.arrow + flight-sql-jdbc-core + ${dep.arrow.version} + tests + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/../../../testing/data + + + + + + diff --git a/java/driver/jni/src/main/cpp/jni_wrapper.cc b/java/driver/jni/src/main/cpp/jni_wrapper.cc new file mode 100644 index 0000000000..70b2bf22c3 --- /dev/null +++ b/java/driver/jni/src/main/cpp/jni_wrapper.cc @@ -0,0 +1,130 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "org_apache_arrow_adbc_driver_jni_impl_NativeAdbc.h" + +#include +#include +#include + +#include +#include +#include + +// We will use exceptions for error handling as that's easier with the JNI +// model. + +namespace { + +struct JniStringView { + JNIEnv* env; + jstring jni_string; + const char* value; + + explicit JniStringView(JNIEnv* env, jstring jni_string) + : env(env), jni_string(jni_string), value(nullptr) { + if (jni_string == nullptr) { + // TODO: + } + value = env->GetStringUTFChars(jni_string, nullptr); + if (value == nullptr) { + // TODO: + } + } + + ~JniStringView() { + if (jni_string == nullptr) { + return; + } + + env->ReleaseStringUTFChars(jni_string, value); + jni_string = nullptr; + } +}; + +std::string GetJniString(JNIEnv* env, jstring jni_string) { + JniStringView view(env, jni_string); + return std::string(view.value); +} + +std::optional MaybeGetJniString(JNIEnv* env, jstring jni_string) { + if (jni_string == nullptr) { + return std::nullopt; + } + JniStringView view(env, jni_string); + return std::string(view.value); +} + +struct AdbcException { + AdbcStatusCode code; + std::string message; + + void ThrowJavaException(JNIEnv* env) const { + jclass exception_klass = + env->FindClass("org/apache/arrow/adbc/driver/jni/impl/NativeAdbcException"); + + env->ThrowNew(exception_klass, message.c_str()); + } +}; + +void RaiseAdbcException(AdbcStatusCode code, const AdbcError& error) { + assert(code != ADBC_STATUS_OK); + throw AdbcException{ + .code = code, + .message = std::string(error.message), + }; +} + +#define CHECK_ADBC_ERROR(expr, error) \ + do { \ + AdbcStatusCode status = (expr); \ + if (status != ADBC_STATUS_OK) { \ + RaiseAdbcException(status, error); \ + } \ + } while (0) + +} // namespace + +extern "C" { + +JNIEXPORT jobject JNICALL +Java_org_apache_arrow_adbc_driver_jni_impl_NativeAdbc_loadDriver( + JNIEnv* env, [[maybe_unused]] jclass self, jstring driver_name_jni, + jstring entrypoint_jni, jint version) { + try { + std::string driver_name = GetJniString(env, driver_name_jni); + std::optional entrypoint = MaybeGetJniString(env, entrypoint_jni); + + struct AdbcDriver* driver = new struct AdbcDriver; + struct AdbcError error = ADBC_ERROR_INIT; + CHECK_ADBC_ERROR( + AdbcLoadDriver(driver_name.c_str(), entrypoint ? entrypoint->c_str() : nullptr, + version, driver, &error), + error); + + // TODO: error handling + jclass nativeDriverKlass = + env->FindClass("org/apache/arrow/adbc/driver/jni/impl/NativeDriver"); + jmethodID nativeDriverCtor = env->GetMethodID(nativeDriverKlass, "", "(J)V"); + return env->NewObject(nativeDriverKlass, nativeDriverCtor, + reinterpret_cast(driver)); + } catch (const AdbcException& e) { + e.ThrowJavaException(env); + return nullptr; + } +} +} diff --git a/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/JniDriver.java b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/JniDriver.java new file mode 100644 index 0000000000..de9d3f9ed0 --- /dev/null +++ b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/JniDriver.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.arrow.adbc.driver.jni; + +import java.net.URISyntaxException; +import java.util.Map; +import java.util.Objects; +import org.apache.arrow.adbc.core.AdbcDatabase; +import org.apache.arrow.adbc.core.AdbcDriver; +import org.apache.arrow.adbc.core.AdbcException; +import org.apache.arrow.adbc.core.TypedKey; +import org.apache.arrow.adbc.driver.jni.impl.JniLoader; +import org.apache.arrow.adbc.driver.jni.impl.NativeDriver; +import org.apache.arrow.adbc.sql.SqlQuirks; +import org.apache.arrow.flight.Location; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.util.Preconditions; + +/** An ADBC driver wrapping Arrow Flight SQL. */ +public class JniDriver implements AdbcDriver { + public static final TypedKey PARAM_DRIVER = new TypedKey<>("driver", String.class); + + private final BufferAllocator allocator; + + public JniDriver(BufferAllocator allocator) { + this.allocator = Objects.requireNonNull(allocator); + } + + @Override + public AdbcDatabase open(Map parameters) throws AdbcException { + String driver = PARAM_DRIVER.get(parameters); + if (driver == null) { + throw AdbcException.invalidArgument( + "[Flight SQL] Must provide String " + PARAM_DRIVER + " parameter"); + } + + NativeDriver d = JniLoader.INSTANCE.loadDriver(driver); + throw new UnsupportedOperationException(); + } +} diff --git a/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/JniDriverFactory.java b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/JniDriverFactory.java new file mode 100644 index 0000000000..b67a534fd5 --- /dev/null +++ b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/JniDriverFactory.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.adbc.driver.jni; + +import org.apache.arrow.adbc.core.AdbcDriver; +import org.apache.arrow.adbc.drivermanager.AdbcDriverFactory; +import org.apache.arrow.memory.BufferAllocator; + +/** Constructs new JniDriver instances. */ +public class JniDriverFactory implements AdbcDriverFactory { + @Override + public AdbcDriver getDriver(BufferAllocator allocator) { + return new JniDriver(allocator); + } +} diff --git a/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/JniLoader.java b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/JniLoader.java new file mode 100644 index 0000000000..be94bc40db --- /dev/null +++ b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/JniLoader.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.adbc.driver.jni.impl; + +public enum JniLoader { + INSTANCE; + + JniLoader() { + // TODO: implement logic to unpack the library from resources as well + Runtime.getRuntime() + .load("/home/lidavidm/Code/arrow-adbc/java/build/driver/jni/libadbc_drvier_jni.so"); + } + + public NativeDriver loadDriver(String driver) { + try { + return NativeAdbc.loadDriver(driver, null, 1001000); + } catch (NativeAdbcException e) { + throw new RuntimeException(e); + } + } +} diff --git a/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbc.java b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbc.java new file mode 100644 index 0000000000..d2156d14c9 --- /dev/null +++ b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbc.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.adbc.driver.jni.impl; + +public class NativeAdbc { + public static native NativeDriver loadDriver(String driverName, String entrypoint, int version) + throws NativeAdbcException; +} diff --git a/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbcException.java b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbcException.java new file mode 100644 index 0000000000..ef205770d3 --- /dev/null +++ b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeAdbcException.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.adbc.driver.jni.impl; + +/** + * Wrapper for a {@code struct AdbcException} that doesn't depend on other Java code. + * + *

This breaks a dependency chain in compilation. If we directly used AdbcException, then we + * would need to compile the Java code before compiling JNI code, but we need the compiled JNI code + * to compile the Java code. + */ +public class NativeAdbcException extends Exception { + public NativeAdbcException(String message) { + super(message); + } +} diff --git a/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeDriver.java b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeDriver.java new file mode 100644 index 0000000000..237716cfa8 --- /dev/null +++ b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/impl/NativeDriver.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.adbc.driver.jni.impl; + +import java.lang.ref.Cleaner; + +public class NativeDriver implements AutoCloseable { + static final Cleaner cleaner = Cleaner.create(); + + private final State state; + private final Cleaner.Cleanable cleanable; + + NativeDriver(long nativeHandle) { + this.state = new State(nativeHandle); + this.cleanable = cleaner.register(this, state); + } + + @Override + public void close() { + cleanable.clean(); + } + + private static class State implements Runnable { + long nativeHandle; + + State(long nativeHandle) { + this.nativeHandle = nativeHandle; + } + + @Override + public void run() { + if (nativeHandle == 0) return; + // TODO: dispose + nativeHandle = 0; + } + } +} diff --git a/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/package-info.java b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/package-info.java new file mode 100644 index 0000000000..ed2ba096a8 --- /dev/null +++ b/java/driver/jni/src/main/java/org/apache/arrow/adbc/driver/jni/package-info.java @@ -0,0 +1,18 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.adbc.driver.jni; diff --git a/java/driver/jni/src/main/resources/META-INF/services/org.apache.arrow.adbc.drivermanager.AdbcDriverFactory b/java/driver/jni/src/main/resources/META-INF/services/org.apache.arrow.adbc.drivermanager.AdbcDriverFactory new file mode 100644 index 0000000000..c592768f18 --- /dev/null +++ b/java/driver/jni/src/main/resources/META-INF/services/org.apache.arrow.adbc.drivermanager.AdbcDriverFactory @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +org.apache.arrow.adbc.driver.jni.NativeDriverFactory diff --git a/java/driver/jni/src/test/java/org/apache/arrow/adbc/driver/jni/JniDriverTest.java b/java/driver/jni/src/test/java/org/apache/arrow/adbc/driver/jni/JniDriverTest.java new file mode 100644 index 0000000000..6b0c2ed486 --- /dev/null +++ b/java/driver/jni/src/test/java/org/apache/arrow/adbc/driver/jni/JniDriverTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.adbc.driver.jni; + +import java.util.HashMap; +import java.util.Map; +import org.apache.arrow.adbc.core.AdbcDatabase; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.junit.jupiter.api.Test; + +class JniDriverTest { + @Test + void minimal() throws Exception { + try (final BufferAllocator allocator = new RootAllocator()) { + JniDriver driver = new JniDriver(allocator); + Map parameters = new HashMap<>(); + JniDriver.PARAM_DRIVER.set(parameters, "adbc_driver_sqlite"); + + try (final AdbcDatabase db = driver.open(parameters)) {} + } + } +} diff --git a/java/pom.xml b/java/pom.xml index 6b80751167..f4a26e8793 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -66,6 +66,7 @@ driver/jdbc-validation-derby driver/jdbc-validation-mssqlserver driver/jdbc-validation-postgresql + driver/jni driver/validation driver-manager sql