bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.4k stars 1.57k forks source link

non maven (direct Jars install), modular javafx19 app getting UnsatisfiedLinkError: ... jniopenblas_nolapack #2152

Closed relaxmax01 closed 6 months ago

relaxmax01 commented 6 months ago

Hello, I'm struggling integrating and evaluating javacv 1.5.9 for an existing javafx application (JAVAFX19 modular, deployed on windows-x68 and linux-arm64 (RaspPI4 bullseye). Dev and test with Eclipse, but without Maven (the app to integrate javacv into is not built with maven but directly use jars.

For eval I have a very simple webcam test app using similar implementation than in this example: https://github.com/rladstaetter/javacv-webcam/tree/master. This test app is running fine for the following 2 scenario and fail for the 3rd:

module-info here: module webcamtestmod { exports com.relaxmax.webcamtest; requires javafx.base; requires javafx.controls; requires transitive javafx.graphics; requires org.bytedeco.javacpp; requires org.bytedeco.javacpp.windows.x86_64; requires org.bytedeco.javacv; requires org.bytedeco.opencv; requires org.bytedeco.opencv.windows.x86_64; }

I combed thru the following reference w/o luck: https://github.com/bytedeco/javacv/issues/1435 https://github.com/bytedeco/javacv/issues/1265

Any hint?

happy to provide screen shots, sources, POM..etc if needed.

many thanks!

saudet commented 6 months ago

Please set the "org.bytedeco.javacpp.logger.debug" system property to "true" to get more information on the console.

saudet commented 6 months ago

It says it's not finding OpenBLAS, so I'd try to add that to the module path...

HGuillemet commented 6 months ago

Please try to add the JVM option --add-modules ALL-MODULE-PATH

relaxmax01 commented 6 months ago

Thank you both. adding "--add-modules ALL-MODULE-PATH" or specifically "requires org.bytedeco.openblas" in module-info.java works. Tested on both Windows and raspberryPi 64 :)

any reason for having to call specifically this dependency ?

saudet commented 6 months ago

It's a limitation of the module system. Please report upstream if you'd like to get this improved!

HGuillemet commented 6 months ago

requires org.bytedeco.openblas works

Didn't you mean requires org.bytedeco.openblas.windows.x86_64?

any reason for having to call specifically this dependency ?

For your app to find the native libraries, you have these options:

  1. Have the library installed on your system or in the Java runtime.
  2. Put the jar containing the native libs on the classpath (not compatible with jlink)
  3. Put the jar containing the native libs on the modulepath AND add the module to the module graph.

In your case you used option 3 but missed the last part. To add the module to the module graph the options are:

  1. Add a requires in your module info. That's not the preferred option since your app does not require openblas, it requires opencv which requires openblas. Also we usually want a platform-agnostic module-info
  2. Add --add-module org.bytedeco.openblas.windows.x86_64 to the command line. Similar to 1.
  3. Add --add-module ALL-MODULE-PATH to the command line. This way you rely on the build system to construct the modulepath using javacpp.platform and javacpp.platform.extension properties and add to the module graph all the modules found in the modulepath.

You might argue that org.bytedeco.opencv.windows.x86_64 module should itself require org.bytedeco.openblas.windows.x86_64, but native modules don't have dependencies towards other native modules, because in some cases there may by different suitable modules (with or without GPU support) that prevent us to hardcode the dependency, and you won't need them if do option 3/3 anyway. Native modules do have a transitive dependency toward the java module, so if you have a require org.bytedeco.opencv.windows.x86_64, you should be able to drop require org.bytedeco.opencv.

steeveen commented 3 months ago

Thank you both. adding "--add-modules ALL-MODULE-PATH" or specifically "requires org.bytedeco.openblas" in module-info.java works. Tested on both Windows and raspberryPi 64 :)

any reason for having to call specifically this dependency ?

hello. I meet the same question. Can you tell me your jdk version? are you using java 8?or java 9?

HGuillemet commented 3 months ago

The reported error is related to the Java Platform Module System, introduced in Java 9. If you use Java 8, you must have the libraries installed on your system or add the native jars to the classpath.

steeveen commented 3 months ago

The reported error is related to the Java Platform Module System, introduced in Java 9. If you use Java 8, you must have the libraries installed on your system or add the native jars to the classpath.

hello. I unzip the jniopenblas_nolapack.so from openblas.jar and copy them to my java.library.path. But It runs into 'NoClassDefFoundError: Could not initialize class org.bytedeco.openblas.global.openblas_nolapack' env: OS: RHEL 7(out of my control) Java: JDK 8 SpringBoot: 2.7

HGuillemet commented 3 months ago

The native jar files contains jni*.so libraries, that implement glue code between Java and the actual libraries, and the actual libraries (openblas here) and maybe some dependencies. Maybe didn't you unzip the actual openblas libraries ? Try to extract all .so you find in the jar. But it's usually simpler to add the native jar to your class path. In this case the libraries will be automatically extracted into javacpp cache directory (.javacpp/cache).

steeveen commented 3 months ago

OK, My operation is just like that. I have exported all .so from jar, but that problem is still happening. I will have a try to add jar in the path. By the way, Is it the default configration that All my jars have been added in the java.library.path when my application starts.

saudet commented 3 months ago

To do things manually like that, you'll need to copy the jniopenblas.so file to jniopenblas_nolapack.so as well

steeveen commented 3 months ago

@saudet Yes I did that. I export ligbcc_s.so.1, libgfortran.so.5, libjniopenblas_nolapack.so ,libjniopenblas.so ,libopenblas.so.0, libquadmath.so.0, dictoary include , dictoary lib. and copy all that 8 to /usr/lib. But the problem changed to could not initialize class openblas_nolapack

steeveen commented 3 months ago

By the way. Why there are some .0,.1,.5 suffix with the file name

steeveen commented 3 months ago

When I started, I unzipped the Jar and started it with JarLauncher. I doubt that the problem may be cauesd by this.

steeveen commented 3 months ago

To synchronize the latest progress, I found that the cause of the above problem is that there is no CXXABI_1_3_8 in my OS. I tried to install gcc4.9 but there was no download source in my environment. Is there any other way? In addition, can the new 1.5.11 avoid this problem? look forward to any bro.

HGuillemet commented 3 months ago

gcc 4.9 is now 10 years old. I doubt @saudet will provide binaries for abi older than that. This would cause problems for building other presets. Are you sure you cannot install gcc-c++ 4.9 on RHEL 7 ? Using devtoolset-3 maybe ?

steeveen commented 3 months ago

I got the libstdc.6.0.28.so, which can support CXXABI_1_3_8. I would have a try to replace libstdc.6.0.19.so with this file. I hope it can work.

steeveen commented 1 month ago

Hello everyone. I have solved my question by using RHEL 9 base image. By the way. Is there any solution that can help the code run normally on RHEL7? As I known, many system still run on that especially in the Financial industry.

Janix520 commented 6 days ago
in module-info.java

requires org.bytedeco.javacv;
requires org.bytedeco.javacpp;

requires org.bytedeco.ffmpeg;
requires org.bytedeco.ffmpeg.windows.x86_64;

requires org.bytedeco.opencv;
requires org.bytedeco.opencv.windows.x86_64;

requires org.bytedeco.openblas;
requires org.bytedeco.openblas.windows.x86_64;

I know how to solve this problem, just require the jars of each dynamic library

steeveen commented 2 days ago
in module-info.java

requires org.bytedeco.javacv;
requires org.bytedeco.javacpp;

requires org.bytedeco.ffmpeg;
requires org.bytedeco.ffmpeg.windows.x86_64;

requires org.bytedeco.opencv;
requires org.bytedeco.opencv.windows.x86_64;

requires org.bytedeco.openblas;
requires org.bytedeco.openblas.windows.x86_64;

I know how to solve this problem, just require the jars of each dynamic library

Yes, I know that. But the key point of this solution is that it is difficult to get supporting openblas in RHEL7, I have to update libstdc、gcc and many other denpendencys.