NoSuchFieldError:RESOURCE_PREFIX,带有使用tess4j的maven项目

时间:2015-02-03 20:18:35

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

tess4j是一个用本机库打包的OCR,我做了一个maven项目来测试它, 我确实添加了maven的安装路径到eclipse。 我添加了M2_HOME,MAVEN_HOME和JAVA_HOME env变量,

这是我的父母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我的插件是插件管理标签,我想我应该把它们放在构建标签之间,不是吗?

有什么想法吗?

感谢。

4 个答案:

答案 0 :(得分:1)

有2个问题

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错误来自

32位版本的pom.xml(你需要安装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>

答案 1 :(得分:1)

可以轻松构建子pom而没有任何问题并手动复制libs,这与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());
    }

那就是它!

答案 2 :(得分:1)

问题是由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>    

答案 3 :(得分:0)

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