Я хочу использовать уже существующий код C ++ в Apache Spark, который работает на Java. Я использовал SWIG для генерации интерфейса JNI, который работает как шарм, пока я вызываю функции из простого класса, подобного этому (MyJavaClass.java):
public class MyJavaClass {
public static void main(String[] args) {
System.loadLibrary("mycppcode");
mycppcode.dostuff();
}
}
Затем я попытался интегрировать класс в свою иерархию пакетов, которую я должен иметь для возможности вызова из Spark (MyJavaClass.java):
package com.mycompany.mypackage;
public class MyJavaClass {
public void MyJavaMethod() {
System.loadLibrary("mycppcode");
mycppcode.dostuff();
}
}
Но как только я добавлю пакет линия я получаю следующую ошибку при запуске Javac в файле:
MyJavaClass.java:6: error: cannot find symbol
mycppcode.dostuff();
^
symbol: variable mycppcode
location: class MyJavaClass
1 error
Я использовал следующие команды для генерации JNI, библиотеки libmycppcode.so и класса Java:
swig -c++ -java -package com.mycompany.mypackage mycppcode.i
g++ -fpic -c mycppcode.cpp mycppcode_wrap.cxx -std=c++17 -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux
g++ -shared mycppcode.o mycppcode.o -o libmycppcode.so
javac MyJavaClass.java
Это файл C ++ (mycppcode.cpp):
#include <iostream>
using namespace std;
int dostuff() {
cout << "Hello World!" << endl;
}
Это интерфейсный файл (mycppcode.i):
%module mycppcode
%{
extern int dostuff();
%}
extern int dostuff();
Это сгенерированный файл JNI (mycppcodeJNI.java):
package com.mycompany.mypackage
public class mycppcodeJNI {
public final static native int dostuff();
}
Это сгенерированный файл Java (mycppcode.java):
public class mycppcode {
public static int dostuff() {
return mycppcodeJNI.dostuff();
}
}
Я только получил это на работу. Большое спасибо @Michael за подсказку с -пакет аргумент.
Кажется, проблема в том, что я пытался запустить Javac из фактической папки файла класса, например:
~/myproject/src/com/mycompany/mypackage$ javac MyJavaClass.java
Вместо Javac должен быть выполнен из корневого исходного каталога следующим образом:
~/myproject/src$ javac com/mycompany/mypackage/MyJavaClass.java
Я не уверен, почему, но это предотвращает ошибку.
Как объяснил Вот, вы не можете использовать класс из пакета по умолчанию в вашем com.mycompany.mypackage. MyJavaClass. Вы должны переименовать mycppcode учебный класс:
package com.mycompany.mypackage;
public class mycppcode {
public static int dostuff() {
return mycppcodeJNI.dostuff();
}
}
На самом деле, он может использовать любое название пакета, например
package jni;
public class mycppcode {
public static int dostuff() {
return mycppcodeJNI.dostuff();
}
}