Google OR-Tools в Intellij: UnsatisfiedLinkError

Я настраиваю java-фреймворк, который должен использовать Google OR-Tools. Приведенный ниже код успешно компилируется, но во время выполнения выдает исключение:

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.google.ortools.linearsolver.operations_research_linear_solverJNI.MPSolver_CLP_LINEAR_PROGRAMMING_get()I
    at com.google.ortools.linearsolver.operations_research_linear_solverJNI.MPSolver_CLP_LINEAR_PROGRAMMING_get(Native Method)
    at com.google.ortools.linearsolver.MPSolver$OptimizationProblemType.<clinit>(MPSolver.java:221)
    at Main.main(Main.java:15)

Я использую Intellij 2018.3 в Windows 10. Я потратил много времени, пытаясь запустить этот запуск, но безуспешно. Основываясь на том, что я нашел в Интернете, исключение может быть вызвано плохим связыванием и/или отсутствием внешних библиотек, от которых зависит OR-Tools. Однако у меня нет фона для решения этой проблемы, а также Intellij ничего не выделяет. Есть идеи, в чем проблема?

Для завершения это код, который я запускаю:

import com.google.ortools.linearsolver.MPObjective;
import com.google.ortools.linearsolver.MPSolver;
import com.google.ortools.linearsolver.MPVariable;

public final class Main {

  public static void main(String[] args) {

    // Create the linear solver with the GLOP backend.
    MPSolver solver =
        new MPSolver("SimpleLpProgram", MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);

    // Create the variables x and y.
    MPVariable x = solver.makeNumVar(0.0, 1.0, "x");
    MPVariable y = solver.makeNumVar(0.0, 2.0, "y");

    System.out.println("Number of variables = " + solver.numVariables());

    // Create a linear constraint, 0 <= x + y <= 2.
    MPConstraint ct = solver.makeConstraint(0.0, 2.0, "ct");
    ct.setCoefficient(x, 1);
    ct.setCoefficient(y, 1);

    System.out.println("Number of constraints = " + solver.numConstraints());

    // Create the objective function, 3 * x + y.
    MPObjective objective = solver.objective();
    objective.setCoefficient(x, 3);
    objective.setCoefficient(y, 1);
    objective.setMaximization();

    solver.solve();

    System.out.println("Solution:");
    System.out.println("Objective value = " + objective.value());
    System.out.println("x = " + x.solutionValue());
    System.out.println("y = " + y.solutionValue());
  }
}

person BJPrim    schedule 12.11.2019    source источник
comment
Вам не хватает собственного файла библиотеки (DLL).   -  person Kayaman    schedule 12.11.2019
comment
Спасибо. Как включить? Могу ли я сделать это непосредственно в Intellij или мне нужно искать это в Интернете самостоятельно? Я только что выполнил поиск, и единственная документация, которой я могу следовать, - это официальная документация Google, но она предполагает Visual Studio в качестве IDE.   -  person BJPrim    schedule 13.11.2019
comment
Хорошо поищите, как использовать нативные библиотеки с Java (JNI). У вас должна быть установлена ​​родная библиотека, и какая IDE вы используете, не имеет ничего общего. Сначала вы должны выяснить, какая библиотека вам нужна, но это должно быть задокументировано где-то в документации инструментов OR.   -  person Kayaman    schedule 13.11.2019


Ответы (2)


Отказ от ответственности: скорее длинный комментарий, чем ответ...

примечание: я предположил, что вы используете репозиторий github or-tools, если вы использовали двоичный пакет, он должен быть более или менее таким же...

1) Вы должны загрузить библиотеку jni, которая загрузит библиотеки C++ OR-Tools и ее зависимости...

/** Simple linear programming example.*/
public class Main {
  static {
    System.loadLibrary("jniortools");
  }

  public static void main(String[] args) throws Exception {

2) Удалось ли вам запустить образцы Java?

make run SOURCE=ortools/linear_solver/samples/SimpleLpProgram.java

ссылка: https://developers.google.com/optimization/introduction/java#simple_example< /а>

3) Как указал Каяман, вы должны передать папку, в которой среда выполнения java может найти собственные библиотеки (т.е. JNI-оболочку jniortools.dll и ее зависимости libortools.dll)

если вы посмотрите на журнал консоли, вы увидите полную командную строку:

java -Xss2048k -Djava.library.path=lib -cp lib\sample.jar;lib\com.google.ortools.jar;lib\protobuf.jar ...\sample

Что исходит из файла makefiles/Makefile.java:

JAVAFLAGS = -Djava.library.path=$(LIB_DIR)
...
ifeq ($(SOURCE_SUFFIX),.java) # Those rules will be used if SOURCE contain a .java file
$(CLASS_DIR)/$(SOURCE_NAME): $(SOURCE) $(JAVA_OR_TOOLS_LIBS) | $(CLASS_DIR)
    -$(DELREC) $(CLASS_DIR)$S$(SOURCE_NAME)
    -$(MKDIR_P) $(CLASS_DIR)$S$(SOURCE_NAME)
    "$(JAVAC_BIN)" -d $(CLASS_DIR)$S$(SOURCE_NAME) \
 -cp $(LIB_DIR)$Scom.google.ortools.jar$(CPSEP)$(LIB_DIR)$Sprotobuf.jar \
 $(SOURCE_PATH)
...
.PHONY: run # Run a Java program.
run: build
    "$(JAVA_BIN)" -Xss2048k $(JAVAFLAGS) \
 -cp $(LIB_DIR)$S$(SOURCE_NAME)$J$(CPSEP)$(LIB_DIR)$Scom.google.ortools.jar$(CPSEP)$(LIB_DIR)$Sprotobuf.jar \
 $(SOURCE_NAME) $(ARGS)
endif

источник: https://github.com/google/or-tools/blob/46173008fdb15dae1dca0e8fa42a21ed6190b6e4/makefiles/Makefile.java.mk#L15 и https://github.com/google/or-tools/blob/46173008fdb15dae1dca0e8fa42a21ed64190b6efiles/makefiles.java.mk#L328-L333

примечание: вы можете запустить make detect_java, чтобы узнать флаги, то есть значение LIB_DIR примечание: если вы использовали предварительно скомпилированный пакет, Makefile находится здесь: https://github.com/google/или-tools/blob/stable/tools/Makefile.cc.java.dotnet

Затем, после того, как вы можете попробовать добавить эту опцию в Intellij...

Вы должны понимать, что or-tools — это набор нативных библиотек C++, которые завернуты в Java с помощью генератора SWIG.

person Mizux    schedule 14.11.2019

Чтобы заставить его работать с использованием Intellij (на компьютере с Windows), вам необходимо:

  1. Установите Распространяемый компонент Microsoft Visual C++ для Visual Студия
  2. Загрузите и извлеките ИЛИ- Библиотека инструментов для Java
  3. В intellij добавьте зависимость jar к 2 jar-файлам в папке lib извлеченных файлов (каждый из двух jar-файлов отдельно, не добавляйте в саму папку lib. почему).
  4. Добавьте путь к библиотеке lib в параметры виртуальной машины. В Intellij отредактируйте конфигурацию запуска и добавьте параметры vm: -Djava.library.path=<path to the lib folder that hold the jars>
  5. Загрузите библиотеку jni статически, добавив приведенный ниже код в свой класс (как уже упоминалось здесь.)

    static { System.loadLibrary("jniortools"); }

person forhas    schedule 05.06.2020