Para System.loadLibrary()
funcionar, a biblioteca (no Windows, uma DLL) deve estar em um diretório em algum lugar do seu PATH
ou em um caminho listado na java.library.path
propriedade do sistema (para que você possa iniciar o Java como java -Djava.library.path=/path/to/dir
).
Além disso, para loadLibrary()
, você especifica o nome base da biblioteca, sem o .dll
no final. Então, para /path/to/something.dll
, você apenas usaria System.loadLibrary("something")
.
Você também precisa olhar exatamente o UnsatisfiedLinkError
que está obtendo. Se disser algo como:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
então ele não consegue encontrar a biblioteca foo (foo.dll) em seu PATH
ou java.library.path
. Se disser algo como:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
então, algo está errado com a própria biblioteca no sentido de que o Java não é capaz de mapear uma função Java nativa em seu aplicativo para sua contraparte nativa real.
Para começar, eu colocaria algum registro em torno de sua System.loadLibrary()
chamada para ver se ela é executada corretamente. Se ele lançar uma exceção ou não estiver em um caminho de código que é realmente executado, você sempre obterá o último tipo UnsatisfiedLinkError
explicado acima.
Como nota lateral, a maioria das pessoas coloca suas loadLibrary()
chamadas em um bloco inicializador estático na classe com os métodos nativos, para garantir que ele seja sempre executado exatamente uma vez:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
loadLibrary()
comentários - muito útil quando você não tem ideia do que está fazendo de errado.lib
prefixo. EntãoSystem.loadLibrary("foo")
precisalibfoo.so
.Alterar a variável 'java.library.path' no tempo de execução não é suficiente porque ela é lida apenas uma vez pela JVM. Você deve redefini-lo como:
Por favor, faça uma recompensa em: Changing Java Library Path at Runtime .
fonte
A resposta original de Adam Batkin levará você a uma solução, mas se você reimplantar seu webapp (sem reiniciar seu contêiner da web), deverá ocorrer o seguinte erro:
Isso acontece porque o ClassLoader que carregou originalmente sua DLL ainda faz referência a essa DLL. No entanto, seu webapp agora está sendo executado com um novo ClassLoader e, como a mesma JVM está em execução e uma JVM não permite 2 referências à mesma DLL, você não pode recarregá- la. Portanto, seu webapp não pode acessar a DLL existente e não pode carregar uma nova. Então .... você está preso.
Documentação do ClassLoader do Tomcat descreve por que seu webapp recarregado é executado em um novo ClassLoader isolado e como você pode contornar essa limitação (em um nível muito alto).
A solução é estender um pouco a solução de Adam Batkin:
Em seguida, coloque um jar contendo APENAS esta classe compilada na pasta TOMCAT_HOME / lib.
Agora, dentro do seu webapp, você só precisa forçar o Tomcat a fazer referência a essa classe, o que pode ser feito da seguinte maneira:
Agora sua DLL deve ser carregada no carregador de classe comum e pode ser referenciada a partir de seu webapp mesmo depois de ser reimplantada.
Faz sentido?
Uma cópia de referência de trabalho pode ser encontrada no código do google, static-dll-bootstrapper .
fonte
Você pode usar
System.load()
para fornecer um caminho absoluto que é o que você deseja, em vez de um arquivo na pasta da biblioteca padrão para o respectivo sistema operacional.Se você quiser aplicativos nativos que já existem, use
System.loadLibrary(String filename)
. Se você deseja fornecer o seu, provavelmente é melhor usar load ().Você também deve ser capaz de usar
loadLibrary
ojava.library.path
conjunto corretamente. VejaClassLoader.java
para fonte de implementação mostrando ambos os caminhos sendo verificados (OpenJDK)fonte
No caso em que o problema é que System.loadLibrary não consegue encontrar a DLL em questão, um equívoco comum (reforçado pela mensagem de erro do Java) é que a propriedade de sistema java.library.path é a resposta. Se você definir a propriedade de sistema java.library.path para o diretório onde sua DLL está localizada, então System.loadLibrary realmente encontrará sua DLL. No entanto, se sua DLL, por sua vez, depender de outras DLLs, como costuma ser o caso, java.library.path não pode ajudar, porque o carregamento das DLLs dependentes é gerenciado inteiramente pelo sistema operacional, que nada sabe sobre java.library. caminho. Portanto, é quase sempre melhor ignorar java.library.path e simplesmente adicionar o diretório da DLL a LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS) ou Path (Windows) antes de iniciar a JVM.
(Observação: estou usando o termo "DLL" no sentido genérico de DLL ou biblioteca compartilhada.)
fonte
Se você precisa carregar um arquivo relativo a algum diretório onde você já está (como no diretório atual), aqui está uma solução fácil:
fonte
Para quem procura
java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
Eu estava enfrentando a mesma exceção; Tentei de tudo e coisas importantes para fazer funcionar são:
Funcionou com o tomcat 6.
fonte
Se você acredita que adicionou um caminho de lib nativo para
%PATH%
, tente testar com:Deve mostrar se a dll está ativada
%PATH%
%PATH%
fonte
Pobre de mim! passou um dia inteiro atrás disso. Escrevendo aqui embaixo se algum corpo replica esse problema.
Eu estava tentando carregar como Adam sugeriu, mas fui pego com a exceção AMD64 vs IA 32. Se em qualquer caso, depois de trabalhar de acordo com o passo a passo de Adam (sem dúvida a melhor escolha), tente ter uma versão de 64 bits do jre mais recente. Certifique-se de seu JRE E JDK são de 64 bits e você os adicionou corretamente ao seu classpath.
Meu exemplo de trabalho vai aqui: erro de link não satisfeito
fonte
Para o Windows, descobri que quando carreguei os filles (jd2xsx.dll chama & ftd2xx.dll) na pasta windowws / system32 isso resolveu os problemas. Então, tive um problema com meu fd2xx.dll mais recente relacionado a parâmetros, por isso tive que carregar a versão mais antiga dessa dll. Terei que descobrir isso mais tarde.
Observação: o jd2xsx.dll chama o ftd2xx.dll, portanto, apenas definir o caminho para o jd2xx.dll pode não funcionar.
fonte
Estou usando Mac OS X Yosemite e Netbeans 8.02, obtive o mesmo erro e a solução simples que encontrei é como a acima, isso é útil quando você precisa incluir biblioteca nativa no projeto. Então, faça o próximo para o Netbeans:
Espero que possa ser útil para alguém. O link onde encontrei a solução está aqui: java.library.path - O que é e como usar
fonte
VM Options: java -Djava.library.path="your_path"
Eu tive o mesmo problema e o erro foi devido a uma renomeação da dll. Pode acontecer que o nome da biblioteca também esteja escrito em algum lugar dentro da dll. Quando coloquei de volta o nome original, consegui carregar usando
System.loadLibrary
fonte
É simples, basta escrever java -XshowSettings: properties na linha de comando do Windows e colar todos os arquivos no caminho mostrado por java.library.path.
fonte