获取 UnsatisfiedLinkError:创建 TessBaseAPI 时 java.library.path 中没有 jnilept
Posted
技术标签:
【中文标题】获取 UnsatisfiedLinkError:创建 TessBaseAPI 时 java.library.path 中没有 jnilept【英文标题】:Getting UnsatisfiedLinkError: no jnilept in java.library.path when I create TessBaseAPI 【发布时间】:2017-01-19 01:06:12 【问题描述】:我是 java cpp 和 tesseract-ocr 的新手。几个小时后,我遇到了一个问题。 我在创建 TessBaseAPI 时收到 UnsatisfiedLinkError: no jnilept in java.library.path。下面是我的一段代码。
public static void tesseractForPdf(String filePath) throws Exception
BytePointer outText;
TessBaseAPI api = new TessBaseAPI();//getting the UnsatisfiedLinkError exception here.
// Initialize tesseract-ocr with English, without specifying tessdata path
if (api.Init(".", "ENG") != 0)
System.err.println("Could not initialize tesseract.");
System.exit(1);
// Open input image with leptonica library
PIX image = pixRead(filePath);
api.SetImage(image);
// Get OCR result
outText = api.GetUTF8Text();
String string = outText.getString();
System.out.println("OCR output:\n" + string);
// Destroy used object and release memory
api.End();
outText.deallocate();
pixDestroy(image);
我在 TessBaseAPI api = new TessBaseAPI(); 上遇到异常线
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jnilept in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:702)
at org.bytedeco.javacpp.Loader.load(Loader.java:500)
at org.bytedeco.javacpp.Loader.load(Loader.java:417)
at org.bytedeco.javacpp.lept.<clinit>(lept.java:10)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at org.bytedeco.javacpp.Loader.load(Loader.java:472)
at org.bytedeco.javacpp.Loader.load(Loader.java:417)
at org.bytedeco.javacpp.tesseract$TessBaseAPI.<clinit>(tesseract.java:3648)
at om.practiceproblems.BasicTesseractExampleTest.givenTessBaseApi_whenImageOcrd_thenTextDisplayed(BasicTesseractExampleTest.java:35)
at com.practiceproblems.BasicTesseractExampleTest.main(BasicTesseractExampleTest.java:22)
Caused by: java.lang.UnsatisfiedLinkError: no liblept in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:702)
at org.bytedeco.javacpp.Loader.load(Loader.java:491)
... 9 more
在我的示例中,我使用 java-presets 库 tesseract-3.04.01-1.2 和 leptonica-1.73-1.2.jar 和 javacpp-1.2.1。我有 Windows 操作系统。 我确实看到了这个https://github.com/bytedeco/javacpp-presets/issues/46 以及关于 SO 和 github 的几个讨论,指出这个问题在 jacacpp-1.1 本身中得到了解决。但我使用的是 javacpp1.2。 对于解决问题或找到根本原因的任何帮助,我将不胜感激。
【问题讨论】:
按照这些说明,让我知道 Dependency Walker 所说的内容:github.com/bytedeco/javacpp-presets/wiki/… 感谢@SamuelAudet 的回复。我尝试了给定链接上列出的步骤。我在我的程序中使用了 Loader.load(tesseract.class)创建 TessBaseAPI 时出现异常,正如预期的那样,它会导致 UnsatisfiedLinkError .. 但我得到一个错误,依赖 walker 说“找不到 tempdirectorypath/jnitesseract.dll”。如前所述,我使用了 Loader.getTempDir( ) + "jnitesseract.dll" 但仍然有同样的错误。我也尝试了 java.library.path 即 Windows 中的 PATH 环境变量,但得到了同样的错误。你能再给我一些建议吗? 这仅仅意味着并非所有的 JAR 文件都在您的类路径中。请将所有 JAR 文件放在你的类路径中。 @SamuelAudet 非常感谢.. 我在 eclipse VM 参数中添加了编译所需的 jar,现在它可以工作了.. 虽然我在使用 eng 以外的语言时遇到了问题.. 我的 maven 安装说分叉的 VM 没有在 tessbaseapi.init 上正确告别就终止了。但我认为不会成为这个问题的一部分。再次感谢.. 如果您能给我指出一些与 tessdata 中的配置相关的文档,那也会很有帮助。 【参考方案1】:您可以克隆或下载项目:
https://github.com/bytedeco/javacpp-presets#the-cppbuildsh-scripts
然后构建模块:Tesseract 的 JavaCPP 预设和 Leptonica 的 JavaCPP 预设;
(要构建 leptonica 项目,您可能需要安装 nasm https://www.nasm.us/)
(要构建整个 javacpp-presets 项目,您还必须安装 cmake)
这将创建本机库:
libjnilept.so 和 libjnitesseract.so
那么你必须指定 jni.library.path
你可以这样做:
System.setProperty(JAVA_LIBRARY_PATH, tmpDirName);
/* Optionally add these two lines */
System.setProperty("jna.library.path", tmpDirName);
System.setProperty("jni.library.path", tmpDirName);
final Field fieldSysPath;
fieldSysPath = ClassLoader.class.getDeclaredField(SYS_PATHS);
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
(您可以改为在虚拟机选项上指定 -Djava.library.path=)
您只需要放置生成的文件: libjnilept.so 和 libjnitesseract.so 在某个文件夹中并将此路径设置为:jni.library.path
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>tesseract</artifactId>
<version>4.0.0-1.4.4</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>leptonica</artifactId>
<version>1.77.0-1.4.4</version>
</dependency>
你也可以尝试添加
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>leptonica-platform</artifactId>
<version>1.77.0-1.4.4</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>tesseract-platform</artifactId>
<version>4.0.0-1.4.4</version>
</dependency>
并在构建中添加一个 maven-assembly-plugin
<build>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<!-- new -->
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</build>
此外,您还可能收到如下错误:
sscanf(line, "%" QUOTED_TOKENSIZE "s %" QUOTED_TOKENSIZE "s %f %f",
linear_token, essential_token, &ParamDesc[i].Min, &ParamDesc[i].Max) == 4
:Error:Assert failed:in file clusttool.cpp, line 73
#
# A fatal error has been detected by the Java Runtime Environment:
由于 Tesseract 的语言环境要求,export LC_ALL=C 是必需的 在运行任何客户端程序之前。
所以:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<environmentVariables>
<LC_ALL>C</LC_ALL>
</environmentVariables>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath />
<argument>$classpath</argument>
</arguments>
</configuration>
</plugin>
来源: - https://github.com/nguyenq/tess4j/issues/106 - https://github.com/sirfz/tesserocr/issues/165
【讨论】:
在您的情况下,您可能只需要为 Leptonica 构建 JavaCPP 预设;但必须同时生成:libjnilept.so 和 libjnitesseract.so。 可能是真的。虽然这个项目有一个后果,我需要检查这个解决方案是否有效以上是关于获取 UnsatisfiedLinkError:创建 TessBaseAPI 时 java.library.path 中没有 jnilept的主要内容,如果未能解决你的问题,请参考以下文章
Android NDK:获取 java.lang.UnsatisfiedLinkError:dlopen 失败:找不到“libffmpeg.so”引用的符号“signal”
1Android Studio集成极光推送(Jpush) 报错 java.lang.UnsatisfiedLinkError: cn.jpush.android.service.PushProtoc