kurt sparber’s weblog

Softwareentwicklung, Architektur, Projektmanagement

Blog umgezogen

Verfasst von sparber am Mai 24, 2009

Dieser Blog ist umgezogen, weiter gehts auf www.kurtsparber.de

Veröffentlicht in 3D Java, Datenbanken, Groovy, Java, JavaFX, MMO, ejb3 | Kommentar schreiben »

MMO mit Java/J2EE? (Teil 2)

Verfasst von sparber am März 31, 2009

Aktives Rendern zur Darstellung von Animationen

Zur Darstellung der Clientgrafiken und Animationen für den MMO Prototyp verwende ich ein eigenes Canvas, welches mit einem Thread die Grafiken in kurzen Zeitabständen zyklisch neuzeichnet, dadurch lassen sich durch den Austausch der Grafiken animationen erzielen. Der Austausch kann an die Eingabe des Clients, oder an die Aktualisierung der Spieldaten des Servers für NSP’s (Nicht-Spieler Charaktere) gekoppelt sein.

Exemplarische (nicht vollständige) Animationssequenz

Exemplarische (nicht vollständige) Animationssequenz

Mein bisheriges Canvas rief in run()-Methode des Threads periodisch repaint() auf. Da repaint() aber keinesfalls garantiert von der JVM aufgerufen wird, sondern in eine Queue eingestellt wird, ist eine reibungslose Animationsdarstellung nicht gewährleistet. Hier ergibt sich eine Verbesserung durch den Einsatz des sog. Active Rendering, die (vereinfachte) Implementierung dazu sieht folgendermaßen aus:


1 private void activeRendering() {
2   Graphics g = this.getGraphics();
3   if (g != null) {
4     g.drawImage(offscreenImage, 00null);
5     Toolkit.getDefaultToolkit().sync();
6     g.dispose();
7   }
8 }

Toolkit.getDefaultToolkit().sync(); Stellt die Aktualisierung des Displays unter Linux sicher. (Quelle: Killer Game Programming, Andrew Davidson)

Veröffentlicht in Java, MMO | Kommentar schreiben »

Oracle XE: Ora-12638

Verfasst von sparber am März 17, 2009

Gelegentlich kann es bei einer Oracle XE unter Windows zu folgendem Fehler kommen:


UDI-00008: Vorgang hat ORACLE-Fehler generiert 12638
ORA-12638: Abrufen der ID-Daten nicht erfolgreich



In diesem Fall trat der Fehler im Zusammenhang mit einem Datenimport auf. Erfahrungsgemäß und durch Berichte anderer User kann das Problem mit einem Neustart des Datenbankservices behoben werden. Sollte dies jedoch nicht der Fall sein, so kann das Ändern der Einstellung SQLNET.AUTHENTICATION_SERVICES= (NTS) auf SQLNET.AUTHENTICATION_SERVICES= (NONE) in der Datei sqlnet.ora das Problem beseitigen. Die Änderung bewirkt, dass nicht mehr die native Windows Security beim Login verwendet wird, sondern nur mehr User und Passwort.

Veröffentlicht in Datenbanken | Kommentar schreiben »

MMO mit Java/J2EE? (Teil 1)

Verfasst von sparber am März 11, 2009

MMO, oder Massively Multiplayer Online Games auf Basis von Java und J2EE? Die Antwort auf diese Frage werde ich in einer Reihe von Artikeln versuchen zu beantworten. Ziel ist eine Machbarkeitsstudie auf Basis eines Prototypen zu entwickeln.

1.1 Einführung

Ein Massively Multiplayer Online Game ist ein Computerspiel, welches ausschließlich über das Internet gespielt werden kann und bei dem gleichzeitig mehrere hundert oder tausend Spieler sich in einer persistenten Spielumgebung treffen und interagieren können. Vertreter bekannter Spiele sind z.B. World of Warcraft, Guildwars oder Warhammer Online.

1.2. Architektur, Komponenten

Ein MMO Game besteht grob aus den Schichten Präsentation (Client), Geschäftslogik (Server) und Datenhaltung (Server), also der klassischen Architektur die mit J2EE realisierbar ist. Folgende Grafik beschreibt die Architektur eines MMO Games:

MMO Architektur

MMO Architektur

Clientseite
Die Präsentationsschicht wird durch den Gameclient repräsentiert. Der Gameclient beinhaltet grob folgende Funktionen:

  • Login Funktionalität, zum Einloggen in die Spielwelt
  • Patch Funktionalität, zum automatischen Bezug und Installation von Softwareupdates
  • Darstellung der Spielwelt und der Interaktionen

Serverseite
Die Serverseite umfasst eine Reihe von Servern mit unterschiedlichen Aufgaben. Die folgende Trennung ist aufgrund der Lastverteilung üblich und wird bei den bekannten MMO’s so praktiziert:

  • Accountserver: Üblicherweise mit Web-basierter Oberfläche zur Verwaltung der Accountdaten, abgelegt in der Accountdatenbank
  • Loginserver: Server zum Überprüfen der Accountdaten und des Patchstandes
  • Sessionserver: Server zum Überprüfen der Gültigkeit der aktiven Session und zur Weiterleitung der Anfragen an den Patch- und Gameserver
  • Patchserver: Server zur Verteilung von Softwareupdates, hier sind mehrere Möglichkeiten denkbar, der Download von Patches über http oder ftp. Auch verteilte Ansätze sind denkbar, so benutzt World of Warcraft Bittorrent als Verteilungssystem.
  • Gameserver: Der eigentliche Spielserver, der die Spielewelt hostet und die Interaktionen der Spieler verwaltet und die Spielzustände in der Game-DB festhält.

1.3. Ausblick

Vorweg würde ich behaupten, dass sich J2EE für die Umsetzung eines MMO’s prinzipiell eignet, die entscheidende Frage stellt sich meines Erachtens, ob eine akzeptable Performance des Gameservers erreicht werden kann oder nicht. Von dieser Fragestellung ist die Anzahl der gleichzeitig bedienbaren Clients pro Server abhängig und damit beantwortet sich die Frage, ob ein MMO realisiert werden kann.

Veröffentlicht in Java, MMO | Kommentar schreiben »

jClaim – ICQ mit Java

Verfasst von sparber am März 9, 2009

Freie ICQ Implementierungen gibt es mittlerweile einige, jedoch kaum welche in Java. Ein Vertreter ist jClaim, neben einer Bibliothek zum Erstellen einer eigenen Anwendung bietet jClaim auch einen fertigen Client, der direkt über Webstart gestartet werden kann. Ein simpler Client ist schnell realisiert:


01 package messaging;
02 
03 import com.itbs.aimcer.commune.joscar.ICQConnection;
04 import com.itbs.util.GeneralUtils;
05 import controller.MessengerGroupFactory;
06 import controller.MessengerContactFactory;
07 import controller.LogEventHandler;
08 
09 public class JavaICQ {
10 
11   public static void main(String[] argsthrows Exception {
12     try {
13       ICQConnection conn = new ICQConnection();
14       conn.assignGroupFactory(new MessengerGroupFactory());
15       conn.assignContactFactory(new MessengerContactFactory());
16       conn.setUserName("icqnumber");
17       conn.setPassword("icqpass");
18       conn.addEventListener(new LogEventHandler());
19       conn.connect();
20       while (true) {
21         GeneralUtils.sleep(60 60 1000);
22       }
23     catch (Exception e) {
24       throw new RuntimeException(e);
25     }
26   }
27 
28 }

Statt des LogEventHandlers kann auch der BotEventHandler, der standardmäßig in der Bilbliothek enthalten ist, verwendet werden.
Bei der Einfachheit dieser Implementierung bleibt es aber auch, so ist es z.B. mit der Bibliothek derzeit nur möglich vom Online Status auf den Away Status zu schalten. Die umfangreichen Funktionen, die der offizielle ICQ Client bietet, sind mit jClaim leider nicht zugänglich.

Veröffentlicht in Java | Kommentar schreiben »

Oracle XE: ORA-12519

Verfasst von sparber am Februar 6, 2009

Gelegentlich kommt es beim Einsatz eines Oracle XE Datenbanksystems zu dem Fehler ORA-12519, dies kann sich mit Java folgendermaßen äußern:


java.sql.SQLException: Listener refused the connection with the following error:
ORA-12519, TNS:no appropriate service handler found
  at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
  at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:131)
  at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:197)
  at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:525)
  at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:413)



Dies kann an der geringen Voreinstellung von üblicherweise 20 für die Anzahl an Sessions liegen. Das Problem kann dadurch gelöst werden, indem die Parameter sessions und processes erhöht werden. Um dies zu erreichen sind folgende Kommandos zu tätigen:


alter system set processes=100 scope=spfile;
alter system reset sessions scope=spfile sid='*';

Die Kommandos können im Webinterface der Administrationsoberfläche unter dem User System ausgeführt werden. Nach einem Neustart der Datenbank sollte das Problem behoben sein. Trotz dieser Möglichkeit den Fehler zu umgehen sollte ein Blick in die Applikation geworfen werden, um die Ursache für den Sessionverbrauch festzustellen.

Veröffentlicht in Datenbanken | Kommentar schreiben »

Levenshtein Distanz mit linearem Speicherverbrauch

Verfasst von sparber am Januar 30, 2009

Folgendes Groovy Skript berechnet die Levenshtein Distanz zweier Zeichenketten. Die Levenshtein Distanz ist ein Maß bezüglich der Operationen Ersetzen, Einfügen und Löschen, um die Gleichheit beider Zeichenketten zu erreichen. In anderen Worten, die Levenshtein Distanz ist ein Maß für die Ähnlichkeit zweier Zeichenketten. Der Algorithmus benötigt im Gegensatz zur normalen Implementierung nur linearen Speicherplatz.


01 /**
02  * Berechnet die Levensthein Distanz der beiden Strings x und y.
03  
04  @param x String x des Vergleichs, nicht null.
05  @param y String y des Vergleichs, nicht null.
06  @return die Levensthein Distanz der beiden Strings x und y
07  */
08 int linearLD(String x, String y) {
09   int n = y.length();
10   int m = x.length();
11  
12   if (n == 0return m;
13   if (m == 0return n;
14  
15   def T = [];
16   T[00;
17   for (j in 1..n) {
18     T[j= T[j-11;
19   }
20   for (i in 1..m) {
21     def s = T[0];
22     T[0= T[01;
23     def c = T[0];
24     for (j in 1..n) {
25       def sub = s + (x.charAt(i-1== y.charAt(j-11);
26       def del = T[j1;
27       def ins = c + 1;
28       c = Math.min(Math.min(sub, del), ins);
29       s = T[j];
30       T[j= c;
31     }
32   }
33   return T[n];
34 }
35 
36 println linearLD("Lin""Lang");

Das Ergebnis des Aufrufs lautet 2, da zwei Operationen zum Angleichen der Zeichenketten notwendig wären.

Hier der Algorithmus nochmal in Java:


01 public class LinearLD {
02 
03   /**
04    * Berechnet die Levensthein Distanz der beiden Strings x und y.
05    
06    @param x String x des Vergleichs, nicht null.
07    @param y String y des Vergleichs, nicht null.
08    @return die Levensthein Distanz der beiden Strings x und y
09    */
10   public static int linearLD(String x, String y) {
11     int n = y.length();
12     int m = x.length();
13    
14     if (n == 0return m;
15     if (m == 0return n;
16    
17     int[] T = new int[n+1];
18     T[00;
19     for (int j=1; j <= n; j++) {
20       T[j= T[j-11;
21     }
22     for (int i=1; i<=m; i++) {
23       int s = T[0];
24       T[0= T[01;
25       int c = T[0];
26       for (int j=1; j<=n; j++) {
27         int sub = s + (x.charAt(i-1== y.charAt(j-11);
28         int del = T[j1;
29         int ins = c + 1;
30         c = Math.min(Math.min(sub, del), ins);
31         s = T[j];
32         T[j= c;
33       }
34     }
35     return T[n];
36   }
37   
38   public static void main(String[] args) {
39     System.out.println(LinearLD.linearLD("""Tier"));
40   }
41 }

Ein praktischer Anwendungsfall für die Berechnung der Levenshtein Distanz ist z.B. im Falle der automatisierten Zusammenführung von unterschiedlichen Stammdatenbeständen gegeben, in denen etwa Vergleiche auf Personen- oder Ortsnamen durchgeführt werden müssen, und in denen Umlaute unterschiedliche dargestellt (z.B. ü und ue) werden.

Veröffentlicht in Groovy, Java | 1 Kommentar »

Groovy Dateien bedingt löschen

Verfasst von sparber am Januar 25, 2009

Hier ein kleines Groovy Skript um bedingt Dateien zu löschen. Klar gibt es dazu auch Möglichkeiten in einer Kommando Shell, aber die wären einfach nicht groovy ;-)


01 import org.apache.commons.io.FileUtils;
02 
03 destDir = new File("D:/Verzeichnis/Unterverzeichnis");
04 
05 destDir.eachDir {
06   it.eachFile {
07     if (it.length() == 0) {
08       println "Lösche: " + it;
09       FileUtils.forceDelete(it);
10     }
11   }
12 }

FileUtils ist übrigens Bestandteil von http://commons.apache.org/

Veröffentlicht in Groovy | Kommentar schreiben »

JavaFX Kalender

Verfasst von sparber am Januar 25, 2009

Seit mitte Dezember liegt nun JavaFX in der Version 1.0 vor.  Im Fokus der neuen Skriptsprache liegt die schnelle und einfache Erstellung von grafisch aufwändigen Desktopapplikationen. Sun verspricht hier nicht zuviel, die Einarbeitung in die Skriptsprache ist dank der umfassenden Dokumentation und der zahlreichen Beispiele auf http://java.sun.com/javafx/reference/docs.jsp sehr einfach. Als Entwicklungsumgebung für JavaFX empfiehlt sich Netbeans http://www.netbeans.org/features/javafx/index.html, welche neben der gewohnten Editorfunktionalität, wie Syntax Highlighting, Codevervollständigung, usw. auch vorgefertigte Codeteile anbietet, welche vom Entwickler per Drag&Drop eingefügt werden können. Allein die eingebaute Preview-Funktion, die sich während des Entwickelns automatisch aktualisiert führt gelegentlich zu etwas nervigen Stacktraces.

Hier also das Ergebnis meins ersten JavaFX-Skripts:

calendar21

Einige der eingefleischten Java-Entwickler werden mit Sicherheit das Gefühl haben, mit JavaFX eine Art Applet 2.0 vor sich liegen zu haben, während andere wiederum sicher an Java2D erinnert werden. JavaFX ist aber deutlich mehr, insbesondere was neue Sprachkonstrukte wie etwa das Bindings zum Binden von Attributen an Variablen für eine automatische Aktualisierung angeht und gerade bei Animationen seine Stärke zeigt. Die Sprache an sich besitzt einen starken deklarativen Charakter und vermittelt das Gefühl einem Baukasten gleich grafische Basiskomponenten zu einer funktionalen Desktopapplikation zusammenzusetzen. Interessant fand ich die schier unerschöpfliche Auswahl bei vordefinierten Color Konstanten, endlich steht die “Farbe” Transparent zur Auswahl.

JavaFX bietet dem Entwickler die Möglichkeit schnell und einfach grafisch beeindruckende Desktopapplikationen zu erstellen. Ich kann mir vorstellen, dass sich besonders im Mobil-Device Bereich neue Möglichkeiten ergeben. Was jedoch funktional aufwändige Applikationen angeht, bleibt fraglich, ob JavaFX hier eine entscheidende Rolle spielen wird und kann.

Veröffentlicht in JavaFX | Kommentar schreiben »

Java3D auf Vista 64

Verfasst von sparber am Januar 11, 2009

Nachdem meine Versuche die JMonkeEngine auf Grund der darunterliegenden Bibliothek lwjgl mit Vista 64 zu laufen zu bringen gescheitert sind, bin ich für meine Versuche wieder auf Java 3D ausgewichen. Java 3D läuft sowohl mit der 32bit Variante des JDK’s als auch mit der 64bit Variante problemlos auf Vista 64. Wie früher auch ziehen die Beispiele einiges an Prozessorleistung.

Veröffentlicht in 3D Java | Verschlagwortet mit : | Kommentar schreiben »