JNI-Dlls aus dynamischen Wrapper-Klassen laden

Status
Nicht offen für weitere Antworten.
R

red99

Gast
Hallo alle zusammen,

ich hab im Zuge der PC-AG unserer Schule ein Spiel geschrieben, bei dem man Spieler in Form von JNI-Wrapperklassen dynamisch über den URL-Klassloader laden kann. Die zugehörigen Delphi-DLLs(nach Anleitung JNI unter Delphi http://www.pacifier.com/~mmead/jni/delphi/) schreiben die anderen PC-AGler. Dann können sie noch die Wrapperklassen, die von einer Oberklasse erben anpassen und kompilieren.
Oberklasse:
Code:
public abstract class Native {
	
	public abstract byte[] start(int Index, byte[][] Positionen);
	public abstract byte[] zug(byte[][] Positionen);
	
	protected String Library;
	protected String Path;
	
	public Native(String Path)
	{
		this.Path=Path;
	}
	
	protected void init()
	{
		System.out.println(Path+Library);
		System.load(Path+Library);
	}
	
}
eine Wrapperklasse
Code:
public class SpielerTest extends Native {

	public SpielerTest(String Path)
	{
		super(Path);
		Library = "SpielerTest.dll";
		init();
	}
	public native byte[] start(int Index, byte[][] Positionen);
	public native byte[] zug(byte[][] Positionen);

}
so wird die Klasse eingebunden:
Code:
	public Main(String... libs)
	{
		try {
			nv = new Native[libs.length];

			for (int i=0;i<libs.length;i++)
			{
				File file = new File(libs[i]);
				File Pfad = new File(file.getParent());
				
				if (!(file.exists()&&file.isFile()))
					throw new FileNotFoundException
						("Library "+libs[i]+" konnte nicht gefunden werden!");
				
				URL url = Pfad.toURI().toURL();
				System.out.println(url);
				URLClassLoader uc = new URLClassLoader(new URL[]{url});
				
				libs[i]=file.getName().substring(0, file.getName().length()-6);
				
				Class<?> n = uc.loadClass(libs[i]);
				
				if(n.getSuperclass()==Native.class)
				{
					c = (Class<? extends Native>)n;
					Class clsargs = String.class;
					Constructor constr = c.getConstructor(clsargs);
					String strarg = Pfad.getCanonicalPath();
					if (!(strarg.endsWith("/")||strarg.endsWith("\\")))
							strarg+=File.separatorChar;
					
					nv[i] = (Native) constr.newInstance(strarg);
				}
				
			}
			Positionen = new byte[nv.length][0];
		} catch (InstantiationException e) {
				e.printStackTrace();
		} catch (IllegalAccessException e) {
				e.printStackTrace();
		} catch (ClassNotFoundException e) {
				e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

Das Probelm ist jetzt, dass dies zwar geht wenn sich die Wrapperklasse mit ihrer DLL im Classpath befindet jedoch nicht, wenn sie irgendwo anders ist, was jedoch mit rein java ja geht. Dann kommt folgende Fehlermeldung:
Code:
Exception in thread "Timer-0" java.lang.UnsatisfiedLinkError: SpielerTest.start(I[[B)[B
	at SpielerTest.start(Native Method)
	at Main.start(Main.java:83)
	at GUI.start(GUI.java:327)
	at GUI.playTask(GUI.java:314)
	at GUI.access$9(GUI.java:306)
	at GUI$7.run(GUI.java:301)
	at java.util.TimerThread.mainLoop(Timer.java:512)
	at java.util.TimerThread.run(Timer.java:462)

Ich habe den Verdacht, dass es an der Bennennung mit JNI wie Java_Paket_Klassenname_Funktion liegt

Könnte mir bitte jemand helfen.
Vielen Dank schon mal
 
R

red99

Gast
Hallo???
Hat keiner eine Idee oder wurde das hier übersehen oder hab ich was falsch gemacht???? :(
Bitte doch mal was schreiben. :) Danke
 

anfänger15

Bekanntes Mitglied
Das Probelm ist jetzt, dass dies zwar geht wenn sich die Wrapperklasse mit ihrer DLL im Classpath befindet jedoch nicht, wenn sie irgendwo anders ist, was jedoch mit rein java ja geht

Ist doch logisch. Befindet die DLL nicht im Classpath weiß Java nicht was es machen soll ( da die DLL nicht gefunden wird) und es gibt ein Fehler.

Meines Wissens kannst du auch beim starten des Java Programm ein Parameter mitgeben, der Java sagt wo die DLL ist.
 
R

red99

Gast
danke für die Antwort
ja nein daran liegt es nicht sonst wär die Fehlermeldung anders. Den Pfad zur Dll übergebe ich ja im Konstruktor von Native bzw SpielerTest. Die Wrapperklasse muss auch nicht im Classpath sein, da die ja über den URL-Classloader aufgerufen wird

Es hat denk ich was mit der JNI Funktions-Bennenung in der Native-Dll zu tun. Vielleicht hat jemand eine Idee wie man das lösen kann.
Fehler:
Code:
java.lang.UnsatisfiedLinkError: SpielerTest.start(I[[B)[B
 
G

Gast

Gast
Man lädt die Libraries bei JNI nur mit dem Namen. Also ohen Pfad und endung. Die Endung wird dann je nach OS von der VM angehängt. Also z.B. .dll in Windows.

Und die Lib muss dann im Pfad liegen oder per Parameter übergeben werden.
 

lhein

Top Contributor
Weshalb man dann mit -Djava.library.path den Pfad zu einer DLL außerhalb des Classpath angeben muss.
 
R

red99

Gast
mit system.load() kann aber auch n-bibliotheken mit pfad und endung laden das ging bei mir
die bibliothek wird auch gefunden sonst wäre eine andere fehlermeldung
 
T

tuxedo

Gast
Ohne "-Djava.library.path ./meinPfad/meineDll.dll" , wie LR es geschrieben hat, funktioniert das nicht. Okay, es gäbe noch den Weg die DLL in die JRE rein zu kopieren, aber das "gehört sich nicht".

- Alex
 
R

red99

Gast
ja aber das ist ein Laufzeitargument beim start. Kann man das dann auch über System.setProperties() mit Wirkung ändern? Ich denke nein und dann wär dieser weg nicht machbar.
 
T

tuxedo

Gast
Was hälst du davon das einfach auszuprobieren (ist ja nur eine zeile code) und dann zu berichten obs geklappt hat?

Nebenbei gesagt:

Wo liegt das Problem eine Convention einzuführen ala "dynamische Wrapper-Klassen werden im Projektverzeichnis im Pfad XYZ abgelegt" ??

- Alex
 
R

red99

Gast
Ok werds ausprobieren bloß grad kei zeit, morgen. Das mit dem Pfad hatte ich mir auch überlegt, anders hätt ichs halt besser gefunden. Aber wenns nicht geht kann man nichts machen.
 
T

tuxedo

Gast
Das ist in vielen Programmen so... gerade wenns um DLLs geht.

[update]
Ich hatte ja geschrieben: Probier's aus die System-Property zur Laufzeit zu ändern. Vielleicht geht's ja tatsächlich....

- Alex
 
R

red99

Gast
Also wenn ich mit System.setProperty() den Pfad zu der Bibliothek zu java.library.path hinzufüge wird es über System.loadLibrary() nicht gefunden und mit System.load() ist es egal, damit wird es immer gefunden.
 
R

red99

Gast
Also ich hab das Projekt umorganisiert und feste Ordner angelegt.
Sieht so aus als gäbe es unter obigen Umständen keinen Lösung.
-----
closed
 

Fancy

Aktives Mitglied
Also, wenn das dynamische Anpassen des java.library.path das einzige Problem ist, versuche mal:

Code:
public final static void setJavaLibraryPath(String path) throws NoSuchFieldException, IllegalAccessException{

	        final String newPath = path + File.pathSeparator + System.getProperty("java.library.path");
	        System.setProperty("java.library.path", newPath);

	        final Field field = (java.lang.ClassLoader.class).getDeclaredField("sys_paths");
	        field.setAccessible(true);
	        if(field != null) field.set((java.lang.System.class).getClassLoader(), null);
	}

Gruß,
Michael
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Dann07 Java-Programm findet DLLs nicht! Allgemeine Java-Themen 20
U Classpath DLLs mittels System.load() laden: Allgemeine Java-Themen 6
U DLLs werden nicht gefunden trotz Pfad: Allgemeine Java-Themen 4
D .dlls mit Java verwenden Allgemeine Java-Themen 2
M JNI mit vorhandenen libs oder dlls verwenden Allgemeine Java-Themen 2
D dlls und jar archive Allgemeine Java-Themen 4
H Pfade von DLLs festlegen Allgemeine Java-Themen 2
R Signieren von Java-Prog. oder Applets - Zugriff auf dlls Allgemeine Java-Themen 8
P DLLs nutzen Allgemeine Java-Themen 3
D Problem mit Login in einem Dynamischen Webprojekt Allgemeine Java-Themen 1
R [Android]Wie dynamischen Button-Feld erstellen? Allgemeine Java-Themen 3
A [gelöst] Dynamischen Webseitentest automatisieren mit Java sinnvoll? Allgemeine Java-Themen 6
M Realisierung einer dynamischen Tabelle unter Android Allgemeine Java-Themen 3
S Darstellung einer dynamischen Matrix Allgemeine Java-Themen 9
L Selectfelder mit dynamischen Auswahlverfahren Allgemeine Java-Themen 3
S AffineTransform Wrapper der im Uhrzeigersinn rotiert..? Allgemeine Java-Themen 2
T JNI Wrapper Klasse Allgemeine Java-Themen 18
D Datentypen Typbestimmung unbekannter Wrapper-Klassen Allgemeine Java-Themen 5
E wie call by reference mit Wrapper-Klassen? Allgemeine Java-Themen 2
dayaftereh Java executable wrapper? Allgemeine Java-Themen 4
K Wrapper um ZipInputStream funktioniert nicht Allgemeine Java-Themen 2
H Einbinden einer 3rd party DLL via Java Wrapper (JNI) Allgemeine Java-Themen 11
J Wrapper Array in korresp. primitiven Array umwandeln? Allgemeine Java-Themen 2
A Eigene Wrapper-Klassen Allgemeine Java-Themen 2
G Object. Wrapper Allgemeine Java-Themen 12
S Java Wrapper Allgemeine Java-Themen 6
M Java Wrapper für interaktive Perl-Skripte Allgemeine Java-Themen 3
G wrapper --> unwrapper Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben