nestrocuation
nestrocuation

Reputation: 249

Tess4j unsatisfied link error on mac OS X

Hey i am trying to use tess4j for tesseract and having this issue for eclipse on mac osx .

My tesseract is working fine from terminal but trying to run tess4j through tesseract throws me an error .

java.lang.UnsatisfiedLinkError: Unable to load library 'tesseract': Native library (darwin/libtesseract.dylib)

i do have tessetact dylib and its named libtesseract.dylib in my opt/local/lib which i installed using macport .

Thanks for your help

Upvotes: 14

Views: 24958

Answers (8)

Wilson
Wilson

Reputation: 1717

After many years, this is still a big issue to many people who want to use Tess4j in MacOs. The issue is on Tess4j, not Tesseract. Tess4j is the Java wrapper for Tesseract. Apparently the Tess4j jar file is missing a c++ library (libtesseract.dylib) necessary for its operation in macos. I'll explain the steps I took to solve this for Mac users.

Tools: Gradle 8.5, JDK 21, Tesseract 5.3.4 (from sourceforge), Tess4j 5.10.0, Intellij, Mac Os - Sonoma 14.2.1, Kotlin 1.9.22, Spring Boot 3.2.2

  1. Install Tesseract using brew brew install tesseract. You can use brew list tesseract to check where brew installed tesseract. For me, brew installed it at /opt/homebrew/Cellar/tesseract/5.3.4

  2. I used both the jar file and gradle dependency from this maven repo.. Here is my my setup (parts of my directory and gradle.build.kts dependencies). directory structure for tessj4 setup in gradle

gradle dependency

The libs directory and everything inside it are created by me. The libtesseract.dylib is a renamed version of libtesseract.5.dylib from brew's tesseract installation. In my case, it's located at /opt/homebrew/Cellar/tesseract/5.3.4/lib/libtesseract.5.dylib. The 5 in libtesseract.5.dylib seems to be the tesseract version, yours might be different depending on the time you'll be reading this.

Side Note: The reason I used both the maven repo in the gradle build file as well as a jar file is that Tess4j has other dependencies which the gradle dependency brings in, such as Lept4J, which is a Java JNA wrapper for image processing. Also, I didn't want to patch the tess4j-5.10.0.jar file built by gradle because it's stored inside a hashed folder which could change when rebuilt or version updated.

  1. The last thing is to patch the jar file with the c++ library we copied. Open a terminal at the libs folder shown in the above image and run the following commands. i) jar uf tess4j-5.10.0.jar darwin - This will update the jar archive file with the darwin directory which you created.

ii) jar uf tess4j-5.10.0.jar darwin/libtesseract.dylib this will update the jar file with the library you copied.

iii) jar tf tess4j-5.10.0.jar (Optional) - verify the patching was successful.

At this point, you should be ready to go.

Bonus:

    fun getImageText(): String {
        val image = ImageIO.read(File("src/main/resources/url.png"))
        val tesseract = Tesseract()
        tesseract.setDatapath("/opt/homebrew/Cellar/tesseract/5.3.4/share/tessdata")
        tesseract.setLanguage("eng")
       // tesseract.setLanguage("jpn_vert") // japanese
        tesseract.setPageSegMode(1)
        tesseract.setOcrEngineMode(1)
       // tesseract.setVariable("tessedit_create_hocr", "1") // html output

        try {
            return tesseract.doOCR(image)
        } catch (e: TesseractException) {
            // handle error
        }
    }

NOTE: In case you are working with images with languages other than English, there's a way to brew more language into tesseract installation but I didn't care to search. What I did was to download the traineddata file for the language I wanted from tesseract repo on github and paste it into the brew's tesseract installation.

For my case, I wanted Japanese, so I downloaded the jpy_vert.traineddata and pasted the downloaded file into tessdata folder inside tesseract brew's installation, which, in my case, is /opt/homebrew/Cellar/tesseract/5.3.4/share/tessdata/jpn_vert.traineddata

Upvotes: 6

Jamy Cake
Jamy Cake

Reputation: 1

You should to specify the path to .dylib via Djna.library.path vm option.

In my case: -Djna.library.path=/usr/local/lib

Also this topic may be useful for you, because in my case it is need to install tesseract for x86_64 architecture:

Upvotes: 0

Max M.
Max M.

Reputation: 266

@maresa after a few years your comment helped me, thanks a lot :) A bit different paths, maybe it'll help someone:

  1. cd /Users/username/.m2/repository/net/sourceforge/tess4j/tess4j/4.5.4/
  2. mkdir darwin
  3. jar uf tess4j-4.5.4.jar darwin/
  4. brew info tesseract (here you can find path to libtesseract.4.dylib)
  5. cp /usr/local/Cellar/tesseract/4.1.1/lib/libtesseract.4.dylib darwin/libtesseract.dylib
  6. jar uf tess4j-4.5.4.jar darwin/libtesseract.dylib
  7. jar tf tess4j-4.5.4.jar

MacOS Catalina - 10.15.3

Upvotes: 8

Long Nguyen
Long Nguyen

Reputation: 10936

You need install the tesseract lib on your Mac.

brew install tesseract --with-all-languages

Upvotes: 5

Michael Miklavcic
Michael Miklavcic

Reputation: 111

I had a very similar issue with Ghost4j, i.e.

InvocationTargetException: Unable to load library 'gs': Native library (darwin/libgs.dylib) not found in resource path

Instead of modifying jar files, point jna to the appropriate lib path by setting jna.library.path. In Eclipse, you need to set the system property in run configurations - SO answer for this here - https://stackoverflow.com/a/862405/2163229

If you're using Maven exec:

mvn -Djna.library.path=/opt/local/lib/ exec:java -Dexec.mainClass="foo.bar.NativeThingy"

or

export MAVEN_OPTS="-Djna.library.path=/opt/local/lib/" && mvn exec:java -Dexec.mainClass="foo.bar.NativeThingy"

Obviously, set the path to wherever your libs are installed. In my case, I ran $ locate libgs.dylib and found the above path.

References: https://jna.java.net/javadoc/com/sun/jna/NativeLibrary.html

Upvotes: 5

Andrew Neilson
Andrew Neilson

Reputation: 912

This is exactly what I was after today, so thanks for the Q&A above. As one additional step beyond what maresa mentioned, I ran into this error after fixing the one you asked about:

java.lang.UnsatisfiedLinkError: dlopen(/var/folders/sq/rh89_ntd7jqdlv9__25zj9dr0000gp/T/jna--913086793/jna8800789057827590119.tmp, 9): Library not loaded: /usr/local/lib/libjpeg.8.dylib
  Referenced from: /usr/local/lib/liblept.4.dylib
  Reason: image not found

So to fix this I needed to set up a symlink for libjpeg.8.dylib:

ln -s /usr/local/Cellar/jpeg/8d/lib/libjpeg.8.dylib /usr/local/lib/libjpeg.8.dylib

Not sure if there is a way to do this without the symlink (i.e. package it in the jar), but I hope this helps anyone else who is looking at this post.

Upvotes: 0

maresa
maresa

Reputation: 641

I know it's an old post. I had this problem too recently when I tried to use Tess4J. However, I managed to find a way around it. I've written a post about it http://www.microshell.com/programming/java/performing-optical-character-recognition-in-java/

In short, the problem is because tess4j-2.0.0.jar doesn't include MacOS library. So I just modified the maven cached jar on mine by doing these steps:

  1. cd /Users/user/.m2/repository/net/sourceforge/tess4j/tess4j/2.0.0 (adjust the directory where your tess4j JAR file resides)
  2. mkdir darwin
  3. jar uf tess4j-2.0.0.jar darwin
  4. cp /opt/local/lib/libtesseract.3.dylib darwin/libtesseract.dylib
  5. jar uf tess4j-2.0.0.jar darwin/libtesseract.dylib
  6. jar tf tess4j-2.0.0.jar (to verify that the file is included)

I was then able to run my Java program after I modify the tess4j-2.0.0.jar file. Below is my MacOS version.

user@laptop:~$ uname -a
Darwin Maresas-MacBook-Pro.local 14.3.0 Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64

Upvotes: 21

nguyenq
nguyenq

Reputation: 8345

Make sure you use libtesseract.dylib of Tesseract 3.02 version. Check out this post on Tesseract Forum.

Upvotes: 0

Related Questions