]> git.proxmox.com Git - ceph.git/blob - ceph/src/arrow/java/c/src/main/java/org/apache/arrow/c/jni/JniLoader.java
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / java / c / src / main / java / org / apache / arrow / c / jni / JniLoader.java
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.arrow.c.jni;
19
20 import java.io.File;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.file.Files;
25 import java.nio.file.StandardCopyOption;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Set;
31
32 /**
33 * The JniLoader for C Data Interface API's native implementation.
34 */
35 public class JniLoader {
36 private static final JniLoader INSTANCE = new JniLoader(Collections.singletonList("arrow_cdata_jni"));
37
38 public static JniLoader get() {
39 return INSTANCE;
40 }
41
42 private final Set<String> librariesToLoad;
43
44 private JniLoader(List<String> libraryNames) {
45 librariesToLoad = new HashSet<>(libraryNames);
46 }
47
48 private boolean finished() {
49 return librariesToLoad.isEmpty();
50 }
51
52 /**
53 * If required JNI libraries are not loaded, then load them.
54 */
55 public void ensureLoaded() {
56 if (finished()) {
57 return;
58 }
59 loadRemaining();
60 }
61
62 private synchronized void loadRemaining() {
63 // The method is protected by a mutex via synchronized, if more than one thread
64 // race to call
65 // loadRemaining, at same time only one will do the actual loading and the
66 // others will wait for
67 // the mutex to be acquired then check on the remaining list: if there are
68 // libraries that were not
69 // successfully loaded then the mutex owner will try to load them again.
70 if (finished()) {
71 return;
72 }
73 List<String> libs = new ArrayList<>(librariesToLoad);
74 for (String lib : libs) {
75 load(lib);
76 librariesToLoad.remove(lib);
77 }
78 }
79
80 private void load(String name) {
81 final String libraryToLoad = System.mapLibraryName(name);
82 try {
83 File temp = File.createTempFile("jnilib-", ".tmp", new File(System.getProperty("java.io.tmpdir")));
84 try (final InputStream is = JniWrapper.class.getClassLoader().getResourceAsStream(libraryToLoad)) {
85 if (is == null) {
86 throw new FileNotFoundException(libraryToLoad);
87 }
88 Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
89 System.load(temp.getAbsolutePath());
90 }
91 } catch (IOException e) {
92 throw new IllegalStateException("error loading native libraries: " + e);
93 }
94 }
95 }