Continuing to investigate, JNI encountered the following point: in the files in which I describe the implementation of methods (cpp), when iostream connected after building the library (which goes fine) during java, while trying to load it, I catch java.lang.UnsatisfiedLinkError: Can't find dependent libraries Empirically found out that this is iostream (I remove it and everything works).

The question is, is this a restriction related to output streams (as java, like this, blocks or controls) or is there any trick?

problem code:

 //#include <iostream>// как только подключаю - ошибка #include <windows.h>// для проверки того что другие либы импортятся #include <conio.h>// для проверки того что другие либы импортятся #include "implementation.h" JNIEXPORT void JNICALL voidMethod_impl(JNIEnv *env, jobject obj) { printf("%s", "printf test"); // std::cout<<"test cout\n";// даже если это закомментировано а iostream подключен - всеравно ошибка } 
  • Show how you compile. - Sergey Gornostaev
  • @Sergey Gornostaev, With the help of CLion, CMakeLists.txt config such as here I specified (except for other names of my files) - Tr1nks
  • @Sergey Gornostaev assembled by hand, but the problem remained - Tr1nks

2 answers 2

The fact is that by default gcc links your dll dynamically with the libgcc, libstdc ++ and libwinpthread libraries. Accordingly, there are several ways not to receive an error.

First, you can put the dlls of these libraries in the directory present in the PATH environment variable.

Secondly, when starting the program, transfer the JVM parameter java.library.path , which contains the paths to both your dll and dll necessary libraries:

 java -Djava.library.path=.;D:\PROGRAMS\mingw64_7_1\bin com.example.Main 

Third, you can link these libraries to yours statically. The easiest way is to pass the -static parameter to the compiler, but then it will stuff everything into your dll that it seems necessary.

Or you can explicitly specify which libraries are needed:

 g++ -Wl,--add-stdcall-alias ^ -I"%JAVA_HOME%\include" ^ -I"%JAVA_HOME%\include\win32" ^ -L"%MINGW_HOME%\lib\gcc\x86_64-w64-mingw32\lib" ^ -shared -o example.dll Example.cpp ^ -static-libgcc -static-libstdc++ ^ -Wl,-Bstatic -lstdc++ -lpthread 
  • If you make static, then the error: java.lang.UnsatisfiedLinkError: D: \ WORKSPACE \ Intellij_Idea \ NoAsm \ NativeLibTest_instruction \ out \ production \ res \ lib \ libc.dll:% 1 is not a Win32 application, and specifying all the libraries helped. Thank. - Tr1nks
  • This is strange. It seems that you have libc or broken or other bit depth. - Sergey Gornostaev
  • libc is the one in which I collect everything and it is x64 - Tr1nks

No, Java does not block anything. You just need to explicitly specify the path to the external library (in your case, iostream) using:

 -Djava.library.path="<path_to_lib>" 

Ps. In addition, you can see similar questions and their solutions: https://stackoverflow.com/questions/11783632/how-do-i-load-and-use-native-library-in-java

  • java -Djava.library.path = "D: \ PROGRAMS \ mingw64_7_1 \ mingw64 \ lib \ gcc \ x86_64-w64-mingw32 \ 7.1.0 \ include \ c ++ \ iostream" -jar NativeLibTest_instruction.jar did not help (the same error - Tr1nks