NullPointerException bei Zugriff auf JNI Objekt

Status
Nicht offen für weitere Antworten.

mhauert

Mitglied
Hallo zusammen,

ich schreibe gerade ein Programm das JNI nutzen soll um C++ Code auszuführen.
Ich nutzte dabei Eclipse und MS Visual C++ 2008 Express auf einem WindowsXP System.

Bei Testen im kleinen Rahmen bin ich auf ein Problem gestoßen, das ich nicht lösen kann.

Es tritt hier auf:
Code:
public static void main(String[] args) 
	{		
		DesktopImpl impl = new DesktopImpl();
		Snapshot x = impl.getComplete();
		System.out.println("Count: " + x.count);
		System.out.println(x.bytes[0]+", "+x.bytes[1]);
		System.out.println(x.changes[0]+", "+x.changes[1]);
         }

In der Konsole zeigt sich folgendes:
Code:
Count: 580449256
Exception in thread "main" java.lang.NullPointerException
	at de.cworxmedia.rds.server.test.main(test.java:17)

Der Konstruktor für Snapshot sieht so aus:
Code:
public Snapshot(int count, byte[] bytes, int[] changes)
	{
		this.count = count;
		this.bytes = bytes;
		this.changes = changes;
	}

Die Methode getComplete() wurde in einer anderen Klasse als native deklariert und in C++ implementiert.
Sie soll ein Snapshot- Objekt erstellen und es dann an das Javaprogramm zurückgeben
Code:
JNIEXPORT jobject JNICALL Java_de_cworxmedia_rds_natives_Win32Desktop_getComplete
  (JNIEnv *env, jobject jc)
{
jclass jclass = env->GetObjectClass(jc);
jmethodID jmid = env->GetMethodID(jclass, "<init>", "()V");
jint jcount = 345;
jbyteArray jbytes = env->NewByteArray(2);
jintArray jchanges = env->NewIntArray(2);
jbyte *jbytesbuf = env->GetByteArrayElements(jbytes, 0);
jint *jchangesbuf = env->GetIntArrayElements(jchanges, 0);
jbytesbuf[0] = (BYTE) 22;
jbytesbuf[1] = (BYTE) 23;
jchangesbuf[0] = (jint) 5;
jchangesbuf[1] = (jint) 46723;
jobject jo = env->NewObject(jclass, jmid, jcount, jbytes, jchanges);
return jo;
}

Der C++ Code wurde dann in eine DLL kompiliert.

Eigentlich sollte ja das Programm die Int- Variable und die beiden Arrays ausgeben.
Aber wie man sieht, der Int-Wert ist falsch und die Arrays nicht vorhanden.

Ich weiß aber nicht, wie ich den C++ Code abändern müsste, um das Problem zu beheben.
Das es am Java Code liegt kann ich mir nicht vorstellen.

Ich bin für jeden Lösungsvorschlag dankbar.
 

mhauert

Mitglied
Erstmal danke für den Link. Der hat mir neue Einblicke beschert.

Nun zu meiner daraus entstandenen Idee:

Code:
JNIEXPORT jobject JNICALL Java_de_cworxmedia_rds_natives_Win32Desktop_getComplete
  (JNIEnv *env, jobject jc)
{

[...] //Der Code hier hat sich nicht geändert

jobject jo = env->NewObject(jclass, jmid, jcount, jbytes, jchanges);
return env->NewGlobalRef(jo);
}

Das einzige was sich danach änderte, war der Wert des Integers von 580449256 in 580440082.

Um die Konstruktion des Snapshot- Objekts in C++ zu umgehen, war meine nächste Idee dann, der C++ Methode ein leeres Snapshot Objekt zu übergeben, und dieses dann zu befüllen und zurück zu geben:

Code:
JNIEXPORT jobject JNICALL Java_de_cworxmedia_rds_natives_Win32Desktop_getCompleteN
  (JNIEnv *env, jobject jc, jobject dummy)
{
jclass cdummy = env->GetObjectClass(dummy);
jbyteArray jbytes  = env->NewByteArray(2);
jintArray jchanges = env->NewIntArray(2);
jbyte *jbytesbuf   = env->GetByteArrayElements(jbytes, 0);
jint *jchangesbuf  = env->GetIntArrayElements(jchanges, 0);
int jcount     = 345;
jbytesbuf[0]   = (BYTE) 22;
jbytesbuf[1]   = (BYTE) 23;
jchangesbuf[0] = (jint) 5;
jchangesbuf[1] = (jint) 46723;

jfieldID jcountID   = env->GetFieldID(cdummy, "count", "I");
jfieldID jbytesID   = env->GetFieldID(cdummy, "bytes", "[B");
jfieldID jchangesID = env->GetFieldID(cdummy, "changes", "[I");

env->SetIntField(dummy, jcountID, jcount);
env->SetObjectField(dummy, jbytesID, jbytes);
env->SetObjectField(dummy, jchangesID, jchanges);

return dummy;
}

Und siehe da, zumindest der Integer ist jetzt richtig. Die Ausgabe des Programms lautet:

Code:
345
0, 0
0, 0

Problem ist nur das die Arrays nun zwar da sind, aber als Werte nur 0 enthalten. Ich würde mal schätzen, das die folgenden Zeilen nicht den gewünschten Effekt haben:

Code:
jbyteArray jbytes  = env->NewByteArray(2);
jintArray jchanges = env->NewIntArray(2);
jbyte *jbytesbuf   = env->GetByteArrayElements(jbytes, 0);
jint *jchangesbuf  = env->GetIntArrayElements(jchanges, 0);

jbytesbuf[0]   = (BYTE) 22;
jbytesbuf[1]   = (BYTE) 23;
jchangesbuf[0] = (jint) 5;
jchangesbuf[1] = (jint) 46723;

Gibt es da noch einen Befehl, der die jarray Objekte aktualisiert? Weil ich dachte, die Zeiger zeigen in diese Objekte...

Solltes du für dieses Problem oder für das ursprüngliche Problem mit der "NullPointerException" noch eine Idee haben, würde mir das sehr helfen.

Danke im Vorraus.
 

mhauert

Mitglied
OK, alles klar.

Hatte in der Spezifikation überlesen, das die Release<Type>ArrayElements- Funktion
nicht nur den Speicher freigibt sondern auch die Werte in das Java- Array schreibt. :roll:

Der folgende Code arbeitet einwandfrei:

Code:
JNIEXPORT jobject JNICALL Java_de_cworxmedia_rds_natives_Win32Desktop_getCompleteN
  (JNIEnv *env, jobject jc, jobject dummy)
{
jclass cdummy = env->GetObjectClass(dummy);
jbyteArray jbytes  = env->NewByteArray(2);
jintArray jchanges = env->NewIntArray(2);
jbyte *jbytesbuf   = env->GetByteArrayElements(jbytes, 0);
jint *jchangesbuf  = env->GetIntArrayElements(jchanges, 0);
int jcount     = 345;
jbytesbuf[0]   = (BYTE) 22;
jbytesbuf[1]   = (BYTE) 23;
jchangesbuf[0] = (jint) 5;
jchangesbuf[1] = (jint) 46723;

jfieldID jcountID   = env->GetFieldID(cdummy, "count", "I");
jfieldID jbytesID   = env->GetFieldID(cdummy, "bytes", "[B");
jfieldID jchangesID = env->GetFieldID(cdummy, "changes", "[I");

env->ReleaseByteArrayElements(jbytes, jbytesbuf, 0);
env->ReleaseIntArrayElements(jchanges, jchangesbuf, 0);

env->SetIntField(dummy, jcountID, jcount);
env->SetObjectField(dummy, jbytesID, jbytes);
env->SetObjectField(dummy, jchangesID, jchanges);

return dummy;
}
Habe ich das auch richtig verstanden, das die Release- Funktion den Speicher wieder freigibt?
Oder muss ich die Zeiger noch extra freigeben und löschen? Nicht das mir der Speicher überläuft...
 

Marco13

Top Contributor
Jo, hab nochmal drübergeschaut: Das hier ist ja so irgendwie wohl nicht richtig
Code:
jclass jclass = env->GetObjectClass(jc);
jmethodID jmid = env->GetMethodID(jclass, "<init>", "()V");
...
jobject jo = env->NewObject(jclass, jmid, jcount, jbytes, jchanges);
return jo;
Du holst dir dort die methodID vom Konstruktor der Klasse, auf der die Methode aufgerufen wird - also von DesktopImpl. Und dieser Konstruktor soll dann verwendet werden, um ein Objekt vom Typ Snapshot zu erstellen.

Hiermit sollte es gehen
Code:
#include "JniReturnTest.h"

JNIEXPORT jobject JNICALL Java_JniReturnTest_getComplete
  (JNIEnv *env, jobject jc)
{
	jint jcount = 345;
	jbyteArray jbytes = env->NewByteArray(2);
	jintArray jchanges = env->NewIntArray(2);
	jbyte *jbytesbuf = env->GetByteArrayElements(jbytes, 0);
	jint *jchangesbuf = env->GetIntArrayElements(jchanges, 0);
	jbytesbuf[0] = 22;
	jbytesbuf[1] = 23;
	jchangesbuf[0] = (jint) 5;
	jchangesbuf[1] = (jint) 46723;

	// Hier releasen / zurückschreiben
	env->ReleaseByteArrayElements(jbytes, jbytesbuf, 0);
	env->ReleaseIntArrayElements(jchanges, jchangesbuf, 0);

	// Konstruktor für "Snapshot" suchen
	jclass jcl = env->FindClass("Snapshot");
	jmethodID jmid = env->GetMethodID(jcl, "<init>", "(I[B[I)V"); // Signatur beachten!
	jobject jo = env->NewObject(jcl, jmid, jcount, jbytes, jchanges);

	return env->NewGlobalRef(jo); // Sollte auch wieder gelöscht werden können !!??!!
}
 

Marco13

Top Contributor
Ach ja: Das mit dem Release sollte so OK sein. Der letzte Post bezog sich jetzt auf das Erstellen des Objektes von C++-Seite aus Und wenn du ein "dummy"-Objekt in Java erstellst und übergibst, brauchst du dir wenigstens keine Gedanken über die Referenz auf der C++-Seite zu machen - DA könnte dann nämlich Speicher flöten gehen...
 

mhauert

Mitglied
Ah ja. Da hab ich wohl was durcheinander gehauen.

Vielen Dank für die Hilfe.
Ich werds jetzt erstmal so lassen und sehen wie es sich in der Praxis macht...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Zeppi NullPointerException in einer if-Abfrage Allgemeine Java-Themen 6
T imagej-server NullPointerException Allgemeine Java-Themen 1
L Methoden NullpointerException Allgemeine Java-Themen 5
B OOP Auslöser für NullPointerException Allgemeine Java-Themen 3
I Vererbung Nicht erklärliche NullPointerException Allgemeine Java-Themen 7
Drachenbauer warum bekomme ich hier eine NullPointerException Allgemeine Java-Themen 6
I Array Parameter mit 2 Klassen - NullPointerException Allgemeine Java-Themen 3
S Exception in thread "main" java.lang.NullPointerException at FamilienApp.main(FamilienApp.java:15) Allgemeine Java-Themen 1
S Methoden Problem mit NullPointerException Allgemeine Java-Themen 9
F Input/Output NullPointerException, aber wieso? [Apache POI] Allgemeine Java-Themen 11
F Input/Output NullPointerException with Apache POI Allgemeine Java-Themen 7
P wiedermal NullPointerException Allgemeine Java-Themen 2
kodela NullPointerException Allgemeine Java-Themen 2
L Variablen NullPointerException (RSA) Allgemeine Java-Themen 2
B NullPointerException bei @Inject JSF Allgemeine Java-Themen 0
Arif Probleme mit NullPointerException Allgemeine Java-Themen 2
G String an Arduino senden NullPointerException in PrintWriter Allgemeine Java-Themen 6
Z NullPointerException beim Schreiben einer ArrayList in eine Datei Allgemeine Java-Themen 6
R NullPointerException Ohne Grund Allgemeine Java-Themen 5
D ByteBuffer getInt NullpointerException Allgemeine Java-Themen 4
S JavaMail - MailSubject,MailFrom,MailDate in String Array speichern NullPointerException Allgemeine Java-Themen 2
T Compiler-Fehler NullpointerException! Allgemeine Java-Themen 7
A Methode ergibt Java NullpointerException. Allgemeine Java-Themen 3
F Socket NullPointerException Bitte um hilfe! Allgemeine Java-Themen 12
L NullPointerException bei Instanzvarialen Allgemeine Java-Themen 3
B Compiler-Fehler NullPointerException beim Auslesen von .lang-Datei Allgemeine Java-Themen 3
I Fehler java.lang.NullPointerException Allgemeine Java-Themen 5
B NullPointerException - Aber kein Fehler im Code Allgemeine Java-Themen 4
H java.lang.NullPointerException Allgemeine Java-Themen 5
L Interpreter-Fehler java.lang.NullPointerException Allgemeine Java-Themen 17
M JSON NullPointerException Allgemeine Java-Themen 5
M NullpointerException Allgemeine Java-Themen 2
L Eclipse NullPointerException Allgemeine Java-Themen 6
M Fitness-Rechner: NullPointerException Allgemeine Java-Themen 7
G Thread erzeugt nicht plausible NullPointerException Allgemeine Java-Themen 7
A java.lang.NullPointerException bei Schleife Allgemeine Java-Themen 3
K Unerklärliche nullpointerexception Allgemeine Java-Themen 6
C Was bekomme ich eine Nullpointerexception? (Apache POI) Allgemeine Java-Themen 3
S javadoc java.lang.NullPointerException Allgemeine Java-Themen 2
K 3Dimensionales Feld - NullPointerException Allgemeine Java-Themen 2
J Compiler-Fehler NullPointerException Allgemeine Java-Themen 12
T Compiler-Fehler NullPointerException bei ADT LinkedTree Allgemeine Java-Themen 31
P Beim sortieren nullpointerexception Allgemeine Java-Themen 12
3 MP3-Finder wirft NullPointerException Allgemeine Java-Themen 13
M NullPointerException MenuItem Allgemeine Java-Themen 7
S Dialog einblenden bei NullPointerException Allgemeine Java-Themen 5
T DefaultTableModel NullPointerException Allgemeine Java-Themen 7
ruutaiokwu NullPointerException auf member, die per konstruktor gesetzt wird (multithread-kontext) Allgemeine Java-Themen 2
B NullPointerException ohne Angabe Allgemeine Java-Themen 5
F NullPointerException aber warum ? Allgemeine Java-Themen 9
F Array NullPointerException Allgemeine Java-Themen 26
B NullPointerException bei Wertzuweisung Allgemeine Java-Themen 3
C NullPointerException Allgemeine Java-Themen 9
MonsterBit java.lang.NullPointerException Allgemeine Java-Themen 2
O NullPointerException (wohl Denkfehler) Allgemeine Java-Themen 5
N Warum nullPointerException? Allgemeine Java-Themen 13
N Generics-NullpointerException Allgemeine Java-Themen 7
J NullPointerException mit HashMap Allgemeine Java-Themen 2
B NullPointerException bei new XStream() Allgemeine Java-Themen 2
J java.lang.NullPointerException bei Threadprogrammierung Allgemeine Java-Themen 9
J NullPointerException bei JasperReports Allgemeine Java-Themen 2
V NullPointerException bei Vector Allgemeine Java-Themen 2
G Warum kommt hier NullPointerException? Allgemeine Java-Themen 3
G NullPointerException Allgemeine Java-Themen 5
R Immer wieder NullPointerException Allgemeine Java-Themen 2
M NullPointerException Allgemeine Java-Themen 4
J Fehler: java.lang.NullPointerException Allgemeine Java-Themen 2
G NullPointerException, aber warum? Allgemeine Java-Themen 10
G NullPointerException problem Allgemeine Java-Themen 30
J Folgender Fehler: java.lang.NullPointerException Allgemeine Java-Themen 4
T NullPointerException nach Java Update Allgemeine Java-Themen 4
G NullPointerException Allgemeine Java-Themen 6
H NullPointerException trotz Abfangen von null? Allgemeine Java-Themen 9
H nullPointerException bei [ArrayList<String>.add(.)] Allgemeine Java-Themen 3
H NullPointerException Allgemeine Java-Themen 10
P NullPointerException Allgemeine Java-Themen 8
A NullPointerException, Thread soll Thread steuern Allgemeine Java-Themen 2
MQue Sichtbarkeit/HashMap/NullPointerexception Allgemeine Java-Themen 2
MQue NullPointerException Allgemeine Java-Themen 17
A NullPointerException Allgemeine Java-Themen 15
G java.lang.NullPointerException JFreeChart Allgemeine Java-Themen 5
A NullPointerException Allgemeine Java-Themen 11
G Methode mit Schleifen NullPointerException Allgemeine Java-Themen 2
B Pobleme mit NullpointerException Allgemeine Java-Themen 13
M java.lang.NullPointerException im Chatclient Allgemeine Java-Themen 12
S NullPointerException beim Laden von BMPs Allgemeine Java-Themen 3
B java.lang.NullPointerException Allgemeine Java-Themen 11
M NullPointerException bei Subklasse ohne MediaTracker Allgemeine Java-Themen 12
G Problem mit NullPointerException Allgemeine Java-Themen 5
D NullPointerException wo keine sein sollte. Allgemeine Java-Themen 2
F NullpointerException beim Einlesen einer Datei Allgemeine Java-Themen 13
V Button schließen - NullPointerException Allgemeine Java-Themen 6
V NullPointerException Allgemeine Java-Themen 12
LucasGlockner Effizienter byte-Zugriff auf ein long[]-Array Allgemeine Java-Themen 8
W Klassen Zugriff auf ein Textfile aus allen Klassen. Allgemeine Java-Themen 2
izoards Zugriff auf gemeinsame Ressource (CSV-File) Allgemeine Java-Themen 3
S Java Zugriff auf Netzwerklaufwerk Allgemeine Java-Themen 1
sascha-sphw Java 9 module Zugriff auf eine resource einer anderen JAR Allgemeine Java-Themen 0
KeexZDeveoper Zugriff auf Methoden vom Server Allgemeine Java-Themen 7
O Zugriff auf mySQL ohne JDBC Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben