3

I have a dll (Delphi) that contains a ADOConnection and ADOQuery, but when running the called DLL in java (using JNA) appear some error information to the console (below):

A fatal error has been detected by the Java Runtime Environment:

Internal Error (0xeedfade), pid=4400, tid=3840

JRE version: 6.0_25-b06 Java VM: Java HotSpot(TM) Client VM (20.0-b11 mixed mode, sharing windows-x86 ) Problematic frame: C [KERNELBASE.dll+0x812f]

An error report file with more information is saved as: C:\Users\Mmn1\Documents\NetBeansProjects\FLMOPDL\hs_err_pid4400.log

If you would like to submit a bug report, please visit:
http://java.sun.com/webapps/bugreport/crash.jsp The crash happened outside the Java Virtual Machine in native code. See problematic frame for where to report the bug.

What bug is this? (I realized that it is only happens if I have a form or as a component in the case ADOConnection ADOQuery and if I remove these components and perform a simple function, it works normally).

Edit:

A similar exemple bellow:

library TESTLIB;
{$DEFINE TESTLIB}

uses
  System.SysUtils,
  System.Classes,
  TestInt in 'TestInt.pas',
  Vcl.Dialogs,
  sharemem,
  Data.DB, Data.Win.ADODB;

{$R *.res}

function MyReturn(x: Integer; Test: PTest): Boolean; stdcall;
var
  ado: TADOQuery;
begin
    Result := True;
    //ado := TADOQuery.Create(nil); <- With this i got a error!
end;

exports MyReturn;

begin
end.

interface in Java

public interface TestInt extends StdCallLibrary {
    TestInt INSTANCE = (TestInt)Native.loadLibrary("C:/test/Win32/Debug/TESTLIB", TestInt.class);

    class Test extends Structure {
        public String vResult;

        public Test() { }
        public Test(int x, Pointer p) {
            super(p);
            read();
        }
        protected List getFieldOrder() { return Arrays.asList(new String[] { "vResult" }); }
    }

    Boolean MyReturn(int x, Test test);
}

conclusion: when I use a component, this error raise. Thanks for help.

Saureco
  • 81
  • 1
  • 8
  • 1
    You'll need some more information to get to the bottom of that. `0xeedfade` is the SEH exception code for a Delphi language extension. Why you DLL has thrown the exception is very hard to say. Only you have the code. I suggest that you run it under the debugger to work out what is going on. – David Heffernan Apr 02 '13 at 12:23
  • the same dll running through an executable functions normally done in Delphi. I've been searching about (over two days) and found no information about it. – Saureco Apr 02 '13 at 12:25
  • You need to debug it. You need more information. – David Heffernan Apr 02 '13 at 12:27
  • 1
    It's hard to say what the problem might be, as you failed to include the Java code that's calling your DLL code (including the way you declared it in Java in the first place). Can you [edit] to do so? Without it, there's no information here we can use to answer it, and it will probably be closed as 'too localized". Thanks. – Ken White Apr 02 '13 at 12:43
  • 2
    Why the `sharemem`? Maybe it's causing the problem? – kobik Apr 02 '13 at 12:53
  • No. I did tests using ShareMem (borlndmm.dll) because I thought that could be a problem of memory allocation, but it is not. – Saureco Apr 02 '13 at 12:57
  • 3
    Well, then maybe a `CoInitialize` is needed in your `MyReturn` function. – kobik Apr 02 '13 at 13:11
  • 3
    Anyway, I'm going to guess. Who is calling `CoInitialize`? Is anyone doing that? Your ADO query object presumably needs it. – David Heffernan Apr 02 '13 at 13:11
  • @kobik or rather in DllMain - why call it twice ? – Arioch 'The Apr 02 '13 at 15:29
  • 1
    @Arioch'The, Usually the calling thread will be responsible for calling `CoInitialize` and not the DLL... But I don't think it's relevant at this point, since the OP did not say if it solves the initial problem or not. – kobik Apr 02 '13 at 15:54
  • 1
    @Arioch No, never call CoInitialize from DllMain. The documentation says so explicitly. In fact never call it from a DLL because the app has to be in charge of that. – David Heffernan Apr 02 '13 at 15:56

2 Answers2

2

According to the message, the problem is

outside the Java Virtual Machine

in this case, it's probably in the Delphi code.

You might want to contact the developer(s) of the Delphi code and see if they can assist in troubleshooting the issue, or browse the code yourself to see what's going on. The hs_err_pid4400.log file will contain valuable information for them.

Either way, without Delphi source code it's hard to troubleshoot the issue.

mthmulders
  • 9,483
  • 4
  • 37
  • 54
  • 1
    It's for sure in the Delphi code. It's an unhandled Delphi language exception. That's what `0xeedfade` indicates. – David Heffernan Apr 02 '13 at 12:27
  • strange because as I said above, the same dll running on an application made ​​in delphi functions normally. This problem occurs when I try to use the same dll in java. – Saureco Apr 02 '13 at 12:38
  • 2
    Carefully compare the way the Delphi application calls the code from the DLL to the way the Java application calls the same code. Any differences might explain the cause of the error. – mthmulders Apr 02 '13 at 12:41
  • Application might easily call `CoInitialize` for its own needs, for example if it had ADO or Office components on its forms – Arioch 'The Apr 02 '13 at 15:31
0

Re-edited:

I got the solution. The problem was "how to" DLL had been made. Below the solution and I hope it helps more people:

TESTLIB (Delphi)

library TESTLIB;
{$DEFINE TESTLIB}

uses
  System.SysUtils,
  System.Classes,
  TestInt in 'TestInt.pas', //here's my unit (interface)
  Vcl.Dialogs,
  ADODB,
  Vcl.Forms;

  {$R *.res}


function MyReturn(Test: PTest): Boolean; stdcall;
var
  ado: TADOQuery;
  con: TADOConnection;
begin
    con := TADOConnection.Create(Application);
    ado := TADOQuery.Create(Application);

    con.ConnectionString := 'Provider=SQLOLEDB.1;Password=aaa;Persist Security Info=True;User ID=aa;Initial Catalog=aa;Data Source=127.0.0.1';
    con.LoginPrompt := False;
    con.Open();

    if con.Connected = True then
        ShowMessage('connected ok')
    else
        ShowMessage('not connected');

    ado.Active := False;
    ado.Connection := con;
    ado.SQL.Clear;
    ado.SQL.Add('select lalala from table where codlala = 1');
    try
        ado.Open();
        Test^.vResult := PAnsiChar(AnsiString(ado.FieldByName('fantasia').AsString));
        Result := True;
    except
        on E: Exception do
        begin
          ShowMessage('error to open the query' + #13 + 'Error: ' + E.Message);
          Result := False;
        end;
    end;
end;

exports MyReturn;

begin
end.

Interface Ole32 (java)

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.win32.StdCallLibrary;

public interface Ole32 extends StdCallLibrary {

    Ole32 INSTANCE = (Ole32) Native.loadLibrary("Ole32", Ole32.class);

    public HRESULT CoInitialize(Pointer p);

    public HRESULT CoUninitialize();

}

Special thanks to kobik and technomage about CoInitialize

links that helped me:

TADOConnection failing in application initialization section of Delphi ISAPI App:

Add CoInitializing constants and improve documentation

Using COM from Java via JNA

Community
  • 1
  • 1
Saureco
  • 81
  • 1
  • 8
  • 3
    You should not call CoInitialize inside a DLL, it is meant to be initialized form the calling process. Read: http://blogs.msdn.com/b/larryosterman/archive/2004/05/12/130541.aspx – jachguate Apr 02 '13 at 16:15
  • 2
    JNA makes `CoInitialize` available in `platform.jar`. You should call that one from the application, rather than the DLL. – technomage Apr 02 '13 at 19:50