Загрузка данных


#include "org_example_ClassLoaderExtend.h"
#include <jni.h>
#include <cstdio>

extern "C" {
    JNIEXPORT void JNICALL Java_org_example_ClassLoaderExtend_defineMethod(
        JNIEnv* env,
        jclass clazz,
        jobject classLoader,
        jstring className,
        jbyteArray bytecode,
        jint offset,
        jint length,
        jobject protectionDomain
    ) {
        // Проверяем, что все параметры не null
        if (classLoader == nullptr || className == nullptr || bytecode == nullptr) {
            env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), "Null argument");
            return;
        }

        // Получаем имя класса
        const char* name = env->GetStringUTFChars(className, nullptr);
        if (name == nullptr) {
            return;
        }

        // Получаем байт-код
        jsize bytecodeLength = env->GetArrayLength(bytecode);
        jbyte* bytes = env->GetByteArrayElements(bytecode, nullptr);
        if (bytes == nullptr) {
            env->ReleaseStringUTFChars(className, name);
            return;
        }

        // Получаем метод defineClass из ClassLoader
        jclass clLoaderClass = env->GetObjectClass(classLoader);
        jmethodID defineClassMethod = env->GetMethodID(
            clLoaderClass,
            "defineClass",
            "(Ljava/lang/String;[BII)Ljava/lang/Class;"
        );

        if (defineClassMethod == nullptr) {
            env->ReleaseStringUTFChars(className, name);
            env->ReleaseByteArrayElements(bytecode, bytes, JNI_ABORT);
            return;
        }

        // Вызываем defineClass
        jclass definedClass = (jclass)env->CallObjectMethod(
            classLoader,
            defineClassMethod,
            className,
            bytecode,
            offset,
            length
        );

        // Освобождаем ресурсы
        env->ReleaseStringUTFChars(className, name);
        env->ReleaseByteArrayElements(bytecode, bytes, JNI_ABORT);

        // Проверяем ошибки
        if (env->ExceptionOccurred()) {
            env->ExceptionDescribe();
        }
    }
}