System.loadLibrary больше не работает как часть пакета в Java

Я хочу использовать уже существующий код 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();
}
}

0

Решение

Я только получил это на работу. Большое спасибо @Michael за подсказку с -пакет аргумент.

Кажется, проблема в том, что я пытался запустить Javac из фактической папки файла класса, например:

~/myproject/src/com/mycompany/mypackage$ javac MyJavaClass.java

Вместо Javac должен быть выполнен из корневого исходного каталога следующим образом:

~/myproject/src$ javac com/mycompany/mypackage/MyJavaClass.java

Я не уверен, почему, но это предотвращает ошибку.

1

Другие решения

Как объяснил Вот, вы не можете использовать класс из пакета по умолчанию в вашем 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();
}
}
0