Posts mit dem Label Java werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Java werden angezeigt. Alle Posts anzeigen

Mittwoch, Januar 13, 2010

Aufräumen löst Probleme

Es gibt Zusammenhänge, die glaubt man kaum.
Unsere Java Applikation hatte plötzlich recht häufig auftretende Probleme mit der Datenbankverbindung.
Wir haben es natürlich auf die neuen Datenbankserver beim Kunden geschoben, aber das war es nicht, denn bald hatte auch ein anderer Kunde ähnliche Effekte.

Morgens beim Anmelden brauchte fast jeder User zwei Versuche, weil der erste ein "Connection reset by peer" aufgrund eines Timeouts bekam. Und nach der Mittagspause dann nochmal.
Also hat ein Arbeitskollege mal etwas gesucht und ist auf folgendes gestossen:
Man muss das Tempverzeichnis (%TEMP%) aufräumen.

Bitte was? Ganz recht. In einer Reihe von Versuchen konnten wir den Zusammenhang deterministisch belegen. Wir hatten zwischen den Versionen auf einen neuen Oracle JDBC Treiber
(für Java 1.5) umgestellt, der anscheinend aus unerfindlichen Gründen inmitten des Logins versucht eine Datei mit irgendwelchen Daten zu speichern (Session Keys oder so). Das heißt also nicht etwa bevor die Verbindung aufgebaut wird oder nachdem die Anmeldung durch ist. Nein. Mitten im Login Handshake wird diese Datei ins Tempverzeichnis geschrieben.

Und wenn das Verzeichnis recht voll ist, macht sich Windows den Spaß schon mal über eine Minute für die Indizierung zu brauchen bevor es weitergeht. Überhaupt scheint XP mit jedem Patch in den Grundfunktionen langsamer zu werden. Microsoft will wohl 7 verkaufen.
Jedenfalls ist bei einigen Datenbanken der Timeout für diese Aktion zu kurz. Aber wenn man das Tempverzeichnis aufgeräumt hat und 2GB Datenmüll entfernt hat, läuft es wieder.

Leider scheint es in Windows keine Funktion zu geben, mit der man diese Bereinigung durchführen könnte. Und Programme wie Crap Cleaner will ich unbedarften Usern nicht in die Hand geben. Da ich das aber gelegentlich benutze und mein Tempverzeichnis nur 200 MB (unaufgeräumt) belegte, konnte ich die Probleme bei mir nie nachstellen.

Mittwoch, Dezember 16, 2009

Mein eigener JDT Plugin

In den letzten zwei Wochen durfte ich mich bei der Arbeit mit der Entwicklung eines Plugins für die Entwicklungsumgebung Eclipse befassen.
Für jedes (Teil-)Feature habe ich ungefähr einen Tag gebraucht, wovon circa die Hälfte auf die Suche nach den jeweils für die Umsetzung benötigten Extension Points draufging.

Jetzt kann man diverse für unsere Firma interessante Probleme sofort beim Speichern erkennen und *Fanfare* die meisten auch mit einem QuickFix sofort beheben.

Ich bin relativ stolz auf mich. Das von mir gebastelte Zwischenframework ermöglicht die Umsetzung einer Java Fehlersuche, mit eigener Konfiguration und QuickFix (mit "Select All" Unterstützung) in ein paar Stunden.
Alle Fehlersuchen sind einzeln deaktivierbar. Und um grobe Performanceschnitzer zu finden, kann man die Ausführungszeiten der Scanner protokollieren lassen.

Als nächstes überlege ich mir mal, ob ich für mein Templategenerator XML Format einen Editor gebaut kriege, der die Daten-, Template- und Ausgabedatei verbindet.

Mittwoch, November 05, 2008

Hilfe gesucht

Ich habe eine interessante Idee für ein online Spiel.
Da ich aber immer wenn ich an einem größeren Projekt alleine arbeite bald die Lust verliere, brauche ich noch

1 Programmierer mit Erfahrungen mit Hibernate. Angepeilte Umgebung ist Java mit JSF und oder JSP (wenn sich keiner findet auch PHP).

1 Menschen mit guten musiktheoretischen Kenntnissen. Es geht um maschinell erzeugte Melodien.

Nicht dass wir uns missverstehen - es handelt sich um ein Hobbyprojekt und Geld gibt's nicht.
Falls wider erwarten irgendwann einmal Geld dabei herausspringt, wird fair geteilt, aber daran denke ich jetzt noch nicht.

Donnerstag, September 25, 2008

Kleinste gemeinsame Obermengen

Heute hatte ich bei der Arbeit ein interessantes Problem.
Es fing ganz harmlos mit "Business Logik" an und reduzierte sich je mehr ich darüber nachdachte auf schlichte Mengenlehre.

Das Kernproblem ist folgendes und sei dem geneigten Leser zur Implementierung überlassen:

Man hat eine Gesamtmenge A von Mengen B.
Diese Mengen B enthalten eventuell gleiche Elemente.
Aufgabe ist es nun "kleinste gemeinsame Obermengen" zu finden. D.h. wenn zwei Mengen gleiche Elemente enthalten, müssen sie vereinigt werden.

Beispiel:
a: [1]
b: [2, 3]
c: [4, 5, 6]
d: [7, 8]
e: [9]
f: [1, 3, 4, 5]

=>
[1, 2, 3, 4, 5, 6], [7, 8], [9]
d.h. a, b, c und f werden vereint. d und e bleiben separat.

Ich habe das ganze mit Maps, Sets und einer Rekursion gelöst. Und irgendwie habe ich das Gefühl, dass es eine einfachere Lösung geben muss.
Vor allem ist mir auf dem Nachhauseweg aufgefallen, dass ich die ganze Aktion vermutlich auch noch für eine andere Gruppierungsebene machen muss...

Ruby

Ich habe jetzt angefangen mir die Programmiersprache Ruby anzusehen.
Koryphäen wie Martin Fowler schwärmen davon. Und das will etwas heißen, denn er hat ein paar wunderbare Bücher über Programmierung geschrieben. Vor allem den Klassiker "
Refactoring: Improving the Design of Existing Code".
Außerdem ist es die Modesprache des Tages.

Und mein erster Eindruck ist: furchtbare Hackersprache. Javascript reloaded.

* Man kann abkürzen wo man will. D.h. Methodenaufrufe brauchen nicht einmal die sonst üblichen Klammern, wenn man keine Parameter hat.
* Membervariabelen werden nicht zwingend deklariert. Sie entstehen quasi bei Benutzung.
* Methodendeklarationen sind arschhäßlich und erinnern mich an 70er Jahre Sprachen. Anstelle von Klammern wird mit "end" gearbeitet. *schauder*
* Überhaupt scheinen die Entwickler eine Allergie gegen Klammern gehabt zu haben, was bei if und ähnlichen Kontrollstrukturen eher zur Verwirrung beiträgt.

Viele Blogs, in denen Ruby gelobt wird, pochen darauf, dass andere Sprachen viel zu unflexibel seien, zu viel Tipparbeit erfordern und den Blick auf das Wesentliche durch zu viel Ballast ("boiler plate code") verschleiern.

Man kann den Code in Ruby zwar durch diverse Umdefinitionen klein halten, aber m.E. leidet die Lesbarkeit sehr darunter. Vermutlich soll der Name von einer gewissen Verwandtschaft mit Perl zeugen. Sozusagen Perl x C++ mit syntaktischen Anlehnungen an Pascal.
Und ich kann mir wirklich nicht vorstellen, wie man da bei einem größeren Projekt noch durchblicken soll. Sobald die ersten Umstrukturierungen kommen, verliert man den Durchblick.

Ich finde Ruby noch unleserlich und verwirrend, aber so ging es mir mit Java 1.1 anfangs auch.
Mal sehen ob sich der Eindruck ändert, wenn ich erst mal etwas damit gemacht habe.

Freitag, Juni 15, 2007

& = und

Jetzt habe ich mal wieder an meinem Templategenerator (genannt DBXML) gebastelt, der aus XML Daten und Templates beliebige andere Textdateien zaubert. In meinem Falle Source Code und SQL Skripte.

Ich wollte einen IF-Tag mit Bedingungsaudrücken haben, der einfache Vergleiche (=, !=), die üblichen logischen Operatoren (&, |, !) und Klammerungen beherrscht. Und in weniger als zwei Stunden hatte ich mir einen Parser für diese Ausdrücke gestrickt, der 1a funktioniert.

Nur, als ich es dann ausprobiert habe, fiel mir auf, dass '&' (logisches Und) in XML ein Sonderzeichen (aka Entity) einleitet. Gna. Daran hätte ich auch früher denken können.
D.h. ich muss meine Bedingungen
derzeit so schreiben:
"${table.name} != definitions & ${column.type} = ID"

Mist, Mist, Mist. Kennt jemand noch ein anderes ASCII Symbol für ein logisches Und?

Dienstag, Juni 12, 2007

Nieder mit den Apachen!

Meine Güte, gehen mir diese Open Source Projekte auf den Keks.
Und mit Open Source meine ich insbesondere Apache. Ich hatte in den letzten Wochen mehrfach das Vergnügen mich in einige dieser Programme einarbeiten zu dürfen.

Mangels brauchbarer Dokumentationen musste ich oft auf kleinste Hinweise in Foren und Newsgroups zurückgreifen.
Und da bekommt man gelegentlich Diskussionen der Entwickler darüber mit, ob man die kurz nach Release als eklatant buggy erkannte neueste Programmversion überhaupt noch mal korrigieren oder gleich einen Versionssprung machen soll (um dann ein Jahr später ein komplett neues verwanztes Produkt zu veröffentlichen). Beides zu tun und Fehlerkorrekturen in beiden Zweigen nachzuziehen - wie es jeder normale Programmierer tun würde - kommt offenbar niemandem in den Sinn.

Die fehlende Dokumentation hat Methode, denn über den Verkauf von Büchern oder PDF Dokumenten macht man das Geld, um die Programmierer bei der Stange zu halten. Genau wie bei Oracle, die früher damit den großen Reibach gemacht haben, dass man sich Consultants bestellen musste, um ihre kryptischen Konfigurationsfeatures zum Laufen zu kriegen. So weit sind also Open Source und Marktführer doch nicht auseinander.

Oder man stößt wieder und wieder auf Bugzilla (den häßlichsten Bugtracker der Welt) und liest als Fehlermeldung genau das Problem, das man selbst mit dem Programm hat. Aber der Fehler war von 2002 und ist immer noch als "neu" und Prio 1 eingestuft. Prio 1 wird sicherlich bald behoben...
Werden die Projektbeteiligten eigentlich dafür bezahlt, auf Fehlermeldungen nicht zu reagieren? Oder besser noch, die Meldung auf "wird nicht behoben" zu setzen?

Bei vielen dieser Projekte bin ich mir sicher, dass ich die Kernfunktionalität in weniger als einer Woche selbst programmieren kann. Absoluter Dreck wie log4j kann nur deswegen nicht durch einen vernünftigen Logger abgelöst werden, weil der Mist in allen Apache Produkten verwendet wird. Gut, so schlimm ist log4j gar nicht. aber es ist auch nicht einmal annähernd gut. Und vor allem war in jeder Firma, in der ich bisher gearbeitet habe, immer der größte Schaumschläger dafür verantwortlich, dass log4j benutzt wurde. Diese Leute werden ca. ein halbes Jahr später gefeuert, aber dann hat man sich mit log4j abgefunden.

Und dann gibt es noch die Projekte, die eine super Website haben, in allen Zeitschriften auf die Titelseite kommen und bei jedem guten Namedropping vertreten sind. Aber wenn man sich dann endlich mühsam eingelesen hat, stellt man fest, dass sie entweder fast nichts können oder eine uralte Idee gerade mal rudimentär verwirklichen.

Zum ausgleichenden Abschluss noch der Hinweis, dass trotz der Hornochsen, die hinter den Programmen stehen, die meisten davon ihren Zweck gut erfüllen (Apache, Tomcat, ant).

Und auch bei "Kaufsoftware" gibt es schwarze Schafe, die bei jeder Abweichung vom goldenen Pfad abstürzen und sich hauptsächlich darin von einem Hobbyprojekt unterscheiden, dass sie durch einen Obfuscator gejagt wurden und mich damit nur daran hindert, den unfähigen Programmieren gezielte Hinweise auf die Problemstellen geben zu können.

Ich hasse andere Menschen.

Montag, September 11, 2006

new String(string) benutzen nur Anfänger?

Kann man sich in Java mit vielen 4 Zeichen langen Strings ein Speicherproblem schaffen?
Klar, wenn man ca. (Speichergröße in Byte / 4) Strings hat.

Weit gefehlt.
Es geht auch anders, wenn man nicht alles über Strings weiß.

Ein Beispiel, das uns ca. 3 Manntage Forschungsarbeit gekostet hat:
Man importiert eine mehrere GB große Datei Zeile für Zeile, parst die Zeilen in die Datenbank und merkt sich nur die 4 Zeichen langen Kennziffern der Zeilen, damit man doppelte Aktionen vermeiden kann.

Was gibt es da über Strings zu wissen? Und wo soll der Speicher verloren gehen, wenn man die Zeile nur innerhalb der Schleife kennt?

Ein String ist ein Objekt, das seinen Text als Auszug aus einem char[] speichert. Wenn man jetzt die ca. 2 KB langen Zeilen der Importdatei
mit substring() zerlegt, werden die Substrings nicht mit einem neuen char[] erzeugt, sondern zeigen auf den gleichen Array mit einem entsprechenden Offset. Eine super Idee, um Speichermüll zu vermeiden.
Aber wenn man - wie wir - einen der Substrings dauerhaft im Speicher hält (Map, etc.), behält man auch dauerhaft den dahinter hängenden char[]. Und das führt zu 2KB unnötigem Speicherverbrauch pro Zeile.

Die Lösung des Problems sieht dann aus wie Anfängercode:
String kennziffer = new String(zeile.substring(0,4));
Durch new String() wird tatsächlich auch ein neuer char[] für die 4 Zeichen erzeugt und schon hat man keine Probleme mehr.

new String(string) ist normalerweise vollkommen nutzlos, weil Strings unveränderlich sind, und sollte aus Speichergründen nicht verwendet werden. Aber wenn man große Strings mit substring() zerlegt, sollte man es in Erwägung ziehen.