Javacpp-presets: Possible to do a headless packaging of OpenCV and FFmpeg?

Created on 28 Jul 2018  路  8Comments  路  Source: bytedeco/javacpp-presets

I'm running on a system with no GTK which is needed by highgui (and probably others). However, I have no need to run any GUI and getting GTK installed on the target system is at present, not possible.

Exception in thread "main" java.lang.UnsatisfiedLinkError: no jniopencv_highgui in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1225)
    at org.bytedeco.javacpp.Loader.load(Loader.java:983)
    at org.bytedeco.javacpp.Loader.load(Loader.java:882)
    at org.bytedeco.javacpp.opencv_highgui.<clinit>(opencv_highgui.java:15)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.bytedeco.javacpp.Loader.load(Loader.java:941)
    at org.bytedeco.javacpp.Loader.load(Loader.java:898)
    ...
Caused by: java.lang.UnsatisfiedLinkError: some.jar/org/bytedeco/javacpp/linux-x86_64/libjniopencv_highgui.so: libgtk-x11-2.0.so.0: cannot open shared object file: No such file or directory
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
    at java.lang.Runtime.load0(Runtime.java:809)
    at java.lang.System.load(System.java:1086)
    at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1205)
    ...

When I remove all references to highgui from the generated jar, I predictably get a different error:

Exception in thread "main" java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
    at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
    at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
    at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
    at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
    at java.lang.Class.createAnnotationData(Class.java:3521)
    at java.lang.Class.annotationData(Class.java:3510)
    at java.lang.Class.createAnnotationData(Class.java:3526)
    at java.lang.Class.annotationData(Class.java:3510)
    at java.lang.Class.getAnnotation(Class.java:3415)
    at org.bytedeco.javacpp.Loader.checkPlatform(Loader.java:816)
    at org.bytedeco.javacpp.Loader.load(Loader.java:918)
    at org.bytedeco.javacpp.Loader.load(Loader.java:898)
enhancement help wanted question

Most helpful comment

Yeah, it looks like opencv_highgui links with everything. Well, that's an issue with OpenCV. Modules shouldn't link with opencv_highgui if they don't need to display something, so if it's something you feel is really important, you should also report upstream...

All 8 comments

Sure, it's possible to do that. Modify the cppbuild.sh script and follow the build instructions:
https://github.com/bytedeco/javacpp-presets#build-instructions

BTW, it won't actually try to display anything by default anyway. It just needs to link with GTK, so we can just install those libraries on the system and it will work just fine without display.

The issue isn鈥檛 that I鈥檓 afraid it will display anything. My issue is I have no control over the target system so I can鈥檛 install them.

Libraries can still be installed locally. Try to put some random libgtk-x11-2.0.so.0 in your library path and it should work. Even some dummy library with nothing in it should work.

For context, this is being deployed to AWS Lambda. The decision to use Lambda is out of my hands (and certainly isn't my choice for now) but it is increasingly common and likely to become increasingly problematic for people using the presets.

I saw a previous issue that suggested publishing (to e.g. Maven) a pre-built headless version. Is that something that is still being considered?

Alternatively, I also saw mention of bundling in libgtk and friends (as is done with libgomp) was also considered at one point. Is that something that is still being considered?

As an aside, just dealing with libgtk isn't nearly enough:

libatk-1.0.so.0 => not found
libcairo.so.2 => not found
libfontconfig.so.1 => not found
libfreetype.so.6 => not found
libgdk-x11-2.0.so.0 => not found
libgdk_pixbuf-2.0.so.0 => not found
libgomp.so.1 => not found
libgtk-x11-2.0.so.0 => not found
libpango-1.0.so.0 => not found
libpangocairo-1.0.so.0 => not found
libpangoft2-1.0.so.0 => not found

Yeah, it looks like opencv_highgui links with everything. Well, that's an issue with OpenCV. Modules shouldn't link with opencv_highgui if they don't need to display something, so if it's something you feel is really important, you should also report upstream...

This helped, me, for those that come across my initial question with docker, you have to install one of these lib deps. I am figuring out the least required dep path for my personal use. But nice work guys. Thanks for the reference @saudet this solved my issue.

@KennyBarraud You need to make sure the binaries for the native platforms are also bundled.

Yeah ! That was my mistake. Sorry for the inconvenience :p

Was this page helpful?
0 / 5 - 0 ratings