Exceção com JNA

26 respostas
Reilander

Olá

antes de conhecer o jna, usava o jni para a comunicacao
com dlls de impressoras fiscais.
era um parto!!
qnd soube do jna, e o testei, achei que solucionaria todos os meus problemas.
sem codigo em C, sem jni, metodos nativos, bla bla bla
mas sempre que a uso com essas dlls da erro de violacao de acesso
VIOLATION ACCESS EXCEPTION
fui pesquisar, e vi no home do projeto que em 90% desses casos,
desse tipo de erro, o problema ta em ponteiros nulos.
mas ai eu me faco alguns comentarios:

  • eh uma dll proprietaria, dificilmente teria esse tipo de erro
  • e mesmo que tivesse, porque a mesma dll funciona em jni e nao em jna?

galera, por favor, postem qualquer coisa, porque eu to querendo muito
usar o jna, eh um mao na roda… a mao nao, o braco todo na roda,
e agilizaria meu trabalho em 60, 70%

flw

26 Respostas

Reilander

e aeh pessoal, alguma coisa?

Reilander

alguem com alguma sugestao?

Reilander

pelo menos alguem tem algum link de apoio?

Reilander

alguem usa jna??

Paulo_Silveira

DLLs proprietarias, em especial de pequenos dispotivos de determinada fabricante, costumam ter muitos bugs. Mas nao acho que esse seja o caso.

Voce tem certeza que o codigo que esta chamando via JNI é o mesmo via JNA? Eu aposto mesmo que o problema aí é algum valor que voce esta passando pro seu stub JNA que está null. Em outras palavras, voce esta passando null, e a DLL nem verifica e sai acessando a memoria. Logue cada invocacao e seus parametros, ou debug e veja cada valor de parametro.

Reilander, voce precisa esperar mais de que algumas horas para que o pessoal do GUJ acabe vendo seu post, e alguem que conheca o seu problema possa responder. Tenha um pouco mais de paciencia nesses casos. Voce chegou a postar uma mensagem DEZ minutos depois da primeira.

Luca

Olá

Este foi exatamente o motivo porque me recusei a responder. Até se fosse meu chefe acharia ruim.

[]s
Luca

Reilander

iii galera, foi malzzz…
mas eh que qnd vejo tópicos como “problema de faculdade”,
“lista de exercicios”, sendo respondido mais de 20x fico chateado…
o cara provavelmente nunca mais vai fazer uma linha de codigo em Java,
mas passou no semestre…

bom, vou verificar aqui de novo entao, e validar os parametros…
vlw de qlq forma.

mais uma vez, foi malzz pela insistencia…

Reilander

Bom Paulo, nao consegui colocar pra funcionar...

o jeito eh postar o codigo aqui...

public class MainJNA {
	public interface JNA extends StdCallLibrary {
		JNA INSTANCE = (JNA)Native.loadLibrary("DLLG2", JNA.class);
		
		long DLLG2_IniciaDriver(String porta, char paridade);
		long DLLG2_EncerraDriver(long handle);
		long DLLG2_ConfiguraDriver(long handle, long speed);
		void DLLG2_DefineTimeout(long handle, long timeout);
		long DLLG2_ExecutaComando(long handle, String comando);
	}

	public static void main(String[] args) {
		JNA jna = JNA.INSTANCE;
		long handle = 0L;
		try {
			handle = jna.DLLG2_IniciaDriver("COM1", 'N');
			jna.DLLG2_ConfiguraDriver(handle, 9600L);
			jna.DLLG2_DefineTimeout(handle, 10L);
			jna.DLLG2_ExecutaComando(handle, "EmiteLeituraX");
		}
		catch(Exception e) {
			e.printStackTrace();
		} finally {
			jna.DLLG2_EncerraDriver(handle);
		}
	}
}

exatamente nesta linha:

jna.DLLG2_ExecutaComando(handle, "EmiteLeituraX");

ocorre o problema:

# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x02f593b4, pid=2784, tid=3984
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0-b105 mixed mode, sharing)
# Problematic frame:
# C [DLLG2.dll+0x593b4]
#
# An error report file with more information is saved as hs_err_pid2784.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#

esses metodos mapeados, sao os mesmo que uso com jni e nao ocorre erro algum.
a dll em questao, a "DLLG2.dll", com jni, todos os metodos funcionam!
se tiverem alguma sugestao, agradeco

T

DLLG2.dll + 0x593b4 - se o cara que escreveu a DLL tiver boa vontade, talvez até seja possível determinar onde é que a DLL está abortando o programa Java (esse erro que você tomou costuma ser devido a algum parâmetro que é um ponteiro nulo para o programa C).
Você consegue explicar isso pro cara que escreveu a DLL?
(Se possível, solicite a versão de depuração da DLL (juntamente com o arquivo .pdb) , e então tente rodar seu programa. Provavelmente vai ocorrer uma de duas coisas:

  • Ou vai dar o mesmo erro, em um endereço um pouco diferente, mas como o arquivo .PDB está disponível talvez seja possível determinar em que linha do programa C/C++ houve o problema, ou
  • Pode ser que simplesmente passe a funcionar (já vi cada coisa nesse mundo…)
Reilander

SOLUÇÃO!!!

Era preciso executar com o seguinte argumento:

-Xcheck:jni

ai, quando se executa, aparece a seguinte mensagem de inicio:

Java HotSpot™ Client VM warning: Floating point control word changed by native JNI code.

so isso, depois tudo funciona blz!

vlw, e desculpa pela nesima vez pela insistencia.

T

Isso quer dizer uma só coisa - essa DLL foi escrita em Delphi ou C++ Builder, não?

Reilander

caaaara, vc eh o cara!

isso mesmo, C++ builder, segundo a documentacao dela.

mas… porque deu pra inferir isso?

Paulo_Silveira

Reilander:
caaaara, vc eh o cara!

isso mesmo, C++ builder, segundo a documentacao dela.

mas… porque deu pra inferir isso?

Eu so nao me espanto porque foi o thingol!! :slight_smile:

Mas me explica uma coisa, porque só usar essa opcao fez tudo funcionar direito? O codigo invocado nem passa nenhum numero com ponto flutuante!!!

T

a) Essa história de “floating point control word” é algo que distingue o Microsoft C++ das linguagens da Codegear (Delphi ou C++ Builder). Se você escrever código nativo que de alguma forma chama (direta ou indiretamente) as bibliotecas de ponto-flutuante vai acabar se deparando com esse problema.
b) Não sabia que “check:jni” olhava o estado desse flag (também chamado de FCW), e o corrigia. Acho que só olhando o fonte em C/C++ do JDK. Provavelmente é necessário achar “_controlfp” ou “_control87” nesses fontes.
c) Isso deve ser reportado para o pessoal que mantém o JNA. Seria interessante a DLL JNI que implementa o JNA chamar _controlfp (ou _statusfp e _clearfp) antes e depois de chamar o código nativo da tal DLL.

Reilander

a opcap -Xint tb funciona, e sem essa msg de aviso

T

-Xint deixa seu programa lento igual a uma carroça porque desabilita o Just-in-time compiler. Prefira usar então o -Xcheck:jni.

Reilander

solicitacao acatada!

mas deixa lento pq?

Reilander

sugestao acatada!

mas deixa lento pq?

T

Como você deve saber, o Java é interpretado até certo ponto, quando entra em cena o Just-in-time Compiler, que transforma os bytecodes em linguagem de máquina. Isso faz com que certos programas Java possam até ser tão ou mais rápidos que programas equivalentes em C++.
Se você passar essa opção -Xint, o JIT Compiler é desabilitado e tudo que o Java fizer será apenas interpretado. Dependendo do tipo de programa Java que você for rodar, ele vai ficar horrivelmente lento.

Reilander

respondido, vlw

agora, mais um alerta a quem for usar o jpa:
atencao com os tipos!

na dll que estou usando, tem-se os metodos retornando e recebendo
inteiros, de 32bits.
pra evitar qlq dores de cabeca, usei long.
o programa nao rodou.
o mapeamento tem de ser fiel, deve-se seguir à risca o mapeamento
sugerido na propria home do jna.

https://jna.dev.java.net/

vlw

F

Reilander:
SOLUÇÃO!!!

Era preciso executar com o seguinte argumento:

-Xcheck:jni

ai, quando se executa, aparece a seguinte mensagem de inicio:

Java HotSpot™ Client VM warning: Floating point control word changed by native JNI code.

so isso, depois tudo funciona blz!

vlw, e desculpa pela nesima vez pela insistencia.

Reilander,

Estou passando pelo mesmo problema que vc, só que a dll em questão foi desenvolvida no Visual Studio 2008. Como vc executou o comando -Xcheck:jni?

Obrigado.

Reilander

java -Xcheck:jni NomeDaClasse

aqui uma lista com outros parâmetros que você pode passar
http://blogs.sun.com/watt/resource/jvm-options-list.html

Z

Boa tarde pessoal. Uma dúvida, espero que a mesma seja simples.

Como eu represento isso em JNA: void **variavel.
Preciso desse ponteiro duplo, que consta na lista de parametros do metodo de minha DLL.
Olhei o site do JNA e tem o tipo equivalente Pointer, para o tipo void *. Como eu faço para ter:
void **variavel.

Muito obrigado e ate mais.

Z

Só para complementar, eis a assinatura do meu método:

int Initialize_HL(PCHAR BoardID, void **hDev);
Lembrando que a DLL que tenho acesso é proprietária.
E gostaria de saber como fica a assinatura deste método utilizando JNA.

Muito obrigado e até mais!

thiagotrss

Aoo irmãozim.

Como voce conseguiu fazer funcionar com esse argumento ??
Eu estou usando a DLLG2.dll para acessar uma dataregis mas mesmo
com o argumento Xcheck:jni está dando problema.
Não consegui fazer o acesso à impressora de forma alguma.

Alguma ideia ?

J

zehjava:
Só para complementar, eis a assinatura do meu método:

int Initialize_HL(PCHAR BoardID, void **hDev);
Lembrando que a DLL que tenho acesso é proprietária.
E gostaria de saber como fica a assinatura deste método utilizando JNA.

Muito obrigado e até mais!

(void**) é um ponteiro para um ponteiro,
equivalente a out no objectpascal,
jna é Um Pointer de um Pointer.

Criado 16 de abril de 2008
Ultima resposta 11 de fev. de 2010
Respostas 26
Participantes 8