Java und Native Code

Endlich! Endlich hab ich die Ursache für einen Fehler der ganz besonderen Art gefunden.

Das Problem

Ich habe ein Minimal-Projekt aufgesetzt mit einer Abhängigkeit auf LWJGL, eine Java-Grafik-Bibliothek die neben einem Java-Teil auch aus einem Teil native Code besteht. Neben der *.jar im Classpath muss der JVM auch ein Pfad vorliegen, unter dem die eben genannten natives gefunden werden können.

-Djava.library.path=build\natives\windows

Mit einer minimal angepassten Launch-Configuration in eclipse wollte ich das Projekt starten, wurde aber mit einer Windows-Fehlermeldung begrüßt, sobald ein Aufruf in den native code ging. Google konnte mir wirklich überhaupt nicht weiterhelfen, denn scheinbar hatte bisher niemand das Problem. Der Hammer: Startete ich das Projekt in der kompilierten Fassung aus der Kommandozeile schien es zu funktionieren.

Die Lösung

Ich hab wirklich alles ausprobiert:

  • Java deinstallieren/installieren.
  • Alle möglichen 32/64bit Kombinationen der natives/eclipse/java ausprobiert.
  • eclipse mit -vm option starten
  • Verschiedene Kombinationen aus JREs im eclipse-classpath.

Irgendwann bin ich dann auf den Trichter gekommen die Prozesse mal mit Process Explorer zu inspizieren um evtl. fehlende oder fehlerhafte JVM-Argumente auszumachen. Pustekuchen.

Ich weiß gar nicht mehr warum, aber aus irgendeinem Grund habe ich dann mal nach offenen File-Handles auf die DLL, die den Fehler verursacht, in Process-Explorer gesucht. Siehe da: Die javaw.exe-Instanz in der mein Projekt lief hat eine DLL aus system32 angezogen und nicht aus dem natives Verzeichnis, das ich angegeben hatte.

Jetzt gibt es zwei Lösungen, eine hat mir geholfen:

  • PATH aufräumen
  • D3DGear in der Systemsteuerung deinstallieren und neustarten

Endlich kann es weitergehen mit den interessanten Problemen. Ich denke übrigens, dass das Problem nicht auf LWJGL beschränkt ist, sondern bei jeder Benutzung von native Code auftreten kann.

ObservableBeans

AutoBeans sind ein gutes, mitgeliefertes Beispiel für Deferred Binding in GWT. Wenn ihr noch nicht die Gelegenheit hattet euch mit dem generieren von Source durch GWT auseinanderzusetzen, ist die Generierung der AutoBean-Implementierung wahrscheinlich ein ziemlich guter Start. Als Ausgangspunkt ist die Klasse AutoBeanFactoryGenerator prima.

Dieser Artikel soll sich aber nicht um AutoBeans drehen, sondern um ObservableBeans. Da geht es im Grunde um normale POJOs, die man überwachen kann, so dass man über Zustandsänderung in Form von Events benachrichtigt wird. Ein Feature was ich in mehreren GWT-Projekten bisher gut hätte gebrauchen können, und eins, dass mir schon länger im Kopf rumgeistert. Aber ich will nicht lange um den heißen Brei rumreden:

Ein Bean-Interface definieren

public interface Actor {

	void setName(String name);

	String getName();

}

Die dazugehörige Factory

public interface ActorFactory extends ObservableBeanFactory {

	ObservableBean create();

	ObservableBean create(Actor actor);

}

Die ObservableBean erstellen

final ActorFactory actorFactory = GWT.create(ActorFactory.class);

final ObservableBean actorObservableBean = actorFactory.create();
final Actor actor = actorObservableBean.as();

Eine Property überwachen

final ObservableProperty nameProperty = actorObservableBean.getProperty(actor.getName());
nameProperty.addPropertyValueChangeHandler(new PropertyValueChangeHandler() {

	@Override
	public void onPropertyValueChange(PropertyValueChangeEvent event) {
		doSomething(event.getOldValue(), event.getNewValue());
	}

});

Sobald jetzt die Property einen neuen (anderen) Wert zugewiesen bekommt, wird ein Event gefeuert.

actor.setName("Sheldon"); 	//Event[oldValue=null, newValue="Sheldon"]
actor.setName("Sheldon"); 	//No event
actor.setName("Wollowitz"); 	//Event[oldValue="Sheldon", newValue="Wollowitz"]

Weitere Details und das Projekt findet ihr auf GitHub.

Hallo Welt!

@OhNoYouDidnt
public String unescapePseudoEscapedCommasAndSemicolons(String url) {
}

Ich hab jetzt schon eine ganze Weile die Domain und so langsam wird es Zeit, diese auch zu nutzen. Also warum sollte ich mich als Software-Entwickler nicht auch einreihen in die Schlangen unzähliger Blogs? Und selbst wenn es keiner liest, so kann ich zumindest mal ein paar Sachen für mich festhalten. Und wer weiß, vielleicht stolpert ja der ein oder andere mal über einen nützlichen Beitrag.

Woher kommt der Name? Der Name stammt von einer Annotation aus der Google Annotations Gallery, die mir heute gezeigt wurde. Ich hoffe ich bekomme irgendwann mal die ein oder andere Gelegenheit die Annotation oder zumindest eine der anderen einzusetzen.