JNI, вызвано: java .lang.UnsatisfiedLinkError: com.tencent.wxapp.core.jni.JNI.call (Ljava / util / List;) [B - PullRequest
0 голосов
/ 04 августа 2020

Пытаюсь позвонить cpp на Java. После упаковки в Jar такая ошибка возникает после запуска. Я могу запустить эти коды в системе Linux, но сожалею, что сообщаю об ошибке после упаковки их в банку.

Как мне изменить мою программу? Есть ли проблема с именованием?

    com.tencent.oceanus.jar.program.ProgramInvocationException: org.apache.flink.client.program.ProgramInvocationException: The program caused an error: 
    at com.tencent.oceanus.jar.CliFrontend.executeProgram(CliFrontend.java:248)
    at com.tencent.oceanus.jar.CliFrontend.getJobGraph(CliFrontend.java:168)
    at com.tencent.oceanus.server.jobs.JobManager.compile(JobManager.java:257)
    at com.tencent.oceanus.server.jobs.transitions.StartTransitionCallback$StartThread.start(StartTransitionCallback.java:236)
    at com.tencent.oceanus.server.jobs.transitions.StartTransitionCallback$StartThread.run(StartTransitionCallback.java:142)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.flink.client.program.ProgramInvocationException: The program caused an error: 
    at org.apache.flink.client.program.OptimizerPlanEnvironment.getOptimizedPlan(OptimizerPlanEnvironment.java:93)
    at com.tencent.oceanus.jar.program.ClusterClient.getOptimizedPlan(ClusterClient.java:244)
    at com.tencent.oceanus.jar.program.ClusterClient.run(ClusterClient.java:316)
    at com.tencent.oceanus.jar.program.ClusterClient.run(ClusterClient.java:285)
    at com.tencent.oceanus.jar.CliFrontend.executeProgram(CliFrontend.java:242)
    ... 9 more
Caused by: java.lang.UnsatisfiedLinkError: com.tencent.wxapp.core.jni.JNI.call(Ljava/util/List;)[B
    at com.tencent.wxapp.core.jni.JNI.call(Native Method)
    at com.tencent.wxapp.core.jni.JNITest.main(JNITest.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.tencent.oceanus.jar.program.CustomPackagedProgram.callMainMethod(CustomPackagedProgram.java:314)
    at com.tencent.oceanus.jar.program.CustomPackagedProgram.invokeInteractiveModeForExecution(CustomPackagedProgram.java:213)
    at org.apache.flink.client.program.OptimizerPlanEnvironment.getOptimizedPlan(OptimizerPlanEnvironment.java:83)
    ... 13 more

Это мой JNI. java

package com.tencent.wxapp.core.jni;

import java.io.*;
import java.util.List;

public class JNI{
    public native byte[] call(List<String> jList);
    static{
        InputStream is = JNI.class.getResourceAsStream("/JNIdll.so");
        File file = null;
        try {
            file = File.createTempFile("lib", ".so");
        } catch (IOException e) {
            e.printStackTrace();
        }
        OutputStream os = null;
        try {
            os = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        byte[] buffer = new byte[1024];
        int length = 0;
        while (true) {
            try {
                if (!((length = is.read(buffer)) != -1)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                os.write(buffer, 0, length);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.load(file.getAbsolutePath());
        file.deleteOnExit();


    }
}

Это мой JNI. cpp

//JNIdll.cpp文件

#include<stdio.h>
#include<iostream>
#include <strstream>
#include "hyperloglog.hpp"
#include <vector>
#include <string>
#include <fstream>
#include "JNI.h"


using namespace hll;
using namespace std;

JNIEXPORT jbyteArray JNICALL Java_JNI_call
  (JNIEnv *env, jobject obj,jobject jList){
      //实现代码
        HyperLogLog hll(10);
        // retrieve the java.util.List interface class
        jclass cList = env->FindClass("java/util/List");
        // retrieve the toArray method and invoke it
        jmethodID mToArray = env->GetMethodID(cList, "toArray", "()[Ljava/lang/Object;");
        jobjectArray array = (jobjectArray)env->CallObjectMethod(jList, mToArray);
        // now create the string array
        string* sArray = new string[env->GetArrayLength(array)];

        for(int i=0;i<env->GetArrayLength(array);i++) {
            // retrieve the chars of the entry strings and assign them to the array!
            jstring strObj = (jstring)env->GetObjectArrayElement(array, i);
            const char * chr = env->GetStringUTFChars(strObj, NULL);
            sArray[i].append(chr);
            env->ReleaseStringUTFChars(strObj, chr);
        }

        // just print the array to std::cout
        for(int i=0;i<env->GetArrayLength(array);i++) {
           //print value
           cout << sArray[i] << endl;
           const char* p = sArray[i].data();
           hll.add(p,10);
        }

        //print estimate value
        cout<<hll.estimate()<<endl;

        //输出到二进制流
        std::ostringstream sstream;
        hll.dump(sstream);

        const std::string nativeString = sstream.str(); //转换成字符串
        jbyteArray arr = env->NewByteArray(nativeString.length());
        env->SetByteArrayRegion(arr,0,nativeString.length(),(jbyte*)nativeString.c_str()); //存入到二进制array传回Java

    return arr;
}

Это это мой JNI.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNI */

#ifndef _Included_JNI
#define _Included_JNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNI
 * Method:    call
 * Signature: (Ljava/util/ArrayList;)[B
 */
JNIEXPORT jbyteArray JNICALL Java_JNI_call
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif

1 Ответ

1 голос
/ 04 августа 2020

Поскольку собственный метод объявлен как com.tencent.wxapp.core.jni.JNI.call, Java ищет метод в общей библиотеке с именем Java_com_tencent_wxapp_core_jni_JNI_call. Вы экспортировали Java_JNI_call.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...