NoSuchFieldError: RESOURCE_PREFIX с проектом maven, использующим tess4j

Tess4j - это OCR, заполненный собственной библиотекой, я сделал проект maven для его тестирования, я добавил путь установки maven в eclipse. Я добавил переменную M2_HOME, MAVEN_HOME и JAVA_HOME,

вот мой родительский пом

<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>

а вот мой ребенок пом

<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) заставит их работать.

Также в родительском помете мой плагин содержит теги управления плагином, я думаю, что я должен был поставить их между тегами сборки, не так ли?

Любая идея?

Благодарю.

4 ответа

Проблема вызвана конфликтом между net.java.dev.jna:jna и com.sun.jna:jna. Обе банки содержат класс 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>    

Дочерний помпон может быть легко собран без каких-либо проблем и ручного копирования библиотек, это не связано с 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/ некоторые dll и файлы из tess4j пришлось скопировать в корневой каталог проекта

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), которая позаботится об этих двух вещах, замените win32-x86 на win32-x86-64, если вы хотите использовать это в 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 не соответствует. вы используете более одной версии в библиотеке путей к классам. просто используйте одну версию JNA.

Другие вопросы по тегам