nguyenq / tess4j

Java JNA wrapper for Tesseract OCR API
Apache License 2.0
1.59k stars 372 forks source link

Homebrew installed Tesseract not detected by Tess4J #194

Open nickjwhite opened 4 years ago

nickjwhite commented 4 years ago

Homebrew on OSX installs Tesseract in /usr/local/Cellar/tesseract/, and it puts symlinks for the libraries in /usr/local/lib. However it doesn't seem like JNI picks up the libraries in this location, with the error "Native library (darwin/libtesseract.dylib) not found in resource path".

I'm using VietOCR, so I temporarily fixed the issue by unpacking the .jar, and copying libtesseract.dylib into a darwin directory within it, and re-zipping it. However I think a better solution would be to use NativeLibrary.addSearchPath() to search for /usr/local/lib, as this is a common way of installing Tesseract on OSX.

I'm not very familiar with Java or OSX (I found this issue while helping someone else), so it's possible that there's a better way to do this, but the above suggested solution is the best I know of.

nguyenq commented 4 years ago

JNA looks for the native libraries in certain system paths as described in https://java-native-access.github.io/jna/4.2.1/com/sun/jna/NativeLibrary.html (code). I would think /usr/local/lib would be among them. But to be certain, you can run the program with the system property jna.debug_load=true to print out the search paths.

java -Djna.debug_load=true -jar VietOCR.jar

nguyenq commented 4 years ago

@nickjwhite I just came across this post at JNA Groups board and wonder it has something to do with the issue you're experiencing on MacOS. I may need to make a new release to incorporate JNA 5.6.0 version, which addresses a Mac-related bug.

nickjwhite commented 4 years ago

Thanks @nguyenq, that's very helpful. I also would have thought that /usr/local/lib would be one of the system paths jna checks, but I got my friend to run VietOCR with the jna.debug_load=true setting as you suggested, and sure enough the relevant line is just:

INFO com.sun.jna.NativeLibrary - Adding system paths: [/usr/lib, /usr/lib]

The post you found about the MacOS changes, and JNA's response to them, is certainly interesting. These issues were on OSX 10.14.6, whereas those bugs are triggered with OSX 11.x, however it may possibly be the case that JNA 5.6.0's different way of probing for libraries would fix this case as well. I suspect it wouldn't, though, to be honest.

nguyenq commented 4 years ago

So it turned out that JNA did not look at the directory we expected, but there's a way to tell it where to look for the native library by setting jna.library.path system property, as follows when you launch the program:

java -Djna.library.path=/usr/local/lib -jar VietOCR.jar

where /usr/local/lib would have libtesseract.dylib symlink.

Or create the symlink in /usr/lib directory, if possible.

https://github.com/java-native-access/jna/blob/master/www/GettingStarted.md

nguyenq commented 4 years ago

@nickjwhite VietOCR-5.6.3, which uses JNA-5.6.0, has just been released. Please see if it has resolved the issue with loading Tesseract dynamic library on MacOS.

Thanks, Quan

nickjwhite commented 4 years ago

@nguyenq thanks for that, good idea. Unfortunately the new version doesn't fix this; surprisingly /usr/local/lib doesn't seem to be checked by JNI on OSX at all. Previous versions of VietOCR I just set the Tesseract executable location, so never thought about detection of system libraries, but presumably that wouldn't have worked back then either.

I have no experience with Java development, I'm afraid, so I can't provide a patch adding the NativeLibrary.addSearchPath() which should hardcode a fix. I think, inelegant as it is, it would be worth doing, as Homebrew is a common and recommended way of installing Tesseract on OSX.

Thanks for your continued help with this.

nguyenq commented 4 years ago

Is this applicable?

https://support.azul.com/hc/en-us/articles/360039650212-On-MacOS-10-15-3-and-later-Zulu-Java-doesn-t-load-the-JNI-Libraries-my-Application-needs

You may want to post the question in JNA Groups and see if there's any explanation for the path exclusion.

Thanks.

RickardRanniger commented 3 years ago

I solved it by adding this inside my main method. System.setProperty("jna.library.path", "/usr/local/lib");

Alternatively add -Djna.library.path=/usr/local/lib/ to your run configuration

nguyenq commented 3 years ago

Thanks, we've recently confirmed that for setting the system property.

https://sourceforge.net/p/vietocr/discussion/833570/thread/a9998d5d0b/

chadbrewbaker commented 1 year ago

This works if you are running it under ant on Mac M1.

ANT_OPTS="-Djna.library.path=/opt/homebrew/lib" ant -f mytask.xml
chadbrewbaker commented 1 year ago

https://github.com/nguyenq/tess4j/pull/240 please test.