【问题标题】:NoSuchFieldError: RESOURCE_PREFIX with a maven project using tess4jNoSuchFieldError: RESOURCE_PREFIX 与使用 tess4j 的 maven 项目
【发布时间】:2015-08-04 14:10:04
【问题描述】:

tess4j 是一个包含原生库的 OCR,我做了一个 maven 项目来测试它, 我确实在eclipse中添加了maven的安装路径。 我添加了 M2_HOME、MAVEN_HOME 和 JAVA_HOME 环境变量,

这是我的父母 pom

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>fr.mssb.ongoing</groupId>
    <artifactId>ongoing-parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0</version>
    <name>ongoing</name>

    <modules>
        <module>capcha-solver</module>
    </modules>

    <build>
        <pluginManagement>
            <plugins>
                <!-- All project will be interpreted (source) and compiled (target) in java 7 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                    </configuration>
                </plugin>
                <!-- this will make eclipse:eclipse goal work and make the project Eclipse compatible -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-eclipse-plugin</artifactId>
                    <version>2.5.1</version>
                    <configuration>
                        <downloadSources>true</downloadSources>
                        <downloadJavadocs>true</downloadJavadocs>
                        <classpathContainers>
                            <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7</classpathContainer>
                        </classpathContainers>
                        <additionalBuildcommands>
                            <buildcommand>net.sf.eclipsecs.core.CheckstyleBuilder</buildcommand>
                        </additionalBuildcommands>
                        <additionalProjectnatures>
                            <projectnature>net.sf.eclipsecs.core.CheckstyleNature</projectnature>
                        </additionalProjectnatures>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <!-- All child pom will inherit those dependancies -->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

这是我的孩子 pom

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>fr.mssb.ongoing</groupId>
        <artifactId>ongoing-parent</artifactId>
        <version>1.0</version>
    </parent>

    <groupId>fr.mssb.ongoing</groupId>
    <artifactId>capcha-solver</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging> <!-- I think this is useless -->

    <name>A capcha solver based on terassec ocr</name>

    <build>
        <plugins>
            <!-- autorun unit tests during maven compilation -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <argLine>-Xmx1024m -XX:MaxPermSize=256m -XX:-UseSplitVerifier</argLine>
                    <skipTests>-DskipTests</skipTests>
                </configuration>
            </plugin>

            <!--  this should make the tesseract ocr native dll work without doing anything -->
            <plugin>
                <groupId>com.googlecode.mavennatives</groupId>
                <artifactId>maven-nativedependencies-plugin</artifactId>
                <version>0.0.7</version>
                <executions>
                    <execution>
                        <id>unpacknatives</id>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- 
        Log4j 2 is broken up in an API and an implementation (core), where the API 
        provides the interface that applications should code to. Strictly speaking 
        Log4j core is only needed at runtime and not at compile time.
        However, below we list Log4j core as a compile time dependency to improve 
        the startup time for custom plugins. 
        -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.1</version>
        </dependency>
        <!--
        Integration of tesseract OCR
        -->
        <dependency>
            <groupId>net.sourceforge.tess4j</groupId>
            <artifactId>tess4j</artifactId>
            <version>1.4.1</version>
        </dependency>
    </dependencies>

</project>

当然还有代码(取自 tess4j 示例)

package test;

import java.io.File;

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

/**
 * Classe d'exemple.
 */
public class TesseractExample {

    public static void main(String[] args) {
        File imageFile = new File("C:\\DEV\\repo\\ongoing\\capcha-solver\\src\\test\\resources\\random.jpg");
        Tesseract instance = Tesseract.getInstance();  // JNA Interface Mapping
        // Tesseract1 instance = new Tesseract1(); // JNA Direct Mapping

        try {
            String result = instance.doOCR(imageFile);
            System.out.println(result);
        } catch (TesseractException e) {
            System.err.println(e.getMessage());
        }
    }
}

当我启动它时,我得到了这个异常

Exception in thread "main" java.lang.NoSuchFieldError: RESOURCE_PREFIX
    at net.sourceforge.tess4j.util.LoadLibs.<clinit>(LoadLibs.java:60)
    at net.sourceforge.tess4j.TessAPI.<clinit>(TessAPI.java:40)
    at net.sourceforge.tess4j.Tesseract.init(Tesseract.java:303)
    at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:239)
    at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:188)
    at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:172)
    at test.TesseractExample.main(TesseractExample.java:19)

我不知道这是否与 tess4j 相关或 JNA/JNI 问题,如您所见,我有一个插件“应该”(以前从未与 DLL 一起使用)使其工作。

同样在父 pom 中,我的插件位于插件管理标签之间,我想我应该将它们放在构建标签之间,不是吗?

有什么想法吗?

谢谢。

【问题讨论】:

  • 可能是 JNA 版本不匹配。尝试使用 -Djna.nosys=True 运行以避免无意中选择了安装在系统上的(旧)版本的 JNA。
  • 不,不会改变任何东西
  • RESOURCE_PREFIX 是 JNA 常量。你安装了吗?
  • 是的,我已经安装了 VS2013 visual c++ redistribuable,如下所示:tess4j.sourceforge.net/usage.html
  • 你需要添加 jna 4.1.0 依赖。

标签: maven java-native-interface tesseract jna tess4j


【解决方案1】:

有两个问题

1/ 必须将 tess4j 中的一些 dll 和文件复制到项目根目录

2/ tess4j 对 com.sun.jna:jna:jar:3.0.9 具有传递依赖性,与 net.java.dev.jna:jna:jar:4.1.0(也来自 tess4j)冲突,排除了 3.0。 9 版本使一切正常,RESSOURCE_PREFIX 错误来自那个

pom.xml 用于 32 位版本(您需要安装 32 位 JVM),它负责这两件事,如果您想在 64 位中使用它,请将 win32-x86 更改为 win32-x86-64

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>fr.mssb.ocr</groupId>
    <artifactId>tesseractOcr</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <name>tesseract ocr project</name>

    <build>
        <plugins>
            <!--  
            this extract the 32 bits dll and the tesseractdata folder to 
            the project root from tess4j.jar  
            -->
            <plugin>
                <groupId>org.apache.portals.jetspeed-2</groupId>
                <artifactId>jetspeed-unpack-maven-plugin</artifactId>
                <version>2.2.2</version>
                <dependencies>
                    <dependency>
                      <groupId>net.sourceforge.tess4j</groupId>
                      <artifactId>tess4j</artifactId>
                      <version>1.4.1</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <id>unpack-step</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                        <configuration>
                            <unpack>
                                <artifact>net.sourceforge.tess4j:tess4j:jar</artifact>
                                <overwrite>true</overwrite>
                                <resources combine.children="append">
                                    <resource>
                                        <path>win32-x86</path>
                                        <destination>../</destination>
                                        <overwrite>true</overwrite>
                                        <flat>true</flat>
                                        <include>*</include>
                                    </resource>
                                    <resource>
                                        <path>tessdata</path>
                                        <destination>../tessdata</destination>
                                        <overwrite>true</overwrite>
                                        <flat>true</flat>
                                        <include>*</include>
                                    </resource>
                                    <resource>
                                        <path>tessdata/configs</path>
                                        <destination>../tessdata/configs</destination>
                                        <overwrite>true</overwrite>
                                        <flat>true</flat>
                                        <include>*</include>
                                    </resource>
                                </resources>
                            </unpack>
                            <verbose>true</verbose>
                        </configuration>
                        </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>net.sourceforge.tess4j</groupId>
            <artifactId>tess4j</artifactId>
            <version>1.4.1</version>
              <exclusions>
                <exclusion>
                    <groupId>com.sun.jna</groupId>
                    <artifactId>jna</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

【讨论】:

  • 我必须说,删除 jna 3.0.9 版本似乎不会影响项目,但我仍然认为你的项目设置不正确:你不应该设置你的 maven 项目对非 maven 项目使用 tess4j howto - 您必须手动复制 dll(tess4j 1.4.1 maven 版本不是这种情况)
  • 恕我直言,这是您所做的错误假设。不必像您那样复制文件。 tess4j 项目正在处理它,请提供证明或项目示例,你。
  • @sliders_alpha,我偶然发现了完全相同的问题,并使用了您提供的解决方案。有人知道提高 OCR 准确性的方法吗?我只有想要提取的图像中存在的数字。
【解决方案2】:

子 pom 可以轻松构建而没有任何问题,并且可以手动复制库,这与 TESS4J 无关。 无论如何,如果不再需要,可以删除 jna 3.0.9:https://github.com/nguyenq/tess4j/issues/8

不过,运行 tess4j 所需要做的只是 maven 依赖项:

<dependency>
    <groupId>net.sourceforge.tess4j</groupId>
    <artifactId>tess4j</artifactId>
    <version>1.4.1</version>
</dependency>

以及正确使用TESS4J-API,例如:

File imageFile = new File("C:\\random.png");
Tesseract instance = Tesseract.getInstance();

//In case you don't have your own tessdata, let it also be extracted for you
File tessDataFolder = LoadLibs.extractTessResources("tessdata");

//Set the tessdata path
instance.setDatapath(tessDataFolder.getAbsolutePath());

    try {
        String result = instance.doOCR(imageFile);
        System.out.println(result);
    } catch (TesseractException e) {
        System.err.println(e.getMessage());
    }

就是这样!

【讨论】:

    【解决方案3】:

    问题是由net.java.dev.jna:jna 和com.sun.jna:jna 冲突引起的。两个 jar 都包含一个类 com.sun.jna.Platform。两个 jar 都被声明为 tess4j 依赖项。要解决这个问题,您可以在 pom 中省略第二个依赖项:

    <dependency>
        <groupId>net.sourceforge.tess4j</groupId>
        <artifactId>tess4j</artifactId>
        <version>1.4.1</version>
        <exclusions>
            <exclusion>
                <groupId>com.sun.jna</groupId>
                <artifactId>jna</artifactId>
            </exclusion>
        </exclusions>
    </dependency>    
    

    【讨论】:

      【解决方案4】:

      因为 JNA 版本不匹配。您在类路径库中使用了多个版本。只需使用一个版本的 JNA。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-12
        • 1970-01-01
        • 1970-01-01
        • 2012-12-02
        • 2023-01-27
        相关资源
        最近更新 更多