JNI->kann abhängige Bibliotheken einer DLL nicht finden

DennisTs

Mitglied
Hallo Leute.

Seit etwas mehr als zwei Wochen beschäftige ich mich mit dem Problem JNI und bin nicht weiter gekommen. Ich hoffe ihr könnt mir bei dem Problem helfen.

Die Vorgehensweise:
1. Die JAVA Klasse ist erstellt worden. Die heißt: Abrechnung302esend.java
2. Mit javac.exe wurde die dazugehörige Klasse erstellt. Abrechnung302eSend
3. Danach wurde die Header datei mit javah erstellt. Auch kein Problem.
4. C++ MFC DLL wurde programmiert und erstellt. Auch kein Problem bis hier.

Der JAVA Code für den Aufruf sieht so aus:
[JAVA=34]
public class Abrechnung302eSend {
public static native boolean Start302eSend() throws Exception;


static {
try{
System.load("C:\\Projekte\\projAbr302.dll");
}catch (Exception ex) {
Client.showException(ex);
}
}



public static void main(String [] args) throws Exception{

boolean TestFunc = Abrechnung302eSend.Start302eSend();
}


}
[/code]

Zur der Main Methode kommt das Prg. garnicht hin da folgende Meldung kommt:

EXCEPTION:
Meldung: Error occurred in server thread; nested exception is:
java.lang.UnsatisfiedLinkError: C:\Projekte\projAbr302.dll: Can't find dependent libraries
java.rmi.ServerError: Error occurred in server thread; nested exception is:
java.lang.UnsatisfiedLinkError: C:\Projekte\projAbr302.dll: Can't find dependent libraries
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)


Die Fehlermeldung besagt, dass die dependet libraries nicht gefunden werden können.
Welche abhängigen Bibliotheken werden hier gemeint? ???:L

Der code der projAbr302.cpp womit die C++ DLL erstellt wird, ist der folgende:

Java:
// projAbr302.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "projAbr302.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//
//TODO: If this DLL is dynamically linked against the MFC DLLs,
//		any functions exported from this DLL which call into
//		MFC must have the AFX_MANAGE_STATE macro added at the
//		very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//


// CprojAbr302App

BEGIN_MESSAGE_MAP(CprojAbr302App, CWinApp)
END_MESSAGE_MAP()


// CprojAbr302App construction

CprojAbr302App::CprojAbr302App()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CprojAbr302App object

CprojAbr302App theApp;

const GUID CDECL BASED_CODE _tlid =
		{ 0x3A93A506, 0xB6ED, 0x4EF5, { 0x95, 0x51, 0x5C, 0xD7, 0xE8, 0xCE, 0x21, 0x10 } };
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;


// CprojAbr302App initialization

BOOL CprojAbr302App::InitInstance()
{
	CWinApp::InitInstance();

	// Register all OLE server (factories) as running.  This enables the
	//  OLE libraries to create objects from other applications.
	COleObjectFactory::RegisterAll();

	return TRUE;
}

// DllGetClassObject - Returns class factory

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return AfxDllGetClassObject(rclsid, riid, ppv);
}


// DllCanUnloadNow - Allows COM to unload DLL

STDAPI DllCanUnloadNow(void)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	return AfxDllCanUnloadNow();
}


// DllRegisterServer - Adds entries to the system registry

STDAPI DllRegisterServer(void)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
		return SELFREG_E_TYPELIB;

	if (!COleObjectFactory::UpdateRegistryAll())
		return SELFREG_E_CLASS;

	return S_OK;
}


// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
		return SELFREG_E_TYPELIB;

	if (!COleObjectFactory::UpdateRegistryAll(FALSE))
		return SELFREG_E_CLASS;

	return S_OK;
}

JNIEXPORT jboolean JNICALL Java_de_vngmbh_vn_pm_faktura_abrechnung302_Abrechnung302eSend_Start302eSend(JNIEnv *jenv, jclass jcl){

	printf("Hello World from C++ DLL!\n");
	return FALSE;

}


Ich benutze Win7 Prof., für die DLL Erstellung VS2005, JDK 1.6.0_26.
Das JAVA Program hat Teile die auf der Serverseite laufen und Teile die auf der Clientseite laufen.
Das Ansprechen des DLLs muß auf der Serverseite erfolgen.

Übersehe ich etwas hier?
Fehlt mir irgendwo noch ein Schritt den ich noch machen muß?
Falls noch etwas benötigt wird sagt mir Bescheid.
Werde mich freuen wenn dieses Problem gelöst wird.

Ich bedanke mich im Voraus.

Dennis
 
Hi dayaftereh.

Windows 7 ist eine 64bit Version.

Im Ordner: Program Files (nicht im Ordner: Program Files(x86)) ist JAVA jdk 1.6.0_26 installiert. Daher gehe ich von aus dass eine 64bit Version ist.
Aber für die DLL kann garnichts zu sagen. Ich habe gesucht aber nichts gefunden.

Eine Idee wie man es herausfindet?

Dennis
 
Ich hatte auch mal das Problem und als war der Fehler das die DLL nicht gefunden werden konnte. Ich habe dann geschaut was für eine DLL ich einlade, ob die für 32Bit oder 64Bit compilt wurde. Die DLL war 32Bit und mein Java + Win 7 war 64Bit. Als ich dann die 64Bit DLL genommen habe, ging es ohne Probleme. Du Compilst die DLL ja selber, kannst du die nicht einfach für 64Bit compilen?

Um raus zu finden welche Java Version du hast, einfach ein Java Programm starten und im TaskManager nach der java.exe oder javaw.exe suchen und schauen ob ein *32 dahinter steht!

Ich glaube eine DLL Kannst du über dumpbin oder den Dependency Walker prüfen, aber da bin ich mir nicht sicher!
 
Ja, an der Konsole ein
dumpbin /DEPENDENTS nameDerDLL.DLL
sollte die Abhängigkeiten auflisten (ggf. geht das auch aus den .LIB-Dateien hervor, die im Projekt verlinkt sind, aber auch nur bedingt...)
 

Zurück
Oben