Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: Não foi possível encontrar o módulo especificado

Bom dia,

Preciso de um Help,

Dentro do meu projeto no Eclipse funciona normalmente, porém, quando jogo para um arquivo Jar e executo, aparece a seguinte mensagem de erro,
Estou utilizando o Tesseract, acho que o problema seja isso, o que poderá ser feito?

Exception in thread “AWT-EventQueue-0” java.lang.UnsatisfiedLinkError: Não foi p
ossível encontrar o módulo especificado.

    at com.sun.jna.Native.open(Native Method)
    at com.sun.jna.Native.open(Native.java:1759)
    at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:260)
    at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
    at com.sun.jna.Library$Handler.<init>(Library.java:147)
    at com.sun.jna.Native.loadLibrary(Native.java:412)
    at com.sun.jna.Native.loadLibrary(Native.java:391)
    at net.sourceforge.tess4j.util.LoadLibs.getTessAPIInstance(LoadLibs.java

:81)
at net.sourceforge.tess4j.TessAPI.(TessAPI.java:42)
at net.sourceforge.tess4j.Tesseract.init(Tesseract.java:379)
at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:292)
at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:224)
at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:208)
at agassys.teste.getOcr(teste.java:3485)
at agassys.teste$18.actionPerformed(teste.java:2248)
at javax.swing.JComboBox.fireActionEvent(Unknown Source)
at javax.swing.JComboBox.contentsChanged(Unknown Source)
at javax.swing.AbstractListModel.fireContentsChanged(Unknown Source)
at javax.swing.DefaultComboBoxModel.setSelectedItem(Unknown Source)
at javax.swing.DefaultComboBoxModel.addElement(Unknown Source)
at javax.swing.JComboBox.addItem(Unknown Source)
at agassys.Abrir_Projeto$4.actionPerformed(Abrir_Projeto.java:234)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour
ce)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
rivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
rivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
rivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Está faltando a biblioteca nativa dessa API (.dll no Windows ou .so em Linux)

No caso no projeto tenho a libtesseract3051.dll, devo colocar no Windows?

Quando executo o programa verifique que ele cria no diretório
Devo trocar o diretório em alguma class Tesseract?

C:\Users\Suporte\AppData\Local\Temp\tess4j\win32-x86

Os arquivos
liblept1744.dll
libtesseract400.dll
libtesseract3051.dll

vc tem que colocar as dlls onde o seu sistema operacional usa. No windows n lembro, mas no Linux é na pasta libs.

Deve ser Arquivos de Programas ou algo assim por aí.

Tentei colocar no diretório

C:\Windows\System32

porém ocorre o mesmo erro,

O estranho é que no Eclipse ele funciona normalmente,
Quando exporto ele para Runnable JAR File, e transformo ele em um arquivo, ele começa a dar esse erro

image

Em princípio só tens que passar como argumento para a máquina virtual a propriedade java.library.path apontando para o diretório onde sua DLL se encontra.

Não porque não é o sistema operacional quem vai utilizar, é a aplicação dele.
É só setar a propriedade java.library.path apontando o diretório onde estão as DLLs que a aplicação dele depende.

1 curtida

Então terei que usar isso?

System.setProperty(“java.library.path”, “C://Users//Suporte//AppData//Local//Temp//tess4j//win32-x86”);

Que eu saiba o java.library.path tem que ser setado como parâmetro da máquina virtual, usando a opção -D
Não sei se vai surtir efeito usando System.setProperty

Entendo, então é só colocar então dentro dessa opção

image

Pelo o Eclipse
C:\Users\Suporte\AppData\Local\Temp\tess4j\win32-x86;
C:\Users\Suporte\Desktop

Pelo o Arquivo Jar
C:\Program Files\Common Files\Oracle\Java\javapath;
C:\Windows\Sun\Java\bin;
C:\Windows\system32;C:\Windows;
C:\Program Files\Common Files\Oracle\Java\javapath;
C:\Program Files\Common Files\Business Objects\3.0\bin\NOTES;
C:\Program Files\Common Files\Business Objects\3.0\bin\NOTES\DATA;
C:\Windows\system32;
C:\Windows;
C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0;
C:\Program Files\Skype\Phone;
C:\Program Files\Java\jdk1.8.0_181\bin;
C:\Users\Suporte\AppData\Local\Temp\tess4j\win32-x86;.

Só que dessa forma só vai funcionar em tempo de desenvolvimento, quando você gerar seu JAR e rodar fora da IDE, já era.

O certo é você setar como parâmetro da máquina virtual usando a opção

-Djava.library.path=<sua pasta>

As propriedades de sistema são guardadas em cache pelo Java, por isso não tem efeito você setar através da linha abaixo:

System.setProperty("java.library.path", "C://Users//Suporte//AppData//Local//Temp//tess4j//win32-x86");

Mas, se você for teimosinho e insistir em não utilizar o -D, dá pra dar uma “hackeada” e colocar o seguinte bloco estático na sua classe com método main:

static {
    try {
        System.setProperty("java.library.path", "C://Users//Suporte//AppData//Local//Temp//tess4j//win32-x86");
        Field sys_paths = ClassLoader.class.getDeclaredField("sys_paths");
        sys_paths.setAccessible(true);
        sys_paths.set(null, null);
    } catch (Exception e) {
        throw new ExceptionInInitializerError(e);
    }
}

Esse código seta o atributo sys_paths do ClassLoader pra null, fazendo com que ele seja reinicializado.
Quando ele for reinicializado, ele vai ler a propriedade que você setou com o System.setProperty.
Mas não é legal fazer isso pois:

  • vai diretamente contra o conceito de encapsulamento, já que estamos modificando um atributo private do ClassLoader;
  • por ser um atributo private do ClassLoader, amanhã ou depois a Oracle pode mudar a implementação e seu código vai deixar de funcionar.

No MANIFEST.MF não se seta o java.library.path nem se põe caminhos absolutos.

Não sei se é dessa maneira que deve ser feito,

Estou tentado colocar conforme passado, mas o CMD não reconhece como um comando para setar na maquina virtual, acho que estou realizando algo errado
image

Um código simples que Funciona no IDE e não funciona depois de transformado em JAR

package agassys;

import java.io.File;
import net.sourceforge.tess4j.*;

public class TesseractExample {
public static void main(String[] args) {
// System.setProperty(“jna.library.path”, “32”.equals(System.getProperty(“sun.arch.data.model”)) ? “lib/win32-x86” : “lib/win32-x86-64”);

    File imageFile = new File("C://Users//Suporte//Desktop//Project//img//Ocr.png");
    ITesseract instance = new Tesseract();  // JNA Interface Mapping
    // ITesseract instance = new Tesseract1(); // JNA Direct Mapping
    // File tessDataFolder = LoadLibs.extractTessResources("tessdata"); // Maven build bundles English data
    // instance.setDatapath(tessDataFolder.getPath());

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

}

testei em outras maquinas e está funcionando normalmente,
Então o problema está na maquina, não faço a minima ideia de como reparar isso

É que você não está passando qual classe quer que o Java execute.

Não precisa registrar as dlls?

No caso minha DLL está localizado no diretorio: “C://Users//Suporte//AppData//Local//Temp//tess4j//win32-x86”

E meu Arquivo no Diretorio:
C:\Users\Suporte\Desktop\Projeto\Projeto.jar

Como devo colocar no CMD?

Eu deixaria o diretório tess4j no mesmo diretório onde está o seu arquivo .jar, isso facilita a distribuição.

java -Djava.library.path=<pasta onde está a dll> -jar <seu arquivo .jar>