JNA problema estranho

11 respostas
S

Olá a todos,

Estou como seguinte problema:

Em minha aplicação utilizo jna para consultar e executar um método específico de uma dll. Esta funcionando OK em todos os meus clientes, porém em 1 deles esta funcionando, mas o calculo esta retornando valores absurdos, após fazer alguns testes ainda não consegui encontrar onde pode estar o problema. E o pior foi que do meu fonte apontei par ao banco em produção deste cliente e os valores retornaram corretamente. A única diferença que vejo é que o sistema operacional deste cliente esta em inglês ( Windows ) porém as configurações regionais esta toda setada para Brasil.

Oque vocês acham que pode estar ocorrendo este erro de cálculo.

Muito obrigado

Abraço

Fernando Sciuba

11 Respostas

S

up

R

Sem ver o código fica dificil né brother…

E

Dá a impressão, pela sua descrição, que o erro de cálculo ocorre dentro dessa DLL. Se você não tiver o fonte dessa DLL fica difícil dizer se é isso mesmo :frowning:

S

Segue fonte de chamada da DLL

/**
     * Classe interface onde serão declarados os métodos contidos na dll Tenha o
     * cuidado de lembrar que, diferente do Delphi, Java é case sensitive.
     */
    public interface DLL extends Library {

        public String CalcularMediaParcial(String caminho,
                String GUID, int idEmpresa, int idGrupoEmpresa, int idUsuario, int idPeriodoLetivo,
                int idCurso, int idCiclo, int idSerie, int idFaseCalendario, int idProfessor, int idDisciplina,
                int idTurma);

        public void LiberarRecursos();
    }

    /**
     * Método que tentará encontrar a dll.
     */
    public static DLL loadAdMediaParcialDLL() {
       
        try {
            //Tenta carregar a DLL em c:\windows\system32
            return (DLL) Native.loadLibrary("AdMediaParcial.dll", DLL.class);
        } catch (UnsatisfiedLinkError e) {
            
                logger.error("AdMediaParcial.dll Não Encontrada!" + ex);
                return null;
            
        }
    }

    public synchronized String execAdMediaParcialDLL(String caminho,
            String GUID, int idEmpresa, int idGrupoEmpresa, int idUsuario, int idPeriodoLetivo,
            int idCurso, int idCiclo, int idSerie, int idFaseCalendario, int idProfessor, int idDisciplina,
            int idTurma) {

       
        String retorno = "";

        try {
            if (consultaDll == null) {
                //System.out.println("[CentralApontamentoNotas] manda carregar a dll");
                consultaDll = loadAdMediaParcialDLL();
            }

            if (consultaDll != null) {
            
            //Aqui é que obtenho o retorno do calculo em uma String 
                  retorno = consultaDll.CalcularMediaParcial(caminho,
                        GUID, idEmpresa, idGrupoEmpresa, idUsuario, idPeriodoLetivo,
                        idCurso, idCiclo, idSerie, idFaseCalendario, idProfessor, idDisciplina, idTurma);

               

                consultaDll.LiberarRecursos();

            }

        } catch (Exception e) {
            //System.out.println("ERRO!");
            e.printStackTrace();
        } finally {
            consultaDll.LiberarRecursos();
            System.gc();
        }
        return retorno;
    }
S

Eu tenho o fonte dela sim!

S

Eu tenho o fonte dela sim!

Feita em Delphi

{ $HDR$}
{******************************************************************}
{ Advice POS }
{ }
{ Copyright (c) 2006-2009 Advice System Sistemas Lucrativos Ltda. }
{ }
{******************************************************************}
{}
{ $Log: 137251: AdMediaParcial.dpr
{
{ Rev 1.1 14/09/2012 16:49:06 mvnascimento
}
{
{ Rev 1.0 13/09/2012 16:18:10 mvnascimento
{ Projeto criado com a finalidade de fornecer rotinas do AdvicePOS ao
}
library AdMediaParcial;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
{ /*************************************************************************/
/*************************************************************************/ }
uses
SysUtils,
ShareMem,
dxGDIPlusAPI,
Classes,
MidasLib,
unt_FechamentoFase,
unt_DmMediaParcial in 'unt_DmMediaParcial.pas' {DmMediaParcial: TDataModule};
{$R *.res}
function CalcularMediaParcial(dirConfigIni: PAnsiChar; GUID: PAnsiChar; idEmpresa,
	idGrupoEmpresa, idUsuario, idPeriodoLetivo, idCurso,
	idCiclo, idSerie, idFaseCalendario, idProfessor,
	idDisciplina, idTurma: Integer): PAnsiChar; stdcall;
	var
	FFMedParcial: TFechamentoFase;
	begin
try
	DmMediaParcial := TDmMediaParcial.Create(dirConfigIni);
	FFMedParcial := TFechamentoFase.Create(DmMediaParcial, idEmpresa, idGrupoEmpresa, idUsuario, GUID
try
	FFMedParcial.PeriodoLetivo := idPeriodoLetivo;
	FFMedParcial.Curso := idCurso;
	FFMedParcial.Ciclo := idCiclo;
	FFMedParcial.Serie := idSerie;
	FFMedParcial.FaseCalendario := idFaseCalendario;
	FFMedParcial.Professor := idProfessor;
	FFMedParcial.Disciplina := idDisciplina;
	FFMedParcial.Turma := idTurma;
	FFMedParcial.CalcConsol := EmptyStr;
	FFMedParcial.TipoFechamento := ftPrevia;
	Result := FFMedParcial.ExecPreviaFechamentoFaseWeb;
finally
	FreeAndNil(FFMedParcial);
	FreeAndNil(DmMediaParcial);
	end;
	except
	on Ex: Exception do
begin
// Retorna o erro especifico p/ quem realizou a chamada
Result := PAnsiChar('ERR-' + Ex.Message);
	end;
	end; // except
	end; // function
procedure LiberarRecursos; stdcall;

	begin
	dxFinalizeGDIPlus;
	end;
	exports
	CalcularMediaParcial,
	LiberarRecursos;
begin
end.

Esta é a outra parte

{ $HDR$}
{******************************************************************}
{ Advice POS }
{ }
{ Copyright (c) 2006-2009 Advice System Sistemas Lucrativos Ltda. }
{ }
{******************************************************************}
{}
{ $Log: 137261: unt_DmMediaParcial.pas
{
{ Rev 1.0 13/09/2012 16:18:14 mvnascimento
{ Projeto criado com a finalidade de fornecer rotinas do AdvicePOS ao
}
unit unt_DmMediaParcial;
//*****************************************************************************//
// (untrDMPrincipal e untDmConnection), assim executando o seu initialization
// e gerando problemas de acesso a pacotes e objetos
//*****************************************************************************//
interface
	uses
	SysUtils, Classes, adDBExpress, DBXpress, DB, SqlExpr, AdFunctions, Swsystem;
	type
	TDmMediaParcial = class(TDataModule)
	SQLConnection: TadSQLConnection;
	procedure DataModuleDestroy(Sender: TObject);
private
	{ Private declarations }
public
	{ Public declarations }
	constructor Create(dirIniConfig: String); reintroduce; overload;
	end;
	var
	DmMediaParcial: TDmMediaParcial;
const
	FileIniConfig = 'AdMediaParcial.ini';
	implementation
	{$R *.dfm}
	uses IniFiles;
	constructor TDmMediaParcial.Create(dirIniConfig: String);
	begin
	inherited Create(nil);
if FileExists(dirIniConfig + FileIniConfig) then
	begin
	SQLConnection.ConnectionName := 'AdvConnection';
	SQLConnection.LoadParamsFromIniFile(dirIniConfig + FileIniConfig);
	// Tira a criptografia da senha
	SQLConnection.Params.Values['User_Name'] := Decriptar(SQLConnection.Params.Values['User_Name']);
	SQLConnection.Params.Values['Password'] := Decriptar(SQLConnection.Params.Values['Password']);
try
	SQLConnection.Open;
	except
	on E: Exception do
	raise Exception.Create()
	end;
	end
else
	begin
	raise Exception.Create();
	end;
	end;
	procedure TDmMediaParcial.DataModuleDestroy(Sender: TObject);
	begin
	SQLConnection.CloseDataSets;
	SQLConnection.Close;
end;
end.

Não manjo de Delphi foi a outra equipe que desenvolveu.

S

up

E

Que tal perguntar à outra equipe? Equipes em uma empresa devem se falar.

De qualquer maneira, dá a impressão que o código em Delphi original deva ter o mesmo problema quando você vá executá-lo sozinho, sem JNA ou Java ou sei lá o quê, quando for rodar na tal máquina com Windows em inglês mas regional settings em português.

Ou então você está fazendo alguma besteira na hora de converter a string para um resultado numérico :slight_smile:

S

entanglement:
Que tal perguntar à outra equipe? Equipes em uma empresa devem se falar.

De qualquer maneira, dá a impressão que o código em Delphi original deva ter o mesmo problema quando você vá executá-lo sozinho, sem JNA ou Java ou sei lá o quê, quando for rodar na tal máquina com Windows em inglês mas regional settings em português.

Ou então você está fazendo alguma besteira na hora de converter a string para um resultado numérico :)

entanglement

Obrigado por responder!

Então kra eles fizeram também um exe para testar a execução da DLL e rodou normalmente no servidor do cliente que esta ocorrendo o erro. e como disse com o meu fonte ( Java ) setando o banco para o endereço deles em produção também rodou corretamente nso outros clientes também esta OK somente nesse que esta ocorrendo isso. cheguei a subir um novo deploy a partis do fonte da minha maquina e o erro do calculo continuou!

Esta dificil entender pois não da erro somente calcula errado.

A outra equipe como o exe para teste funciona corretamente ja jogam a culpa par ao Java.

Complicado

E

Pois é, você vai ter de reproduzir o ambiente do cara onde o cálculo é feito incorretamente. Não descarto nada, pode ser problema do Delphi mesmo, ou do Java? (eles jogaram o tal programa de teste namáquina que deu problema?

S

Exatamente eu mesmo efetuei o teste!

E é oque estou fazendo neste momento subindo uma VM com o mesmo SO do cliente e montar um ambiente idêntico para testar!

Obrigado pela atenção ate o momento entanglement qualquer possível ideia ou sugestão agradeço, o resultado desses testes irei postar aqui.

Abraço

Criado 25 de abril de 2013
Ultima resposta 25 de abr. de 2013
Respostas 11
Participantes 3