Coverage Report

Created: 2026-10-09 12:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/util/jni-util.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with 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,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <butil/macros.h>
21
#include <jni.h>
22
#include <limits.h>
23
#include <stddef.h>
24
#include <stdint.h>
25
26
#include <atomic>
27
#include <cstdlib>
28
#include <optional>
29
#include <string>
30
31
#include "common/status.h"
32
#include "jni_md.h"
33
#include "util/defer_op.h"
34
#include "util/thrift_util.h"
35
36
// defined in hadoop/hadoop-hdfs-project/hadoop-hdfs/src/main/native/libhdfs/jni_helper.c
37
extern "C" JNIEnv* getJNIEnv(void);
38
39
namespace doris {
40
41
#define RETURN_ERROR_IF_EXC(env)                      \
42
263k
    do {                                              \
43
263k
        if (env->ExceptionCheck()) [[unlikely]]       \
44
4
            return Jni::Env::GetJniExceptionMsg(env); \
45
263k
    } while (false)
46
47
//In order to reduce the potential risks caused by not handling exceptions,
48
// you need to refer to  https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html
49
// to confirm whether the jni method will throw an exception.
50
51
namespace Jni {
52
class JvmLauncher;
53
54
class Env {
55
public:
56
221k
    static Status Get(JNIEnv** env) {
57
221k
        if (tls_env_) {
58
221k
            *env = tls_env_;
59
221k
        } else {
60
166
            Status status = GetJNIEnvSlowPath(env);
61
166
            if (!status.ok()) {
62
0
                return status;
63
0
            }
64
166
        }
65
221k
        if (*env == nullptr) [[unlikely]] {
66
0
            return Status::JniError("Failed to get JNIEnv: it is nullptr.");
67
0
        }
68
221k
        return Status::OK();
69
221k
    }
70
71
3
    static Status Init() { return init_throw_exception(); }
72
73
    static Status GetJniExceptionMsg(JNIEnv* env, bool log_stack = true,
74
                                     const std::string& prefix = "") WARN_UNUSED_RESULT;
75
76
private:
77
    static Status GetJNIEnvSlowPath(JNIEnv** env);
78
    // What the JVM of this process was created from, for the one error message that has to
79
    // report a deployment problem rather than a programming one. Says so explicitly when the
80
    // variable is unset, which is what a BE not started by bin/start_be.sh looks like.
81
0
    static std::string class_path_of_this_process() {
82
0
        const char* class_path = getenv("CLASSPATH");
83
0
        return class_path == nullptr ? std::string("<CLASSPATH unset>") : std::string(class_path);
84
0
    }
85
3
    static Status init_throw_exception() {
86
3
        JNIEnv* env = nullptr;
87
3
        RETURN_IF_ERROR(Jni::Env::Get(&env));
88
89
        // Find JniUtil class and create a global ref.
90
3
        jclass local_jni_util_cl = env->FindClass("org/apache/doris/jni/spi/utils/JniUtil");
91
3
        if (local_jni_util_cl == nullptr) {
92
0
            if (env->ExceptionOccurred()) {
93
0
                env->ExceptionDescribe();
94
0
            }
95
            // Named rather than left as a bare FindClass failure: this is the first class BE
96
            // resolves out of the shared layer, so a deployment whose lib/jni/spi is missing or
97
            // was not put on the class path fails exactly here, and the answer is a directory
98
            // name and a jar name. The failure is then cached for the life of the process, so
99
            // this is also the only chance to say it.
100
0
            return Status::JniError(
101
0
                    "Failed to find the JniUtil class of the Java plugin SPI. It ships in "
102
0
                    "doris-jni-spi.jar under DORIS_HOME/lib/jni/spi, which bin/start_be.sh puts "
103
0
                    "on the class path; check that the directory exists and holds "
104
0
                    "doris-jni-spi.jar and doris-jni-bootstrap.jar. Class path: {}",
105
0
                    class_path_of_this_process());
106
0
        }
107
3
        jni_util_cl_ = reinterpret_cast<jclass>(env->NewGlobalRef(local_jni_util_cl));
108
3
        env->DeleteLocalRef(local_jni_util_cl);
109
3
        if (jni_util_cl_ == nullptr) {
110
0
            if (env->ExceptionOccurred()) {
111
0
                env->ExceptionDescribe();
112
0
            }
113
0
            return Status::JniError("Failed to create global reference to JniUtil class.");
114
0
        }
115
3
        if (env->ExceptionOccurred()) {
116
0
            return Status::JniError("Failed to delete local reference to JniUtil class.");
117
0
        }
118
119
        // Throwable toString()
120
3
        throwable_to_string_id_ = env->GetStaticMethodID(
121
3
                jni_util_cl_, "throwableToString", "(Ljava/lang/Throwable;)Ljava/lang/String;");
122
3
        if (throwable_to_string_id_ == nullptr) {
123
0
            if (env->ExceptionOccurred()) {
124
0
                env->ExceptionDescribe();
125
0
            }
126
0
            return Status::JniError("Failed to find JniUtil.throwableToString method.");
127
0
        }
128
129
        // throwableToStackTrace()
130
3
        throwable_to_stack_trace_id_ = env->GetStaticMethodID(
131
3
                jni_util_cl_, "throwableToStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;");
132
3
        if (throwable_to_stack_trace_id_ == nullptr) {
133
0
            if (env->ExceptionOccurred()) {
134
0
                env->ExceptionDescribe();
135
0
            }
136
0
            return Status::JniError("Failed to find JniUtil.throwableToFullStackTrace method.");
137
0
        }
138
3
        return Status::OK();
139
3
    }
140
141
    // Drops the cached JNIEnv of the calling thread. Only the thread exit hook and the JVM
142
    // bootstrap may call this: the env it caches is gone the moment the thread is detached,
143
    // and anything reading it afterwards - another thread exit hook, say - would read freed
144
    // memory.
145
51
    static void reset_tls_env() { tls_env_ = nullptr; }
146
    // Caches an env the bootstrap attached by itself, so that resolving the JNI base right
147
    // after the JVM comes up stays on Get()'s fast path instead of re-entering ensure_jvm().
148
669
    static void set_tls_env(JNIEnv* env) { tls_env_ = env; }
149
    // What Get() would hand out on this thread without asking anyone, nullptr when nothing is
150
    // cached. For JvmLauncher::ScopedVmEnv, which primes the cache for one scope and has to put
151
    // back what it found rather than assume there was nothing: on the bootstrap thread there is.
152
333
    static JNIEnv* tls_env() { return tls_env_; }
153
    friend class JvmLauncher;
154
155
private:
156
    // Thread-local cache of the JNIEnv for this thread.
157
    static __thread JNIEnv* tls_env_;
158
159
    //for exception
160
    static jclass jni_util_cl_;
161
    static jmethodID throwable_to_string_id_;
162
    static jmethodID throwable_to_stack_trace_id_;
163
};
164
165
enum RefType { Local, Global };
166
167
enum BufferType { Chars, ByteArray };
168
169
template <RefType Ref>
170
struct RefHelper {};
171
172
template <>
173
struct RefHelper<Local> {
174
3.30k
    static jobject create(JNIEnv* env, jobject obj) { return env->NewLocalRef(obj); }
175
176
191k
    static void destroy(JNIEnv* env, jobject obj) { env->DeleteLocalRef(obj); }
177
178
194k
    static Status get_env(JNIEnv** env) {
179
        // Get the JNIEnv* corresponding to current thread.
180
194k
        return Jni::Env::Get(env);
181
194k
    }
182
};
183
184
template <>
185
struct RefHelper<Global> {
186
10.8k
    static jobject create(JNIEnv* env, jobject obj) { return env->NewGlobalRef(obj); }
187
188
10.8k
    static void destroy(JNIEnv* env, jobject obj) { env->DeleteGlobalRef(obj); }
189
190
10.8k
    static Status get_env(JNIEnv** env) { return Jni::Env::Get(env); }
191
};
192
193
template <RefType Ref>
194
class Object;
195
196
template <RefType Ref>
197
class Class;
198
199
class MethodId {
200
public:
201
14.2k
    MethodId() = default;
202
136k
    bool uninitialized() const { return _id == nullptr; }
203
204
    template <RefType U>
205
    friend class Object;
206
207
    template <RefType U>
208
    friend class Class;
209
210
private:
211
    jmethodID _id = nullptr;
212
};
213
214
class FieldId {
215
public:
216
18
    FieldId() = default;
217
36
    bool uninitialized() const { return _id == nullptr; }
218
219
    template <RefType U>
220
    friend class Object;
221
222
    template <RefType U>
223
    friend class Class;
224
225
private:
226
    jfieldID _id = nullptr;
227
};
228
229
enum CallTag {
230
    ObjectMethod,
231
    IntMethod,
232
    LongMethod,
233
    VoidMethod,
234
    BooleanMethod,
235
236
    StaticObjectMethod,
237
    StaticIntMethod,
238
    StaticLongMethod,
239
    StaticVoidMethod,
240
241
    NewObject,
242
243
    NonvirtualVoidMethod,
244
    NonvirtualObjectMethod,
245
    NonvirtualIntMethod,
246
    NonvirtualBooleanMethod,
247
};
248
249
template <CallTag Tag>
250
struct CallHelper {};
251
252
template <>
253
struct CallHelper<ObjectMethod> {
254
83.2k
    static jobject call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
255
83.2k
        return env->CallObjectMethodA(obj, methodID, args);
256
83.2k
    }
257
    using BASE_TYPE = jobject;
258
    using RETURN_TYPE = jobject;
259
};
260
261
template <>
262
struct CallHelper<IntMethod> {
263
990
    static jint call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
264
990
        return env->CallIntMethodA(obj, methodID, args);
265
990
    }
266
    using BASE_TYPE = jobject;
267
    using RETURN_TYPE = jint;
268
};
269
270
template <>
271
struct CallHelper<LongMethod> {
272
13.6k
    static jlong call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
273
13.6k
        return env->CallLongMethodA(obj, methodID, args);
274
13.6k
    }
275
    using BASE_TYPE = jobject;
276
    using RETURN_TYPE = jlong;
277
};
278
279
template <>
280
struct CallHelper<VoidMethod> {
281
271
    static void call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
282
271
        env->CallVoidMethodA(obj, methodID, args);
283
271
    }
284
    using BASE_TYPE = jobject;
285
    using RETURN_TYPE = void;
286
};
287
288
template <>
289
struct CallHelper<BooleanMethod> {
290
6
    static jboolean call_impl(JNIEnv* env, jobject obj, jmethodID methodID, const jvalue* args) {
291
6
        return env->CallBooleanMethodA(obj, methodID, args);
292
6
    }
293
    using BASE_TYPE = jobject;
294
    using RETURN_TYPE = jboolean;
295
};
296
297
template <>
298
struct CallHelper<StaticObjectMethod> {
299
6.68k
    static jobject call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
300
6.68k
        return env->CallStaticObjectMethodA(cls, methodID, args);
301
6.68k
    }
302
    using BASE_TYPE = jclass;
303
    using RETURN_TYPE = jobject;
304
};
305
306
template <>
307
struct CallHelper<StaticIntMethod> {
308
0
    static jint call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
309
0
        return env->CallStaticIntMethodA(cls, methodID, args);
310
0
    }
311
    using BASE_TYPE = jclass;
312
    using RETURN_TYPE = jint;
313
};
314
315
template <>
316
struct CallHelper<StaticLongMethod> {
317
0
    static jlong call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
318
0
        return env->CallStaticLongMethodA(cls, methodID, args);
319
0
    }
320
    using BASE_TYPE = jclass;
321
    using RETURN_TYPE = jlong;
322
};
323
324
template <>
325
struct CallHelper<StaticVoidMethod> {
326
928
    static void call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
327
928
        return env->CallStaticVoidMethodA(cls, methodID, args);
328
928
    }
329
330
    using BASE_TYPE = jclass;
331
    using RETURN_TYPE = void;
332
};
333
334
template <>
335
struct CallHelper<NewObject> {
336
5.59k
    static jobject call_impl(JNIEnv* env, jclass cls, jmethodID methodID, const jvalue* args) {
337
5.59k
        return env->NewObjectA(cls, methodID, args);
338
5.59k
    }
339
340
    using BASE_TYPE = jclass;
341
    using RETURN_TYPE = jobject;
342
};
343
344
template <>
345
struct CallHelper<NonvirtualVoidMethod> {
346
    static void call_impl(JNIEnv* env, jobject obj, jclass clazz, jmethodID methodID,
347
6.02k
                          const jvalue* args) {
348
6.02k
        return env->CallNonvirtualVoidMethodA(obj, clazz, methodID, args);
349
6.02k
    }
350
351
    using BASE_TYPE = jobject;
352
    using RETURN_TYPE = void;
353
};
354
355
template <>
356
struct CallHelper<NonvirtualObjectMethod> {
357
    static jobject call_impl(JNIEnv* env, jobject obj, jclass clazz, jmethodID methodID,
358
100
                             const jvalue* args) {
359
100
        return env->CallNonvirtualObjectMethodA(obj, clazz, methodID, args);
360
100
    }
361
362
    using BASE_TYPE = jobject;
363
    using RETURN_TYPE = jobject;
364
};
365
366
template <>
367
struct CallHelper<NonvirtualIntMethod> {
368
    static jint call_impl(JNIEnv* env, jobject obj, jclass clazz, jmethodID methodID,
369
0
                          const jvalue* args) {
370
0
        return env->CallNonvirtualIntMethodA(obj, clazz, methodID, args);
371
0
    }
372
373
    using BASE_TYPE = jobject;
374
    using RETURN_TYPE = jint;
375
};
376
377
template <>
378
struct CallHelper<NonvirtualBooleanMethod> {
379
    static jboolean call_impl(JNIEnv* env, jobject obj, jclass clazz, jmethodID methodID,
380
0
                              const jvalue* args) {
381
0
        return env->CallNonvirtualBooleanMethodA(obj, clazz, methodID, args);
382
0
    }
383
384
    using BASE_TYPE = jobject;
385
    using RETURN_TYPE = jboolean;
386
};
387
388
template <CallTag tag>
389
class FunctionCall {
390
public:
391
    FunctionCall(FunctionCall&& other) noexcept = default;
392
393
    static FunctionCall instance(JNIEnv* env, typename CallHelper<tag>::BASE_TYPE base,
394
111k
                                 jmethodID method_id) {
395
111k
        return FunctionCall(env, base, method_id);
396
111k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE5EE8instanceEP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
394
6.69k
                                 jmethodID method_id) {
395
6.69k
        return FunctionCall(env, base, method_id);
396
6.69k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
394
83.2k
                                 jmethodID method_id) {
395
83.2k
        return FunctionCall(env, base, method_id);
396
83.2k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
394
13.6k
                                 jmethodID method_id) {
395
13.6k
        return FunctionCall(env, base, method_id);
396
13.6k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE1EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
394
990
                                 jmethodID method_id) {
395
990
        return FunctionCall(env, base, method_id);
396
990
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
394
273
                                 jmethodID method_id) {
395
273
        return FunctionCall(env, base, method_id);
396
273
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EE8instanceEP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
394
5.59k
                                 jmethodID method_id) {
395
5.59k
        return FunctionCall(env, base, method_id);
396
5.59k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE4EE8instanceEP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
394
6
                                 jmethodID method_id) {
395
6
        return FunctionCall(env, base, method_id);
396
6
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EE8instanceEP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
394
928
                                 jmethodID method_id) {
395
928
        return FunctionCall(env, base, method_id);
396
928
    }
397
398
    /// Pass a primitive arg (eg an integer).
399
    /// Multiple arguments may be passed by repeated calls.
400
    template <class T>
401
        requires std::disjunction_v<std::is_same<T, jboolean>, std::is_same<T, jbyte>,
402
                                    std::is_same<T, jchar>, std::is_same<T, jshort>,
403
                                    std::is_same<T, jint>, std::is_same<T, jlong>,
404
                                    std::is_same<T, jfloat>, std::is_same<T, jdouble>>
405
11.6k
    FunctionCall& with_arg(T arg) {
406
11.6k
        jvalue v;
407
11.6k
        std::memset(&v, 0, sizeof(v));
408
11.6k
        if constexpr (std::is_same_v<T, jboolean>) {
409
250
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
9.98k
        } else if constexpr (std::is_same_v<T, jint>) {
417
9.98k
            v.i = arg;
418
9.98k
        } else if constexpr (std::is_same_v<T, jlong>) {
419
1.38k
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
11.6k
        _args.push_back(v);
428
11.6k
        return *this;
429
11.6k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE8with_argIiQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
405
3.63k
    FunctionCall& with_arg(T arg) {
406
3.63k
        jvalue v;
407
3.63k
        std::memset(&v, 0, sizeof(v));
408
        if constexpr (std::is_same_v<T, jboolean>) {
409
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
3.63k
        } else if constexpr (std::is_same_v<T, jint>) {
417
3.63k
            v.i = arg;
418
        } else if constexpr (std::is_same_v<T, jlong>) {
419
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
3.63k
        _args.push_back(v);
428
3.63k
        return *this;
429
3.63k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EE8with_argIiQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
405
5.59k
    FunctionCall& with_arg(T arg) {
406
5.59k
        jvalue v;
407
5.59k
        std::memset(&v, 0, sizeof(v));
408
        if constexpr (std::is_same_v<T, jboolean>) {
409
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
5.59k
        } else if constexpr (std::is_same_v<T, jint>) {
417
5.59k
            v.i = arg;
418
        } else if constexpr (std::is_same_v<T, jlong>) {
419
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
5.59k
        _args.push_back(v);
428
5.59k
        return *this;
429
5.59k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8with_argIhQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
405
250
    FunctionCall& with_arg(T arg) {
406
250
        jvalue v;
407
250
        std::memset(&v, 0, sizeof(v));
408
250
        if constexpr (std::is_same_v<T, jboolean>) {
409
250
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
        } else if constexpr (std::is_same_v<T, jint>) {
417
            v.i = arg;
418
        } else if constexpr (std::is_same_v<T, jlong>) {
419
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
250
        _args.push_back(v);
428
250
        return *this;
429
250
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8with_argIiQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
405
755
    FunctionCall& with_arg(T arg) {
406
755
        jvalue v;
407
755
        std::memset(&v, 0, sizeof(v));
408
        if constexpr (std::is_same_v<T, jboolean>) {
409
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
755
        } else if constexpr (std::is_same_v<T, jint>) {
417
755
            v.i = arg;
418
        } else if constexpr (std::is_same_v<T, jlong>) {
419
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
755
        _args.push_back(v);
428
755
        return *this;
429
755
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
405
250
    FunctionCall& with_arg(T arg) {
406
250
        jvalue v;
407
250
        std::memset(&v, 0, sizeof(v));
408
        if constexpr (std::is_same_v<T, jboolean>) {
409
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
        } else if constexpr (std::is_same_v<T, jint>) {
417
            v.i = arg;
418
250
        } else if constexpr (std::is_same_v<T, jlong>) {
419
250
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
250
        _args.push_back(v);
428
250
        return *this;
429
250
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
405
205
    FunctionCall& with_arg(T arg) {
406
205
        jvalue v;
407
205
        std::memset(&v, 0, sizeof(v));
408
        if constexpr (std::is_same_v<T, jboolean>) {
409
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
        } else if constexpr (std::is_same_v<T, jint>) {
417
            v.i = arg;
418
205
        } else if constexpr (std::is_same_v<T, jlong>) {
419
205
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
205
        _args.push_back(v);
428
205
        return *this;
429
205
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE5EE8with_argIiQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
405
5
    FunctionCall& with_arg(T arg) {
406
5
        jvalue v;
407
5
        std::memset(&v, 0, sizeof(v));
408
        if constexpr (std::is_same_v<T, jboolean>) {
409
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
5
        } else if constexpr (std::is_same_v<T, jint>) {
417
5
            v.i = arg;
418
        } else if constexpr (std::is_same_v<T, jlong>) {
419
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
5
        _args.push_back(v);
428
5
        return *this;
429
5
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
405
928
    FunctionCall& with_arg(T arg) {
406
928
        jvalue v;
407
928
        std::memset(&v, 0, sizeof(v));
408
        if constexpr (std::is_same_v<T, jboolean>) {
409
            v.z = arg;
410
        } else if constexpr (std::is_same_v<T, jbyte>) {
411
            v.b = arg;
412
        } else if constexpr (std::is_same_v<T, jchar>) {
413
            v.c = arg;
414
        } else if constexpr (std::is_same_v<T, jshort>) {
415
            v.s = arg;
416
        } else if constexpr (std::is_same_v<T, jint>) {
417
            v.i = arg;
418
928
        } else if constexpr (std::is_same_v<T, jlong>) {
419
928
            v.j = arg;
420
        } else if constexpr (std::is_same_v<T, jfloat>) {
421
            v.f = arg;
422
        } else if constexpr (std::is_same_v<T, jdouble>) {
423
            v.d = arg;
424
        } else {
425
            static_assert(false);
426
        }
427
928
        _args.push_back(v);
428
928
        return *this;
429
928
    }
430
431
    template <RefType Ref>
432
    FunctionCall& with_arg(const Object<Ref>& obj) WARN_UNUSED_RESULT;
433
434
    template <typename ReturnType>
435
        requires(std::is_same_v<typename CallHelper<tag>::RETURN_TYPE, ReturnType>)
436
14.6k
    Status call(ReturnType* result) {
437
14.6k
        *result = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
438
14.6k
        RETURN_ERROR_IF_EXC(_env);
439
14.6k
        return Status::OK();
440
14.6k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EE4callIlQsr3stdE9is_same_vINS0_10CallHelperIXT_EE11RETURN_TYPEETL0__EEENS_6StatusEPT_
Line
Count
Source
436
13.6k
    Status call(ReturnType* result) {
437
13.6k
        *result = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
438
13.6k
        RETURN_ERROR_IF_EXC(_env);
439
13.6k
        return Status::OK();
440
13.6k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE1EE4callIiQsr3stdE9is_same_vINS0_10CallHelperIXT_EE11RETURN_TYPEETL0__EEENS_6StatusEPT_
Line
Count
Source
436
990
    Status call(ReturnType* result) {
437
990
        *result = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
438
990
        RETURN_ERROR_IF_EXC(_env);
439
990
        return Status::OK();
440
990
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE4EE4callIhQsr3stdE9is_same_vINS0_10CallHelperIXT_EE11RETURN_TYPEETL0__EEENS_6StatusEPT_
Line
Count
Source
436
6
    Status call(ReturnType* result) {
437
6
        *result = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
438
6
        RETURN_ERROR_IF_EXC(_env);
439
6
        return Status::OK();
440
6
    }
441
442
    Status call(Object<Local>* result);
443
444
    Status call(Object<Global>* result);
445
446
18.0k
    Status call() {
447
18.0k
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
448
        if constexpr (std::disjunction_v<
449
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
450
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
451
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
452
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
453
1.19k
                              std::is_same<return_type, void>>) {
454
1.19k
            CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
455
1.19k
            RETURN_ERROR_IF_EXC(_env);
456
16.8k
        } else if constexpr (std::is_same_v<return_type, jobject>) {
457
16.8k
            jobject tmp = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
458
16.8k
            _env->DeleteLocalRef(tmp);
459
16.8k
            RETURN_ERROR_IF_EXC(_env);
460
        } else {
461
            static_assert(false);
462
        }
463
18.0k
        return Status::OK();
464
18.0k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE4callEv
Line
Count
Source
446
269
    Status call() {
447
269
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
448
        if constexpr (std::disjunction_v<
449
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
450
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
451
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
452
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
453
269
                              std::is_same<return_type, void>>) {
454
269
            CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
455
269
            RETURN_ERROR_IF_EXC(_env);
456
        } else if constexpr (std::is_same_v<return_type, jobject>) {
457
            jobject tmp = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
458
            _env->DeleteLocalRef(tmp);
459
            RETURN_ERROR_IF_EXC(_env);
460
        } else {
461
            static_assert(false);
462
        }
463
269
        return Status::OK();
464
269
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE4callEv
Line
Count
Source
446
16.8k
    Status call() {
447
16.8k
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
448
        if constexpr (std::disjunction_v<
449
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
450
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
451
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
452
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
453
                              std::is_same<return_type, void>>) {
454
            CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
455
            RETURN_ERROR_IF_EXC(_env);
456
16.8k
        } else if constexpr (std::is_same_v<return_type, jobject>) {
457
16.8k
            jobject tmp = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
458
16.8k
            _env->DeleteLocalRef(tmp);
459
16.8k
            RETURN_ERROR_IF_EXC(_env);
460
        } else {
461
            static_assert(false);
462
        }
463
16.8k
        return Status::OK();
464
16.8k
    }
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EE4callEv
Line
Count
Source
446
928
    Status call() {
447
928
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
448
        if constexpr (std::disjunction_v<
449
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
450
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
451
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
452
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
453
928
                              std::is_same<return_type, void>>) {
454
928
            CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
455
928
            RETURN_ERROR_IF_EXC(_env);
456
        } else if constexpr (std::is_same_v<return_type, jobject>) {
457
            jobject tmp = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
458
            _env->DeleteLocalRef(tmp);
459
            RETURN_ERROR_IF_EXC(_env);
460
        } else {
461
            static_assert(false);
462
        }
463
928
        return Status::OK();
464
928
    }
465
466
protected:
467
    explicit FunctionCall(JNIEnv* env, typename CallHelper<tag>::BASE_TYPE base,
468
                          jmethodID method_id)
469
117k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE5EEC2EP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
469
6.70k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
469
83.2k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
469
13.6k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE1EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
469
990
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
469
273
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EEC2EP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
469
5.59k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE10EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
469
6.03k
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE11EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
469
101
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE4EEC2EP7JNIEnv_P8_jobjectP10_jmethodID
Line
Count
Source
469
6
            : _env(env), _base(base), _method(method_id) {}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EEC2EP7JNIEnv_P7_jclassP10_jmethodID
Line
Count
Source
469
928
            : _env(env), _base(base), _method(method_id) {}
470
471
    JNIEnv* _env = nullptr;
472
    CallHelper<tag>::BASE_TYPE _base; // is jobject/jclass  not need new/delete local/global ref.
473
    const jmethodID _method = nullptr;
474
    std::vector<jvalue> _args;
475
    Status _st = Status::OK();
476
    DISALLOW_COPY_AND_ASSIGN(FunctionCall);
477
};
478
479
template <CallTag tag>
480
class NonvirtualFunctionCall : public FunctionCall<tag> {
481
public:
482
    NonvirtualFunctionCall(NonvirtualFunctionCall&& other) noexcept = default;
483
484
    static NonvirtualFunctionCall instance(JNIEnv* env, typename CallHelper<tag>::BASE_TYPE base,
485
6.13k
                                           jclass cls, jmethodID method_id) {
486
6.13k
        return NonvirtualFunctionCall(env, base, cls, method_id);
487
6.13k
    }
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE10EE8instanceEP7JNIEnv_P8_jobjectP7_jclassP10_jmethodID
Line
Count
Source
485
6.03k
                                           jclass cls, jmethodID method_id) {
486
6.03k
        return NonvirtualFunctionCall(env, base, cls, method_id);
487
6.03k
    }
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE11EE8instanceEP7JNIEnv_P8_jobjectP7_jclassP10_jmethodID
Line
Count
Source
485
101
                                           jclass cls, jmethodID method_id) {
486
101
        return NonvirtualFunctionCall(env, base, cls, method_id);
487
101
    }
488
489
    // no override
490
    template <class T>
491
        requires std::disjunction_v<std::is_same<T, jboolean>, std::is_same<T, jbyte>,
492
                                    std::is_same<T, jchar>, std::is_same<T, jshort>,
493
                                    std::is_same<T, jint>, std::is_same<T, jlong>,
494
                                    std::is_same<T, jfloat>, std::is_same<T, jdouble>>
495
237
    NonvirtualFunctionCall& with_arg(T arg) {
496
237
        jvalue v;
497
237
        std::memset(&v, 0, sizeof(v));
498
        if constexpr (std::is_same_v<T, jboolean>) {
499
            v.z = arg;
500
        } else if constexpr (std::is_same_v<T, jbyte>) {
501
            v.b = arg;
502
        } else if constexpr (std::is_same_v<T, jchar>) {
503
            v.c = arg;
504
        } else if constexpr (std::is_same_v<T, jshort>) {
505
            v.s = arg;
506
        } else if constexpr (std::is_same_v<T, jint>) {
507
            v.i = arg;
508
237
        } else if constexpr (std::is_same_v<T, jlong>) {
509
237
            v.j = arg;
510
        } else if constexpr (std::is_same_v<T, jfloat>) {
511
            v.f = arg;
512
        } else if constexpr (std::is_same_v<T, jdouble>) {
513
            v.d = arg;
514
        } else {
515
            static_assert(false);
516
        }
517
237
        this->_args.push_back(v);
518
237
        return *this;
519
237
    }
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE10EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
495
136
    NonvirtualFunctionCall& with_arg(T arg) {
496
136
        jvalue v;
497
136
        std::memset(&v, 0, sizeof(v));
498
        if constexpr (std::is_same_v<T, jboolean>) {
499
            v.z = arg;
500
        } else if constexpr (std::is_same_v<T, jbyte>) {
501
            v.b = arg;
502
        } else if constexpr (std::is_same_v<T, jchar>) {
503
            v.c = arg;
504
        } else if constexpr (std::is_same_v<T, jshort>) {
505
            v.s = arg;
506
        } else if constexpr (std::is_same_v<T, jint>) {
507
            v.i = arg;
508
136
        } else if constexpr (std::is_same_v<T, jlong>) {
509
136
            v.j = arg;
510
        } else if constexpr (std::is_same_v<T, jfloat>) {
511
            v.f = arg;
512
        } else if constexpr (std::is_same_v<T, jdouble>) {
513
            v.d = arg;
514
        } else {
515
            static_assert(false);
516
        }
517
136
        this->_args.push_back(v);
518
136
        return *this;
519
136
    }
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE11EE8with_argIlQsr3stdE13disjunction_vISt7is_sameITL0__hES5_IS6_aES5_IS6_tES5_IS6_sES5_IS6_iES5_IS6_lES5_IS6_fES5_IS6_dEEEERS3_T_
Line
Count
Source
495
101
    NonvirtualFunctionCall& with_arg(T arg) {
496
101
        jvalue v;
497
101
        std::memset(&v, 0, sizeof(v));
498
        if constexpr (std::is_same_v<T, jboolean>) {
499
            v.z = arg;
500
        } else if constexpr (std::is_same_v<T, jbyte>) {
501
            v.b = arg;
502
        } else if constexpr (std::is_same_v<T, jchar>) {
503
            v.c = arg;
504
        } else if constexpr (std::is_same_v<T, jshort>) {
505
            v.s = arg;
506
        } else if constexpr (std::is_same_v<T, jint>) {
507
            v.i = arg;
508
101
        } else if constexpr (std::is_same_v<T, jlong>) {
509
101
            v.j = arg;
510
        } else if constexpr (std::is_same_v<T, jfloat>) {
511
            v.f = arg;
512
        } else if constexpr (std::is_same_v<T, jdouble>) {
513
            v.d = arg;
514
        } else {
515
            static_assert(false);
516
        }
517
101
        this->_args.push_back(v);
518
101
        return *this;
519
101
    }
520
521
    template <RefType Ref>
522
    NonvirtualFunctionCall& with_arg(const Object<Ref>& obj) WARN_UNUSED_RESULT;
523
524
    // no override
525
6.02k
    Status call() {
526
6.02k
        using return_type = typename CallHelper<tag>::RETURN_TYPE;
527
        if constexpr (std::disjunction_v<
528
                              std::is_same<return_type, jboolean>, std::is_same<return_type, jbyte>,
529
                              std::is_same<return_type, jchar>, std::is_same<return_type, jshort>,
530
                              std::is_same<return_type, jint>, std::is_same<return_type, jlong>,
531
                              std::is_same<return_type, jfloat>, std::is_same<return_type, jdouble>,
532
6.02k
                              std::is_same<return_type, void>>) {
533
6.02k
            CallHelper<tag>::call_impl(this->_env, this->_base, _cls, this->_method,
534
6.02k
                                       this->_args.data());
535
6.02k
            RETURN_ERROR_IF_EXC(this->_env);
536
        } else if constexpr (std::is_same_v<return_type, jobject>) {
537
            jobject tmp = CallHelper<tag>::call_impl(this->_env, this->_base, _cls, this->_method,
538
                                                     this->_args.data());
539
            RETURN_ERROR_IF_EXC(this->_env);
540
            this->_env->DeleteLocalRef(tmp);
541
        } else {
542
            static_assert(false);
543
        }
544
6.02k
        return Status::OK();
545
6.02k
    }
546
547
    Status call(Object<Local>* result);
548
549
    template <typename ReturnType>
550
        requires(std::is_same_v<typename CallHelper<tag>::RETURN_TYPE, ReturnType>)
551
    Status call(ReturnType* result) {
552
        *result = CallHelper<tag>::call_impl(this->_env, this->_base, _cls, this->_method,
553
                                             this->_args.data());
554
        RETURN_ERROR_IF_EXC(this->_env);
555
        return Status::OK();
556
    }
557
558
private:
559
    explicit NonvirtualFunctionCall(JNIEnv* env, typename CallHelper<tag>::BASE_TYPE base,
560
                                    jclass cls, jmethodID method_id)
561
6.13k
            : FunctionCall<tag>(env, base, method_id), _cls(cls) {}
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE10EEC2EP7JNIEnv_P8_jobjectP7_jclassP10_jmethodID
Line
Count
Source
561
6.03k
            : FunctionCall<tag>(env, base, method_id), _cls(cls) {}
_ZN5doris3Jni22NonvirtualFunctionCallILNS0_7CallTagE11EEC2EP7JNIEnv_P8_jobjectP7_jclassP10_jmethodID
Line
Count
Source
561
101
            : FunctionCall<tag>(env, base, method_id), _cls(cls) {}
562
    jclass _cls;
563
    DISALLOW_COPY_AND_ASSIGN(NonvirtualFunctionCall);
564
};
565
566
/**
567
 * When writing JNI code, developers usually need to pay extra attention to several error-prone aspects, including:
568
 * 1. The reference type of jobject (local vs. global)
569
 * 2. The lifetime and scope of JNI references
570
 * 3. Proper release of references after use
571
 * 4. Explicit exception checking after JNI calls
572
 * Because these concerns are verbose and easy to overlook, they often lead to bugs or inconsistent code. To simplify this, 
573
 * we provide a wrapper framework around raw JNI APIs. The following describes how to use it (assuming the user already 
574
 * understands the basic JNI programming model).
575
 *
576
 * 0. Get JNIEnv* env: `Status st = Jni::Env::Get(&env)`
577
 * 1. Choose the reference type
578
 *   First, determine whether the JNI object should be a local or global reference. Based on this, create the corresponding C++ wrapper object:
579
 *   LocalObject / GlobalObject. If the exact JNI type is known, use specialized wrappers such as <Local/Global><Array/String/Class>. 
580
 * 2. Initialize the object
581
 *   For `jclass`, typically use: `Status st = Jni::Util::find_class(xxx);`
582
 *   For other object types, they are usually initialized via: `Status st = clazz.new_object(xxx).with_arg(xxx).call(&object) or by calling methods on existing objects.
583
 * 3. Call methods and retrieve results
584
 *   To invoke a method and obtain a return value, use: `Status st = object.call_<return_type>_method(xxx).call(&result);` 
585
 * 
586
 * Notes
587
 * 1. All JNI references are automatically released in the wrapper’s destructor, ensuring safe and deterministic cleanup.
588
 * 2. All framework method invocations return a Status.
589
 * The actual JNI return value is written to the address passed to call().
590
 * 
591
 * Example: be/test/util/jni_util_test.cpp
592
*/
593
template <RefType Ref>
594
class Object {
595
    // env->GetObjectRefType
596
public:
597
219k
    Object() = default;
_ZN5doris3Jni6ObjectILNS0_7RefTypeE1EEC2Ev
Line
Count
Source
597
11.1k
    Object() = default;
_ZN5doris3Jni6ObjectILNS0_7RefTypeE0EEC2Ev
Line
Count
Source
597
208k
    Object() = default;
598
599
    template <RefType U>
600
    friend class Object;
601
602
    template <RefType U>
603
    friend class Class;
604
605
    template <RefType U>
606
    friend class String;
607
608
    template <RefType U>
609
    friend class Array;
610
611
    template <BufferType bufferfType, RefType U>
612
    friend class BufferGuard;
613
614
    template <CallTag tag>
615
    friend class FunctionCall;
616
617
    template <CallTag tag>
618
    friend class NonvirtualFunctionCall;
619
620
219k
    virtual ~Object() {
621
219k
        if (_obj != nullptr) [[likely]] {
622
202k
            JNIEnv* env = nullptr;
623
202k
            if (Status st = RefHelper<Ref>::get_env(&env); !st.ok()) [[unlikely]] {
624
0
                LOG(WARNING) << "Can't destroy Jni Ref : " << st.msg();
625
0
                return;
626
0
            }
627
202k
            RefHelper<Ref>::destroy(env, _obj);
628
202k
        }
629
219k
    }
_ZN5doris3Jni6ObjectILNS0_7RefTypeE0EED2Ev
Line
Count
Source
620
208k
    virtual ~Object() {
621
208k
        if (_obj != nullptr) [[likely]] {
622
191k
            JNIEnv* env = nullptr;
623
191k
            if (Status st = RefHelper<Ref>::get_env(&env); !st.ok()) [[unlikely]] {
624
0
                LOG(WARNING) << "Can't destroy Jni Ref : " << st.msg();
625
0
                return;
626
0
            }
627
191k
            RefHelper<Ref>::destroy(env, _obj);
628
191k
        }
629
208k
    }
_ZN5doris3Jni6ObjectILNS0_7RefTypeE1EED2Ev
Line
Count
Source
620
11.1k
    virtual ~Object() {
621
11.1k
        if (_obj != nullptr) [[likely]] {
622
10.8k
            JNIEnv* env = nullptr;
623
10.8k
            if (Status st = RefHelper<Ref>::get_env(&env); !st.ok()) [[unlikely]] {
624
0
                LOG(WARNING) << "Can't destroy Jni Ref : " << st.msg();
625
0
                return;
626
0
            }
627
10.8k
            RefHelper<Ref>::destroy(env, _obj);
628
10.8k
        }
629
11.1k
    }
630
631
    template <RefType R>
632
14.0k
    static Status create(JNIEnv* env, const Object<R>& other, Object<Ref>* result) {
633
14.0k
        DCHECK(!other.uninitialized());
634
14.0k
        DCHECK(result->uninitialized());
635
636
14.0k
        result->_obj = RefHelper<Ref>::create(env, other._obj);
637
14.0k
        RETURN_ERROR_IF_EXC(env);
638
14.0k
        return Status::OK();
639
14.0k
    }
_ZN5doris3Jni6ObjectILNS0_7RefTypeE1EE6createILS2_0EEENS_6StatusEP7JNIEnv_RKNS1_IXT_EEEPS3_
Line
Count
Source
632
10.7k
    static Status create(JNIEnv* env, const Object<R>& other, Object<Ref>* result) {
633
10.7k
        DCHECK(!other.uninitialized());
634
10.7k
        DCHECK(result->uninitialized());
635
636
10.7k
        result->_obj = RefHelper<Ref>::create(env, other._obj);
637
10.7k
        RETURN_ERROR_IF_EXC(env);
638
10.7k
        return Status::OK();
639
10.7k
    }
_ZN5doris3Jni6ObjectILNS0_7RefTypeE0EE6createILS2_0EEENS_6StatusEP7JNIEnv_RKNS1_IXT_EEEPS3_
Line
Count
Source
632
3.30k
    static Status create(JNIEnv* env, const Object<R>& other, Object<Ref>* result) {
633
3.30k
        DCHECK(!other.uninitialized());
634
3.30k
        DCHECK(result->uninitialized());
635
636
3.30k
        result->_obj = RefHelper<Ref>::create(env, other._obj);
637
3.30k
        RETURN_ERROR_IF_EXC(env);
638
3.30k
        return Status::OK();
639
3.30k
    }
640
641
695k
    bool uninitialized() const { return _obj == nullptr; }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE0EE13uninitializedEv
Line
Count
Source
641
512k
    bool uninitialized() const { return _obj == nullptr; }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE1EE13uninitializedEv
Line
Count
Source
641
183k
    bool uninitialized() const { return _obj == nullptr; }
642
643
    // Access the JNI handle without changing ownership.
644
0
    jobject get() const { return _obj; }
Unexecuted instantiation: _ZNK5doris3Jni6ObjectILNS0_7RefTypeE1EE3getEv
Unexecuted instantiation: _ZNK5doris3Jni6ObjectILNS0_7RefTypeE0EE3getEv
645
646
2
    void reset(JNIEnv* env) {
647
2
        if (_obj == nullptr) {
648
0
            return;
649
0
        }
650
2
        RefHelper<Ref>::destroy(env, _obj);
651
2
        _obj = nullptr;
652
2
    }
653
654
    template <RefType T>
655
109k
    bool equal(JNIEnv* env, const Object<T>& other) {
656
109k
        DCHECK(!uninitialized());
657
109k
        DCHECK(!other.uninitialized());
658
109k
        return env->IsSameObject(this->_obj, other._obj); //assume not throw exception.
659
109k
    }
660
661
83.2k
    FunctionCall<ObjectMethod> call_object_method(JNIEnv* env, MethodId method_id) const {
662
83.2k
        DCHECK(!this->uninitialized());
663
83.2k
        DCHECK(!method_id.uninitialized());
664
83.2k
        return FunctionCall<ObjectMethod>::instance(env, _obj, method_id._id);
665
83.2k
    }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE0EE18call_object_methodEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
661
83.2k
    FunctionCall<ObjectMethod> call_object_method(JNIEnv* env, MethodId method_id) const {
662
83.2k
        DCHECK(!this->uninitialized());
663
        DCHECK(!method_id.uninitialized());
664
83.2k
        return FunctionCall<ObjectMethod>::instance(env, _obj, method_id._id);
665
83.2k
    }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE1EE18call_object_methodEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
661
2
    FunctionCall<ObjectMethod> call_object_method(JNIEnv* env, MethodId method_id) const {
662
2
        DCHECK(!this->uninitialized());
663
        DCHECK(!method_id.uninitialized());
664
2
        return FunctionCall<ObjectMethod>::instance(env, _obj, method_id._id);
665
2
    }
666
667
990
    FunctionCall<IntMethod> call_int_method(JNIEnv* env, MethodId method_id) const {
668
990
        DCHECK(!this->uninitialized());
669
990
        DCHECK(!method_id.uninitialized());
670
990
        return FunctionCall<IntMethod>::instance(env, _obj, method_id._id);
671
990
    }
672
673
13.6k
    FunctionCall<LongMethod> call_long_method(JNIEnv* env, MethodId method_id) const {
674
13.6k
        DCHECK(!this->uninitialized());
675
13.6k
        DCHECK(!method_id.uninitialized());
676
13.6k
        return FunctionCall<LongMethod>::instance(env, _obj, method_id._id);
677
13.6k
    }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE0EE16call_long_methodEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
673
10.8k
    FunctionCall<LongMethod> call_long_method(JNIEnv* env, MethodId method_id) const {
674
10.8k
        DCHECK(!this->uninitialized());
675
        DCHECK(!method_id.uninitialized());
676
10.8k
        return FunctionCall<LongMethod>::instance(env, _obj, method_id._id);
677
10.8k
    }
_ZNK5doris3Jni6ObjectILNS0_7RefTypeE1EE16call_long_methodEP7JNIEnv_NS0_8MethodIdE
Line
Count
Source
673
2.78k
    FunctionCall<LongMethod> call_long_method(JNIEnv* env, MethodId method_id) const {
674
2.78k
        DCHECK(!this->uninitialized());
675
        DCHECK(!method_id.uninitialized());
676
2.78k
        return FunctionCall<LongMethod>::instance(env, _obj, method_id._id);
677
2.78k
    }
678
679
273
    FunctionCall<VoidMethod> call_void_method(JNIEnv* env, MethodId method_id) const {
680
273
        DCHECK(!this->uninitialized());
681
273
        DCHECK(!method_id.uninitialized());
682
273
        return FunctionCall<VoidMethod>::instance(env, _obj, method_id._id);
683
273
    }
684
685
6
    FunctionCall<BooleanMethod> call_boolean_method(JNIEnv* env, MethodId method_id) const {
686
6
        DCHECK(!this->uninitialized());
687
6
        DCHECK(!method_id.uninitialized());
688
6
        return FunctionCall<BooleanMethod>::instance(env, _obj, method_id._id);
689
6
    }
690
691
    template <RefType R>
692
    NonvirtualFunctionCall<NonvirtualVoidMethod> call_nonvirtual_void_method(
693
            JNIEnv* env, const Class<R>& clazz, MethodId method_id) const;
694
695
    template <RefType R>
696
    NonvirtualFunctionCall<NonvirtualObjectMethod> call_nonvirtual_object_method(
697
            JNIEnv* env, const Class<R>& clazz, MethodId method_id) const;
698
699
    template <RefType R>
700
    NonvirtualFunctionCall<NonvirtualIntMethod> call_nonvirtual_int_method(
701
            JNIEnv* env, const Class<R>& clazz, MethodId method_id) const;
702
703
    template <RefType R>
704
    NonvirtualFunctionCall<NonvirtualBooleanMethod> call_nonvirtual_boolean_method(
705
            JNIEnv* env, const Class<R>& clazz, MethodId method_id) const;
706
707
protected:
708
    jobject _obj = nullptr;
709
    DISALLOW_COPY_AND_ASSIGN(Object);
710
};
711
712
using LocalObject = Object<Local>;
713
using GlobalObject = Object<Global>;
714
715
static inline Status local_to_global_ref(JNIEnv* env, const LocalObject& local_ref,
716
10.8k
                                         GlobalObject* global_ref) {
717
10.8k
    return Object<Global>::create(env, local_ref, global_ref);
718
10.8k
}
Unexecuted instantiation: doris_main.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_0_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: config.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: doris_metrics.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
jvm_metrics.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Line
Count
Source
716
62
                                         GlobalObject* global_ref) {
717
62
    return Object<Global>::create(env, local_ref, global_ref);
718
62
}
Unexecuted instantiation: unity_2_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_3_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_5_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_14_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
unity_1_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Line
Count
Source
716
10.7k
                                         GlobalObject* global_ref) {
717
10.7k
    return Object<Global>::create(env, local_ref, global_ref);
718
10.7k
}
Unexecuted instantiation: unity_8_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_7_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_12_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_6_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_13_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_11_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_10_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_9_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_4_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hashjoin_build_sink.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: join_build_sink_operator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: operator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: partitioned_aggregation_sink_operator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: scan_operator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vfile_result_writer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_31_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_30_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_29_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_28_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_27_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_26_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_25_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_24_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_22_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_21_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_20_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_19_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_18_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_17_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_16_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_15_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: ai_functions.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: function_array_aggregation.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: function_date_or_datetime_computation.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: function_datetime_floor_ceil.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: in.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: uuid.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: arrow_row_batch.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: arrow_stream_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: csv_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: new_json_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vorc_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: column_type_convert.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: schema_desc.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_group_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_column_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_column_chunk_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_page_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: parquet_column_convert.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_page_index.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: parquet_block_split_bloom_filter.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: deletion_vector_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: es_http_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hive_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hive_orc_nested_column_utils.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hudi_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hudi_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_delete_file_reader_helper.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_position_delete_sys_table_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_orc_nested_column_utils.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: equality_delete.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_sys_table_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: jdbc_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: max_compute_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: paimon_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: paimon_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: parquet_metadata_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: parquet_utils.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: remote_doris_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: table_format_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: table_schema_change_helper.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: transactional_hive_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: trino_connector_jni_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: text_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: merge_partitioner.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: iceberg_partition_function.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vcsv_transformer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vfile_format_transformer_factory.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: viceberg_parquet_writer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vjni_format_transformer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vorc_transformer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vparquet_writer.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: adbc_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: hdfs_file_system.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: unity_23_cxx.cxx:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: inverted_index_compound_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: inverted_index_fs_directory.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: zone_map_index.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: vcollect_iterator.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: predicate_creator_comparison.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: predicate_creator_in_list_in.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: predicate_creator_in_list_not_in.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: tablet.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: engine_clone_task.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: descriptors.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: backend_service.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: point_query_executor.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: be_server_starter_factory.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: http_service.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: internal_service.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: arrow_flight_batch_reader.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: thrift_util.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: load_stream.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: routine_load_task_executor.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
Unexecuted instantiation: cloud_compaction_action.cpp:_ZN5doris3JniL19local_to_global_refEP7JNIEnv_RKNS0_6ObjectILNS0_7RefTypeE0EEEPNS3_ILS4_1EEE
719
720
// auto ReleaseStringUTFChars ReleaseByteArrayElements ...
721
template <BufferType bufferfType, RefType Ref>
722
class BufferGuard {
723
public:
724
3.30k
    BufferGuard() = default;
725
726
    template <RefType R>
727
    static Status create(JNIEnv* env, const Object<R>& object,
728
3.30k
                         BufferGuard<bufferfType, Ref>* result, jboolean* isCopy) {
729
3.30k
        DCHECK(result->_buffer == nullptr && result->_object.uninitialized());
730
731
3.30k
        RETURN_IF_ERROR(Object<Ref>::create(env, object, &result->_object));
732
733
3.30k
        if constexpr (bufferfType == BufferType::Chars) {
734
3.30k
            result->_buffer = env->GetStringUTFChars((jstring)result->_object._obj, isCopy);
735
        } else if constexpr (bufferfType == BufferType::ByteArray) {
736
            result->_buffer =
737
                    (char*)env->GetByteArrayElements((jbyteArray)result->_object._obj, isCopy);
738
        } else {
739
            static_assert(false);
740
        }
741
742
3.30k
        RETURN_ERROR_IF_EXC(env);
743
3.30k
        if (result->_buffer == nullptr) [[unlikely]] {
744
0
            return Status::JniError("GetStringUTFChars/GetByteArrayElements fail.");
745
0
        }
746
747
3.30k
        return Status::OK();
748
3.30k
    }
749
750
3.30k
    ~BufferGuard() {
751
3.30k
        if (_object.uninitialized() || _buffer == nullptr) [[unlikely]] {
752
0
            return;
753
0
        }
754
3.30k
        JNIEnv* env = nullptr;
755
756
3.30k
        if (auto st = RefHelper<Ref>::get_env(&env); !st.ok()) [[unlikely]] {
757
0
            LOG(WARNING) << "BufferGuard release fail: " << st;
758
0
            return;
759
0
        }
760
761
3.30k
        if constexpr (bufferfType == BufferType::Chars) {
762
3.30k
            env->ReleaseStringUTFChars((jstring)_object._obj, _buffer);
763
        } else if constexpr (bufferfType == BufferType::ByteArray) {
764
            env->ReleaseByteArrayElements((jbyteArray)_object._obj, (jbyte*)_buffer, JNI_ABORT);
765
        }
766
3.30k
    }
767
768
6.60k
    const char* get() const { return _buffer; }
769
770
private:
771
    Object<Ref> _object;
772
    const char* _buffer = nullptr;
773
774
    DISALLOW_COPY_AND_ASSIGN(BufferGuard);
775
};
776
777
template <RefType Ref>
778
using StringBufferGuard = BufferGuard<Chars, Ref>;
779
using LocalStringBufferGuard = BufferGuard<Chars, Local>;
780
using GlobalStringBufferGuard = BufferGuard<Chars, Global>;
781
782
template <RefType Ref>
783
using ByteArrayBufferGuard = BufferGuard<ByteArray, Ref>;
784
using LocalByteArrayBufferGuard = BufferGuard<ByteArray, Local>;
785
using GlobalByteArrayBufferGuard = BufferGuard<ByteArray, Global>;
786
787
template <RefType Ref>
788
class String : public Object<Ref> {
789
public:
790
48.6k
    String() = default;
791
792
45.2k
    static Status new_string(JNIEnv* env, const char* utf_chars, String<Ref>* result) {
793
45.2k
        DCHECK(result->uninitialized());
794
795
45.2k
        if constexpr (Ref == Local) {
796
45.2k
            result->_obj = env->NewStringUTF(utf_chars);
797
45.2k
            RETURN_ERROR_IF_EXC(env);
798
        } else if constexpr (Ref == Global) {
799
            String local_result;
800
            local_result->_obj = env->NewStringUTF(utf_chars);
801
            RETURN_ERROR_IF_EXC(env);
802
            RETURN_IF_ERROR(local_to_global_ref(env, local_result, result));
803
        } else {
804
            static_assert(false);
805
        }
806
45.2k
        return Status::OK();
807
45.2k
    }
808
809
3.30k
    Status get_string_chars(JNIEnv* env, StringBufferGuard<Ref>* jni_chars) const {
810
3.30k
        return StringBufferGuard<Ref>::create(env, *this, jni_chars, nullptr);
811
3.30k
    }
812
813
private:
814
    DISALLOW_COPY_AND_ASSIGN(String);
815
};
816
817
template <RefType Ref>
818
class Array : public Object<Ref> {
819
public:
820
6.26k
    Array() = default;
821
822
429
    Status get_length(JNIEnv* env, jsize* result) const {
823
429
        DCHECK(!this->uninitialized());
824
825
429
        *result = env->GetArrayLength((jarray)this->_obj);
826
429
        RETURN_ERROR_IF_EXC(env);
827
429
        return Status::OK();
828
429
    }
829
830
53.1k
    Status get_object_array_element(JNIEnv* env, jsize index, Jni::LocalObject* result) {
831
53.1k
        DCHECK(!this->uninitialized());
832
53.1k
        DCHECK(result->uninitialized());
833
53.1k
        result->_obj = env->GetObjectArrayElement((jobjectArray)this->_obj, index);
834
53.1k
        RETURN_ERROR_IF_EXC(env);
835
53.1k
        return Status::OK();
836
53.1k
    }
837
838
    Status get_byte_elements(JNIEnv* env, ByteArrayBufferGuard<Ref>* jni_bytes) const {
839
        DCHECK(!this->uninitialized());
840
        return ByteArrayBufferGuard<Ref>::create(env, *this, jni_bytes, nullptr);
841
    }
842
843
99
    Status get_byte_elements(JNIEnv* env, jsize start, jsize len, jbyte* buffer) {
844
99
        DCHECK(!this->uninitialized());
845
99
        env->GetByteArrayRegion((jbyteArray)this->_obj, start, len, buffer);
846
99
        RETURN_ERROR_IF_EXC(env);
847
99
        return Status::OK();
848
99
    }
849
850
    static Status WriteBufferToByteArray(JNIEnv* env, const jbyte* buffer, jint size,
851
5.43k
                                         Array<Local>* serialized_msg) {
852
5.43k
        DCHECK(serialized_msg->uninitialized());
853
        /// create jbyteArray given buffer
854
5.43k
        serialized_msg->_obj = env->NewByteArray(size);
855
5.43k
        RETURN_ERROR_IF_EXC(env);
856
5.43k
        if (serialized_msg->_obj == nullptr) [[unlikely]] {
857
0
            return Status::JniError("couldn't construct jbyteArray");
858
0
        }
859
5.43k
        env->SetByteArrayRegion((jbyteArray)serialized_msg->_obj, 0, size, buffer);
860
5.43k
        RETURN_ERROR_IF_EXC(env);
861
5.43k
        return Status::OK();
862
5.43k
    }
863
864
    template <class T>
865
5.39k
    static Status SerializeThriftMsg(JNIEnv* env, T* msg, Array<Local>* serialized_msg) {
866
5.39k
        int buffer_size = 100 * 1024; // start out with 100KB
867
5.39k
        ThriftSerializer serializer(false, buffer_size);
868
869
5.39k
        uint8_t* buffer = nullptr;
870
5.39k
        uint32_t size = 0;
871
5.39k
        RETURN_IF_ERROR(serializer.serialize(msg, &size, &buffer));
872
873
        // Make sure that 'size' is within the limit of INT_MAX as the use of
874
        // 'size' below takes int.
875
5.39k
        if (size > INT_MAX) [[unlikely]] {
876
0
            return Status::JniError(
877
0
                    "The length of the serialization buffer ({} bytes) exceeds the limit of {} "
878
0
                    "bytes",
879
0
                    size, INT_MAX);
880
0
        }
881
5.39k
        RETURN_IF_ERROR(WriteBufferToByteArray(env, (jbyte*)buffer, size, serialized_msg));
882
5.39k
        return Status::OK();
883
5.39k
    }
884
885
private:
886
    DISALLOW_COPY_AND_ASSIGN(Array);
887
};
888
889
template <RefType Ref>
890
class Class : public Object<Ref> {
891
public:
892
10.9k
    Class() = default;
_ZN5doris3Jni5ClassILNS0_7RefTypeE1EEC2Ev
Line
Count
Source
892
5.55k
    Class() = default;
_ZN5doris3Jni5ClassILNS0_7RefTypeE0EEC2Ev
Line
Count
Source
892
5.42k
    Class() = default;
893
894
44
    static Status find_class(JNIEnv* env, const char* class_str, Class<Ref>* result) {
895
44
        DCHECK(result->uninitialized());
896
        if constexpr (Ref == Local) {
897
            result->_obj = env->FindClass(class_str);
898
            RETURN_ERROR_IF_EXC(env);
899
            return Status::OK();
900
44
        } else if constexpr (Ref == Global) {
901
44
            Class<Local> local_class;
902
44
            local_class._obj = env->FindClass(class_str);
903
44
            RETURN_ERROR_IF_EXC(env);
904
44
            return local_to_global_ref(env, local_class, result);
905
        } else {
906
            static_assert(false);
907
        }
908
44
    }
909
910
    /**
911
     * The class of an object that is already in hand.
912
     *
913
     * Needed where a class cannot be named: an object produced by a plugin is an instance of a
914
     * class inside that plugin's classloader, which FindClass - searching BE's own loader -
915
     * cannot see. Asking the object is the only way to reach it.
916
     */
917
    template <RefType R>
918
5.36k
    static Status get_object_class(JNIEnv* env, const Object<R>& object, Class<Ref>* result) {
919
5.36k
        DCHECK(!object.uninitialized());
920
5.36k
        DCHECK(result->uninitialized());
921
5.36k
        if constexpr (Ref == Local) {
922
0
            result->_obj = env->GetObjectClass(object._obj);
923
0
            RETURN_ERROR_IF_EXC(env);
924
0
            return Status::OK();
925
5.36k
        } else if constexpr (Ref == Global) {
926
5.36k
            Class<Local> local_class;
927
5.36k
            local_class._obj = env->GetObjectClass(object._obj);
928
5.36k
            RETURN_ERROR_IF_EXC(env);
929
5.36k
            return local_to_global_ref(env, local_class, result);
930
        } else {
931
            static_assert(false);
932
        }
933
5.36k
    }
Unexecuted instantiation: _ZN5doris3Jni5ClassILNS0_7RefTypeE0EE16get_object_classILS2_1EEENS_6StatusEP7JNIEnv_RKNS0_6ObjectIXT_EEEPS3_
_ZN5doris3Jni5ClassILNS0_7RefTypeE1EE16get_object_classILS2_1EEENS_6StatusEP7JNIEnv_RKNS0_6ObjectIXT_EEEPS3_
Line
Count
Source
918
5.36k
    static Status get_object_class(JNIEnv* env, const Object<R>& object, Class<Ref>* result) {
919
5.36k
        DCHECK(!object.uninitialized());
920
5.36k
        DCHECK(result->uninitialized());
921
        if constexpr (Ref == Local) {
922
            result->_obj = env->GetObjectClass(object._obj);
923
            RETURN_ERROR_IF_EXC(env);
924
            return Status::OK();
925
5.36k
        } else if constexpr (Ref == Global) {
926
5.36k
            Class<Local> local_class;
927
5.36k
            local_class._obj = env->GetObjectClass(object._obj);
928
5.36k
            RETURN_ERROR_IF_EXC(env);
929
5.36k
            return local_to_global_ref(env, local_class, result);
930
        } else {
931
            static_assert(false);
932
        }
933
5.36k
    }
934
935
    /**
936
     * Whether an object is an instance of this class.
937
     *
938
     * The one way to check the kind of something a plugin handed back: the object's own class is
939
     * private to the plugin's classloader, so the only comparable identity is a shared base class
940
     * BE resolved itself. IsInstanceOf raises no exception, hence the plain bool.
941
     */
942
    template <RefType R>
943
5
    bool is_instance(JNIEnv* env, const Object<R>& object) const {
944
5
        DCHECK(!this->uninitialized());
945
5
        DCHECK(!object.uninitialized());
946
5
        return env->IsInstanceOf(object._obj, (jclass)this->_obj) == JNI_TRUE;
947
5
    }
948
949
    Status get_static_method(JNIEnv* env, const char* method_str, const char* method_signature,
950
17
                             MethodId* method_id) const {
951
17
        DCHECK(!this->uninitialized());
952
17
        DCHECK(method_id->uninitialized());
953
17
        method_id->_id = env->GetStaticMethodID((jclass)this->_obj, method_str, method_signature);
954
17
        RETURN_ERROR_IF_EXC(env);
955
17
        return Status::OK();
956
17
    }
957
958
    Status get_method(JNIEnv* env, const char* method_str, const char* method_signature,
959
13.1k
                      MethodId* method_id) const {
960
13.1k
        DCHECK(!this->uninitialized());
961
13.1k
        DCHECK(method_id->uninitialized());
962
13.1k
        method_id->_id = env->GetMethodID((jclass)this->_obj, method_str, method_signature);
963
13.1k
        RETURN_ERROR_IF_EXC(env);
964
13.1k
        return Status::OK();
965
13.1k
    }
966
967
    Status get_static_fieldId(JNIEnv* env, const char* name, const char* signature,
968
18
                              FieldId* field_id) const {
969
18
        DCHECK(!this->uninitialized());
970
18
        DCHECK(field_id->uninitialized());
971
18
        field_id->_id = env->GetStaticFieldID((jclass)this->_obj, name, signature);
972
18
        RETURN_ERROR_IF_EXC(env);
973
18
        return Status::OK();
974
18
    }
975
976
    Status get_static_object_field(JNIEnv* env, const FieldId& field_id,
977
                                   Object<Local>* result) const {
978
        DCHECK(!this->uninitialized());
979
        DCHECK(!field_id.uninitialized());
980
        result->_obj = env->GetStaticObjectField((jclass)this->_obj, field_id._id);
981
        RETURN_ERROR_IF_EXC(env);
982
        return Status::OK();
983
    }
984
985
    Status get_static_object_field(JNIEnv* env, const FieldId& field_id,
986
18
                                   Object<Global>* global_result) const {
987
18
        DCHECK(!this->uninitialized());
988
18
        DCHECK(!field_id.uninitialized());
989
18
        Object<Local> local_result;
990
18
        local_result._obj = env->GetStaticObjectField((jclass)this->_obj, field_id._id);
991
18
        RETURN_ERROR_IF_EXC(env);
992
18
        return local_to_global_ref(env, local_result, global_result);
993
18
    }
994
995
    Status get_static_object_field(JNIEnv* env, const char* name, const char* signature,
996
18
                                   Object<Global>* global_result) const {
997
18
        Jni::FieldId tmpFieldID;
998
18
        RETURN_IF_ERROR(get_static_fieldId(env, name, signature, &tmpFieldID));
999
18
        RETURN_IF_ERROR(get_static_object_field(env, tmpFieldID, global_result));
1000
18
        return Status::OK();
1001
18
    }
1002
1003
5.59k
    FunctionCall<NewObject> new_object(JNIEnv* env, MethodId method_id) const {
1004
5.59k
        DCHECK(!this->uninitialized());
1005
5.59k
        DCHECK(!method_id.uninitialized());
1006
5.59k
        return FunctionCall<NewObject>::instance(env, (jclass)this->_obj, method_id._id);
1007
5.59k
    }
1008
1009
    FunctionCall<StaticObjectMethod> call_static_object_method(JNIEnv* env,
1010
6.67k
                                                               MethodId method_id) const {
1011
6.67k
        DCHECK(!this->uninitialized());
1012
6.67k
        DCHECK(!method_id.uninitialized());
1013
6.67k
        return FunctionCall<StaticObjectMethod>::instance(env, (jclass)this->_obj, method_id._id);
1014
6.67k
    }
1015
1016
928
    FunctionCall<StaticVoidMethod> call_static_void_method(JNIEnv* env, MethodId method_id) const {
1017
928
        DCHECK(!this->uninitialized());
1018
928
        DCHECK(!method_id.uninitialized());
1019
928
        return FunctionCall<StaticVoidMethod>::instance(env, (jclass)this->_obj, method_id._id);
1020
928
    }
1021
1022
private:
1023
    DISALLOW_COPY_AND_ASSIGN(Class);
1024
};
1025
1026
using LocalClass = Class<Local>;
1027
using GlobalClass = Class<Global>;
1028
1029
using LocalArray = Array<Local>;
1030
using GlobalArray = Array<Global>;
1031
1032
using LocalString = String<Local>;
1033
using GlobalString = String<Global>;
1034
1035
template <CallTag tag>
1036
template <RefType Ref>
1037
56.7k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
1038
56.7k
    jvalue v;
1039
56.7k
    std::memset(&v, 0, sizeof(v));
1040
56.7k
    v.l = obj._obj;
1041
56.7k
    _args.push_back(v);
1042
56.7k
    return *this;
1043
56.7k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
1037
34.0k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
1038
34.0k
    jvalue v;
1039
34.0k
    std::memset(&v, 0, sizeof(v));
1040
34.0k
    v.l = obj._obj;
1041
34.0k
    _args.push_back(v);
1042
34.0k
    return *this;
1043
34.0k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE3EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
1037
249
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
1038
249
    jvalue v;
1039
249
    std::memset(&v, 0, sizeof(v));
1040
249
    v.l = obj._obj;
1041
249
    _args.push_back(v);
1042
249
    return *this;
1043
249
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE2EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
1037
5.34k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
1038
5.34k
    jvalue v;
1039
5.34k
    std::memset(&v, 0, sizeof(v));
1040
5.34k
    v.l = obj._obj;
1041
5.34k
    _args.push_back(v);
1042
5.34k
    return *this;
1043
5.34k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE5EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
1037
16.1k
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
1038
16.1k
    jvalue v;
1039
16.1k
    std::memset(&v, 0, sizeof(v));
1040
16.1k
    v.l = obj._obj;
1041
16.1k
    _args.push_back(v);
1042
16.1k
    return *this;
1043
16.1k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE8EE8with_argILNS0_7RefTypeE0EEERS3_RKNS0_6ObjectIXT_EEE
Line
Count
Source
1037
928
FunctionCall<tag>& FunctionCall<tag>::with_arg(const Object<Ref>& obj) {
1038
928
    jvalue v;
1039
928
    std::memset(&v, 0, sizeof(v));
1040
928
    v.l = obj._obj;
1041
928
    _args.push_back(v);
1042
928
    return *this;
1043
928
}
1044
1045
template <CallTag tag>
1046
template <RefType Ref>
1047
101
NonvirtualFunctionCall<tag>& NonvirtualFunctionCall<tag>::with_arg(const Object<Ref>& obj) {
1048
101
    jvalue v;
1049
101
    std::memset(&v, 0, sizeof(v));
1050
101
    v.l = obj._obj;
1051
101
    this->_args.push_back(v);
1052
101
    return *this;
1053
101
}
1054
1055
template <CallTag tag>
1056
73.2k
Status FunctionCall<tag>::call(Object<Local>* result) {
1057
73.2k
    DCHECK(result->uninitialized());
1058
73.2k
    result->_obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
1059
73.2k
    RETURN_ERROR_IF_EXC(this->_env);
1060
73.2k
    return Status::OK();
1061
73.2k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE5EE4callEPNS0_6ObjectILNS0_7RefTypeE0EEE
Line
Count
Source
1056
1.32k
Status FunctionCall<tag>::call(Object<Local>* result) {
1057
1.32k
    DCHECK(result->uninitialized());
1058
1.32k
    result->_obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
1059
1.32k
    RETURN_ERROR_IF_EXC(this->_env);
1060
1.32k
    return Status::OK();
1061
1.32k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE0EE4callEPNS0_6ObjectILNS0_7RefTypeE0EEE
Line
Count
Source
1056
66.3k
Status FunctionCall<tag>::call(Object<Local>* result) {
1057
66.3k
    DCHECK(result->uninitialized());
1058
66.3k
    result->_obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
1059
66.3k
    RETURN_ERROR_IF_EXC(this->_env);
1060
66.3k
    return Status::OK();
1061
66.3k
}
_ZN5doris3Jni12FunctionCallILNS0_7CallTagE9EE4callEPNS0_6ObjectILNS0_7RefTypeE0EEE
Line
Count
Source
1056
5.59k
Status FunctionCall<tag>::call(Object<Local>* result) {
1057
5.59k
    DCHECK(result->uninitialized());
1058
5.59k
    result->_obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
1059
5.59k
    RETURN_ERROR_IF_EXC(this->_env);
1060
5.59k
    return Status::OK();
1061
5.59k
}
1062
1063
template <CallTag tag>
1064
5.36k
Status FunctionCall<tag>::call(Object<Global>* result) {
1065
5.36k
    DCHECK(result->uninitialized());
1066
5.36k
    Object<Local> local_result;
1067
5.36k
    local_result._obj = CallHelper<tag>::call_impl(_env, _base, _method, _args.data());
1068
5.36k
    RETURN_ERROR_IF_EXC(this->_env);
1069
5.36k
    return local_to_global_ref(_env, local_result, result);
1070
5.36k
}
1071
1072
template <CallTag tag>
1073
101
Status NonvirtualFunctionCall<tag>::call(Object<Local>* result) {
1074
101
    DCHECK(result->uninitialized());
1075
101
    result->_obj = CallHelper<tag>::call_impl(this->_env, this->_base, _cls, this->_method,
1076
101
                                              this->_args.data());
1077
101
    RETURN_ERROR_IF_EXC(this->_env);
1078
101
    return Status::OK();
1079
101
}
1080
1081
template <RefType Ref>
1082
template <RefType R>
1083
NonvirtualFunctionCall<NonvirtualObjectMethod> Object<Ref>::call_nonvirtual_object_method(
1084
101
        JNIEnv* env, const Class<R>& clazz, MethodId method_id) const {
1085
101
    DCHECK(!this->uninitialized());
1086
101
    DCHECK(!method_id.uninitialized());
1087
1088
101
    return NonvirtualFunctionCall<NonvirtualObjectMethod>::instance(env, _obj, (jclass)clazz._obj,
1089
101
                                                                    method_id._id);
1090
101
}
1091
1092
template <RefType Ref>
1093
template <RefType R>
1094
NonvirtualFunctionCall<NonvirtualVoidMethod> Object<Ref>::call_nonvirtual_void_method(
1095
6.02k
        JNIEnv* env, const Class<R>& clazz, MethodId method_id) const {
1096
6.02k
    DCHECK(!this->uninitialized());
1097
6.02k
    DCHECK(!method_id.uninitialized());
1098
6.02k
    return NonvirtualFunctionCall<NonvirtualVoidMethod>::instance(env, _obj, (jclass)clazz._obj,
1099
6.02k
                                                                  method_id._id);
1100
6.02k
}
1101
1102
template <RefType Ref>
1103
template <RefType R>
1104
NonvirtualFunctionCall<NonvirtualIntMethod> Object<Ref>::call_nonvirtual_int_method(
1105
        JNIEnv* env, const Class<R>& clazz, MethodId method_id) const {
1106
    DCHECK(!this->uninitialized());
1107
    DCHECK(!method_id.uninitialized());
1108
    return NonvirtualFunctionCall<NonvirtualIntMethod>::instance(env, _obj, (jclass)clazz._obj,
1109
                                                                 method_id._id);
1110
}
1111
1112
template <RefType Ref>
1113
template <RefType R>
1114
NonvirtualFunctionCall<NonvirtualBooleanMethod> Object<Ref>::call_nonvirtual_boolean_method(
1115
        JNIEnv* env, const Class<R>& clazz, MethodId method_id) const {
1116
    DCHECK(!this->uninitialized());
1117
    DCHECK(!method_id.uninitialized());
1118
    return NonvirtualFunctionCall<NonvirtualBooleanMethod>::instance(env, _obj, (jclass)clazz._obj,
1119
                                                                     method_id._id);
1120
}
1121
1122
class Util {
1123
public:
1124
    static size_t get_max_jni_heap_memory_size();
1125
1126
    template <RefType Ref>
1127
44
    static Status find_class(JNIEnv* env, const char* class_str, Class<Ref>* result) {
1128
44
        return Class<Ref>::find_class(env, class_str, result);
1129
44
    }
1130
1131
    template <RefType Ref, RefType R>
1132
5.37k
    static Status get_object_class(JNIEnv* env, const Object<R>& object, Class<Ref>* result) {
1133
5.37k
        return Class<Ref>::get_object_class(env, object, result);
1134
5.37k
    }
Unexecuted instantiation: _ZN5doris3Jni4Util16get_object_classILNS0_7RefTypeE0ELS3_1EEENS_6StatusEP7JNIEnv_RKNS0_6ObjectIXT0_EEEPNS0_5ClassIXT_EEE
_ZN5doris3Jni4Util16get_object_classILNS0_7RefTypeE1ELS3_1EEENS_6StatusEP7JNIEnv_RKNS0_6ObjectIXT0_EEEPNS0_5ClassIXT_EEE
Line
Count
Source
1132
5.37k
    static Status get_object_class(JNIEnv* env, const Object<R>& object, Class<Ref>* result) {
1133
5.37k
        return Class<Ref>::get_object_class(env, object, result);
1134
5.37k
    }
1135
1136
    template <RefType Ref>
1137
    static Status WriteBufferToByteArray(JNIEnv* env, const jbyte* buffer, jint size,
1138
101
                                         Array<Ref>* serialized_msg) {
1139
101
        if constexpr (Ref == Local) {
1140
101
            return Array<Local>::WriteBufferToByteArray(env, buffer, size, serialized_msg);
1141
        } else if constexpr (Ref == Global) {
1142
            Array<Local> local_obj;
1143
            RETURN_IF_ERROR(Array<Local>::WriteBufferToByteArray(env, buffer, size, &local_obj));
1144
            return local_to_global_ref(env, local_obj, serialized_msg);
1145
        } else {
1146
            static_assert(false);
1147
        }
1148
101
    }
1149
1150
    template <class T, RefType Ref>
1151
5.40k
    static Status SerializeThriftMsg(JNIEnv* env, T* msg, Array<Ref>* serialized_msg) {
1152
5.40k
        if constexpr (Ref == Local) {
1153
5.40k
            return Array<Local>::SerializeThriftMsg(env, msg, serialized_msg);
1154
        } else if (Ref == Global) {
1155
            Array<Local> local_obj;
1156
            RETURN_IF_ERROR(Array<Local>::SerializeThriftMsg(env, msg, local_obj));
1157
            return local_to_global_ref(env, local_obj, serialized_msg);
1158
        } else {
1159
            static_assert(false);
1160
        }
1161
5.40k
    }
1162
1163
    template <RefType Ref>
1164
    static Status convert_to_java_map(JNIEnv* env, const std::map<std::string, std::string>& map,
1165
5.59k
                                      Object<Ref>* hashmap_object) {
1166
5.59k
        RETURN_IF_ERROR(hashmap_class.new_object(env, hashmap_constructor)
1167
5.59k
                                .with_arg((jint)map.size())
1168
5.59k
                                .call(hashmap_object));
1169
1170
16.8k
        for (const auto& it : map) {
1171
16.8k
            LocalString key;
1172
16.8k
            RETURN_IF_ERROR(String<Local>::new_string(env, it.first.c_str(), &key));
1173
1174
16.8k
            LocalString value;
1175
16.8k
            RETURN_IF_ERROR(String<Local>::new_string(env, it.second.c_str(), &value));
1176
1177
16.8k
            LocalObject result;
1178
16.8k
            RETURN_IF_ERROR(hashmap_object->call_object_method(env, hashmap_put)
1179
16.8k
                                    .with_arg(key)
1180
16.8k
                                    .with_arg(value)
1181
16.8k
                                    .call());
1182
16.8k
        }
1183
5.59k
        return Status::OK();
1184
5.59k
    }
1185
1186
    template <RefType Ref>
1187
    static Status convert_to_cpp_map(JNIEnv* env, const Object<Ref>& map,
1188
2
                                     std::map<std::string, std::string>* resultMap) {
1189
2
        LocalObject entrySet;
1190
2
        RETURN_IF_ERROR(map.call_object_method(env, mapEntrySetMethod).call(&entrySet));
1191
1192
        // Call the iterator method on the set to iterate over the key-value pairs
1193
2
        LocalObject iteratorSet;
1194
2
        RETURN_IF_ERROR(entrySet.call_object_method(env, iteratorSetMethod).call(&iteratorSet));
1195
1196
6
        while (true) {
1197
6
            jboolean hasNext = false;
1198
6
            RETURN_IF_ERROR(
1199
6
                    iteratorSet.call_boolean_method(env, iteratorHasNextMethod).call(&hasNext));
1200
6
            if (!hasNext) {
1201
2
                break;
1202
2
            }
1203
1204
4
            LocalObject entry;
1205
4
            RETURN_IF_ERROR(iteratorSet.call_object_method(env, iteratorNextMethod).call(&entry));
1206
1207
4
            LocalString javaKey;
1208
4
            RETURN_IF_ERROR(entry.call_object_method(env, getEntryKeyMethod).call(&javaKey));
1209
1210
4
            LocalString javaValue;
1211
4
            RETURN_IF_ERROR(entry.call_object_method(env, getEntryValueMethod).call(&javaValue));
1212
1213
4
            LocalStringBufferGuard key;
1214
4
            RETURN_IF_ERROR(javaKey.get_string_chars(env, &key));
1215
1216
4
            LocalStringBufferGuard value;
1217
4
            RETURN_IF_ERROR(javaValue.get_string_chars(env, &value));
1218
1219
            // Store the key-value pair in the map
1220
4
            (*resultMap)[key.get()] = value.get();
1221
4
        }
1222
2
        return Status::OK();
1223
2
    }
1224
1225
    // The outcome of the one attempt to resolve the JNI base, or nullopt when nothing has
1226
    // attempted it yet. Public, unlike ensure_jni_base() below, precisely because it never
1227
    // triggers the attempt: this is what a reader that must not create a JVM asks - the
1228
    // /api/jni_plugin_status endpoint, which exists to answer "why is Java not working here"
1229
    // and would otherwise have to start a JVM to find out.
1230
    static std::optional<Status> jni_base_outcome();
1231
1232
private:
1233
    // Resolves everything the BE needs from the JVM before it can call any Java code: the
1234
    // exception helpers, the native methods the Java side links against, and the
1235
    // collection classes cached below. Runs once, right after the JVM appears; every
1236
    // caller that follows gets the outcome of that one attempt.
1237
    //
1238
    // Deliberately NOT part of "does this process have a JVM": all of it comes out of
1239
    // doris-jni-spi.jar, and a BE whose Java deployment is incomplete still serves HDFS through
1240
    // libhdfs. JvmLauncher runs it once at the end of its bootstrap and logs a failure; Env, the
1241
    // door every Java caller comes through, refuses to hand out a JNIEnv while it is failing.
1242
    //
1243
    // Only those two may call it. JvmLauncher calls it from inside its bootstrap, with the
1244
    // calling thread already attached and its env cached, because the resolution asks Env::Get()
1245
    // for a JNIEnv and an unattached thread there would go back through ensure_jvm() and deadlock
1246
    // on the once flag the bootstrap is already holding.
1247
    //
1248
    // Env::GetJNIEnvSlowPath() calls it from an unattached thread on purpose, and the invariant
1249
    // that makes THAT safe is a different one, worth stating because nothing enforces it: by the
1250
    // time the slow path gets here, ensure_jvm()'s call_once has already run to completion on
1251
    // some thread, so the resolution below is never the one that runs - it is always the cached
1252
    // answer of the attempt the bootstrap made. Every early exit of _bootstrap() leaves
1253
    // jvm_status non-OK, and the slow path returns on that before reaching this line.
1254
    //
1255
    // Making the base lazy (that is, resolving it here for real rather than reading a cached
1256
    // answer) would put the deadlock straight back, so GetJNIEnvSlowPath() holds it down with a
1257
    // DCHECK: on that path an outcome must already exist before this is called.
1258
    static Status ensure_jni_base();
1259
    friend class JvmLauncher;
1260
    friend class Env;
1261
1262
    static void _parse_max_heap_memory_size_from_jvm();
1263
1264
    // Bytes named by the last -Xmx in `options`, or 0 when none of them says. Split out from the
1265
    // above so that the parsing can be tested without a JVM; see jni_util_test.cpp.
1266
    static jlong _parse_xmx(const std::string& options);
1267
1268
    static Status _init_jni_base() WARN_UNUSED_RESULT;
1269
    static Status _init_collect_class() WARN_UNUSED_RESULT;
1270
    static Status _init_register_natives() WARN_UNUSED_RESULT;
1271
1272
    // for jvm heap
1273
    static jlong max_jvm_heap_memory_size_;
1274
1275
    //for hashmap
1276
    static GlobalClass hashmap_class;
1277
    static MethodId hashmap_constructor;
1278
    static MethodId hashmap_put;
1279
1280
    //for map
1281
    static GlobalClass mapClass;
1282
    static MethodId mapEntrySetMethod;
1283
1284
    // for map entry
1285
    static GlobalClass mapEntryClass;
1286
    static MethodId getEntryKeyMethod;
1287
    static MethodId getEntryValueMethod;
1288
1289
    //for set
1290
    static GlobalClass setClass;
1291
    static MethodId iteratorSetMethod;
1292
1293
    // for iterator
1294
    static GlobalClass iteratorClass;
1295
    static MethodId iteratorHasNextMethod;
1296
    static MethodId iteratorNextMethod;
1297
};
1298
}; // namespace Jni
1299
1300
} // namespace doris