Aktuelle neue Alben im März und April

Im Moment gibt es für Freunde der leichten Unterhaltung einiges auf die Ohren: Pennywise, No Use For A Name, Millencolin und Good Riddance haben jeweils ein neues Album am Start!

Pennywise haben sich entschieden, ihr Album “Reason to believe” kostenlos (!) im Internet zu veröffentlichen und ich kann nur jedem raten, es herunterzuladen, denn es sind einige Ohrwürmer dabei und man kann es durchaus von vorne bis hinten durchhören, ohne langweiligen Songs lauschen zu müssen. Eine absolute Empfehlung. Die letzte Download-Zahl, die ich gelesen habe, lag bei 500.000! Absolut verdient. Und “The Western World” ist direkt mal auf Platz 34 der Amerikanischen Charts eingestiegen (und es ist nicht der beste Song des Albums!).

Eine absolute Enttäuschung ist dagegen “The Feel Good Record Of The Year” von No Use For A Name. Erinnert mich irgendwie an das letzte Album von Yellowcard: Der erste Song (“Biggest Lie”) ist ein Knaller und danach kommt nur noch (langsamer, softiger, leider auch nicht melodischer) Müll. Schade eigentlich.

Ich glaube ähnlich wird es bei Millencolins “Machine 15” aussehen. Der erste Song “Detox” ist schonmal sehr “mainstreamig”. Was soll das eigentlich? Wie können zwei ehemals so gute Bands wie No Use und Millencolin, denen ich meine ersten Jahre des Punks verdanke, zu solchen Sell-Outs werden… tststs…

Da bleibt nur noch der Ausweg in Erinnerungen zu schwelgen und dem Live Album von Good Riddance (das gleichzeitig leider das letzte der Band ist) zu lauschen. All the Best Songs wäre ein passenderer Name gewesen als “Remain in Memory”… *schnüff*

Wie gut, dass es auch ein paar neue Bands gibt, die es sich anzuhören lohnt. Wie z.B. A Wilhelm Scream, die ein kleines Video zum Kracher “I Wipe My Ass With Showbiz” veröffentlicht haben. Inklusive Seitenhieb auf die (oben genannten) Sell-Outs 😉

Und für die nahe Zukunft sind auch schon neue Alben von Goldfinger, Pulley und (endlich!) Craig’s Brother angekündigt. Da wird jawohl was Schönes dabei sein!

Anonymen Read-Only-Zugriff für ein Subversion-Repository einrichten

Geht ganz einfach: In der entsprechenden Konfigurationsdatei des Apache vor Require valid-user die folgende Zeile einfügen und den Apache neustarten (siehe Server Configuration im SVNBook):

Satisfy Any

In die Access-Konfigurationsdatei (meist access.conf) von Subversion für das gewünschte Repository die folgende Zeile einfügen:

* = r

Das war’s!

Einheitliche Textausgabe mit Java auf der Konsole und in JSP

Ich habe heute mal ein wenig mit JSP rumgespielt und nach einer Lösung gesucht, Textausgaben per Sytem.out.println() auch in einer JSP auszugeben. Standardmäßig landen solche Ausgaben nämlich in JSP nicht im HTML-Text, sondern im Tomcat-Logfile.

Ich habe eine einfache Anwendung, die Textausgaben erzeugt. Diese soll sowohl über die Konsole, als auch über eine JSP-Seite aufgerufen werden können. Gebe ich die Texte nun per Sytem.out.println() aus, erscheinen sie auf der Konsole, aber nicht in der JSP (hier muss out.println() verwendet werden).

Die sauberste Lösung wäre sicherlich, die Ausgaben aus den “arbeitenden” Klassen zu entfernen und je nach Umgebung einen geeigneten Konsolen- bzw. JSP-View für die Textausgaben zu verwenden. Aber zum Rumspielen ist mir das zuviel Aufwand 🙂

Die Lösung für mein Problem sieht nun so aus: Ich habe einfach alle Sytem.out.println()-Ausgaben durch Writer.println() ersetzt, wobei Writer eine statische Klasse ist, die ein Attribut vom Typ PrintWriter besitzt und alle Anfragen an println() an dieses weiterleitet. Mittels Writer.setWriter(PrintWriter pw) kann dieser Writer nun je nach Umgebung auf ein geeignetes Ausgabeobjekt gesetzt werden: Auf der Konsole wäre das PrintWriter(System.out) und in JSP PrintWriter(out).

Das Ganze funktioniert, da der Konstruktor von PrintWriter polymorph ist und sowohl mit einem java.io.Writer (von dem JspWriter (Objekt out unter JSP) abgeleitet ist), als auch mit einem java.io.OutputStream (von dem PrintStream (Objekt System.out der Konsole) abgeleitet ist) aufgerufen werden kann.

Beispiel

Klasse Writer:
import java.io.PrintWriter; public class Writer { private static PrintWriter s_pw; public static void setWriter(PrintWriter pw) { s_pw = pw; } public static void println(Object o) { s_pw.println(o); } public static void println() { println(""); } }

Textausgabe in irgendeiner Klasse:
public void gibWasAus() { Writer.println("Das ist der auszugebende Text."); }

Aufruf der obigen Klasse auf der Konsole in der main():
Writer.setWriter(new PrintWriter(System.out), true); // Instantiieren des Objektes "ausgObj" etc. ausgObj.gibWasAus();

Aufruf der obigen Klasse auf der Konsole in der JSP-Datei:
Writer.setWriter(new PrintWriter(out), true); // Instantiieren des Objektes "ausgObj" etc. ausgObj.gibWasAus();

Mittels XPath in Java Werte aus XML-Dateien lesen

Genauso wie das Validieren von XML-Dateien gegen Schemas ist auch das Auslesen von Werten aus XML-Dateien mittels XPath sehr gut im Internet dokumentiert: z.B. The Java XPath API oder Java, XPath und Namespaces.

Ich erweitere mal mein kleines PlantBuilder-Beispiel um eine einfache Auflistung der IDs aller in der XML-Datei enthaltenen Module:
XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(new PPNamespaceContext()); String xModules = "/pp:ProductionPlant/pp:Modules/pp:Module"; NodeList modules = (NodeList) xpath.evaluate(xModules, doc, XPathConstants.NODESET);
Wichtig ist, dass doc Namespace-aware eingelesen wurde (siehe Zeile 47 im Quelltext) und ein NamespaceContext angelegt wird, da die zu verarbeitende XML-Datei Namensräume verwendet.

Download

Das erweiterte PlantBuilder-Beispiel inkl. benötigter import-Anweisungen und NamespaceContext gibt es hier zum Download: PlantBuilder2.

Und so wird es ausgeführt:

Kompilierung und Ausführung von PlantBuilder2

WDS-Image auf Basis eines Windows XP PCs erstellen

In den letzten Tagen habe ich mich mit den Windows Deployment Services herumgeschlagen. Inzwischen habe ich es nach einigem Rumprobieren und Lesen von zahlreichen Forenbeiträgen endlich geschafft, ein Image von einem Windows XP PC zu erstellen und dieses automatisch an andere PCs zu verteilen. Meine Vorgehensweise basiert hauptsächlich auf diesen drei Artikeln:

Vorgehensweise

  1. PC für WDS-Image vorbereiten (Windows, Treiber und Software installieren)
  2. Computer aus der Domäne entfernen und umbenennen (bspw. in ImagePC)
  3. Inhalt der \Support\Tools\Deploy.cab von der Windows-CD nach c:\sysprep entpacken
  4. Optional: c:\sysprep\setupmgr.exe starten und eine neue sysprep.inf erstellen
    • Keine (!) vollständig automatisierte Installation
    • Computernamen automatisch generieren
    • Die erzeugte sysprep.inf auf den WDS-Server kopieren, da sie später für die automatische Installation benötigt wird
  5. c:\sysprep\sysprep.exe ausführen (“Miniinstallation verwenden” auswählen und “Erneut versiegeln” anklicken)
  6. PC starten und über das Netzwerk (!) booten (bereits vorhandenes “Aufzeichnungsabbild” verwenden)
  7. Den Aufzeichnungswizard durchlaufen und das Image nur lokal auf C:\ speichern
  8. Den PC neu starten, das erstellte Image auf den WDS-Server kopieren und es dort unter ”Installationsabbilder → Clients” hinzufügen

XML-Datei mit Java einlesen und gegen ein Schema validieren

Eine XML-Datei mit Java einzulesen und gegen ein XML-Schema zu validieren ist recht einfach, wenn man weiß wie es geht 😉

Gut, dass es zu diesem Thema einige sehr gute Quellen im Internet gibt (z.B. XML Validation and XPath Evaluation in J2SE 5.0 oder Validation with Java and XML Schema, Part 3). Zuerst habe ich es mit der hier beschriebenen Vorgehensweise probiert: Validating with XML Schema. Kurz gesagt: man holt sich eine DocumentBuilderFactory und konfiguriert sie mittels setValidating(true), um die XML-Datei zu validieren. Dafür muss jedoch in der entsprechenden XML-Datei dann auf das XML-Schema verwiesen werden (mittels schemaLocation), was in meinem Fall zu Problemen beim Auflösen von Pfaden führte (die man aber sicher irgendwie umgehen kann). Darüber hinaus hat die Validierung von Constraints (in meinem Fall unique) nicht korrekt funktioniert, sodass ich den Weg über einen Validator gegangen bin.

Doch zunächst einmal mein Beispiel: Es handelt sich um eine XML-Datei, die (sehr einfach) den Aufbau einer Fertigungsanlage beschreibt (siehe Bild hier: Wegfindung mit dem A*-Algorithmus in Java). Eine ProductionPlant enthält Modules (die Teile der Anlage wie z.B. Förderbänder und Drehteller) und Connections zwischen diesen, die jedoch für mein Beispiel nicht wichtig sind. Jedes Module hat eine (eindeutige → unique) ID.

Der eigentliche Code, der nun die XML-Datei einliest und validiert, ist der folgende:

// create a factory that understands namespaces and validates the XML input DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); // read the XML file DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new File("SamplePlant.xml")); // create a SchemaFactory and a Schema SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Source schemaFile = new StreamSource(new File("ProductionPlant.xsd")); Schema schema = schemaFactory.newSchema(schemaFile); // create a Validator object and validate the XML file Validator validator = schema.newValidator(); validator.validate(new DOMSource(doc)); System.out.println("XML file successfully validated.");

Download

In eine Klasse gepackt und um die import-Anweisungen und einen (einfachen) ErrorHandler ergänzt, gibt es das Ganze hier zum Download: PlantBuilder.

Wie folgt kann das kleine Programm gestartet werden:

Kompilierung und Ausführung von PlantBuilder

Umstellung von RIS auf WDS

Da auch nach mehreren aufwändigen Versuchen die Installation der Esprimo E5925-PCs mittels RIS nicht funktioniert (Bluescreen nach dem ersten Neustart, wahrscheinlich auf Grund fehlender SATA-Treiber, die ich allerdings ins Image integriert habe wie bei reckenpferd.de und zerbit.de beschrieben), habe ich mich heute dazu entschlossen, das Ganze mit den Windows Deployment Services (WDS) auszuprobieren. Diese sind seit Windows Server 2003 SP2 mit an Bord und können recht schnell installiert werden. Ich habe diese sehr gute Anleitung befolgt: Deploy XP Images in the Computer Lab with Windows Deployment Services on Server 2003.

Nach der Installation und dem Einbinden der ersten Images (und dem 1GB großen Download von Microsoft 😉 ) habe ich dann einfach mal einen Test gemacht, um zu schauen, ob das Booten über das Netzwerk klappt. Dazu musste ich die DHCP-Einstellungen ein wenig anpassen, da ich WDS nicht auf dem gleichen Server laufen lasse, wie vorher RIS. Aufgrund einiger Forenposts fand ich schließlich die richtigen Einstellungen für die DHCP-Optionen 066 und 067 heraus:

RIS WDS
066 Hostname des Startservers IP-Adresse des RIS-Servers Hostname (!) des WDS-Servers
067 Name der Startdatei OSChooser\I386\startrom.com boot\x86\pxeboot.com

Der erste Test lieferte dann folgende Fehlermeldung nach zunächst erfolgreichem Netzwerkboot:

Windows failed to start...

File: \Boot\BCD

Status: 0xc000000f

Info: An error occurred while attempting to read the boot configuration data.

Die Lösung fand ich im Technet Forum. Der Name der Startdatei muss auf boot\x86\wdsnbp.com geändert werden. Der folgende Screenshot zeigt nun die korrekten Einstellungen.

DHCP-Einstellungen für WDS

Nachdem der erste Bootvorgang mit dem Windows Vista PE-Image über WDS nun erfolgreich war, habe ich mit sysprep.exe mein System für das Erstellen eines Images vorbereitet, den PC neugestartet, mein eingerichtetes Capture-Image gebootet und den Capture Wizard durchlaufen. Als ich dann auf dem Bildschirm “Image Capture Destination” den Servernamen des WDS-Servers eingab und “Connect” anklickte, passierte mehrere Minuten gar nichts und irgendwann kam die Meldung The Network location cannot be reached. Wie ich mal wieder im Technet-Forum gelesen habe, kann man mit SHIFT-F10 eine Kommandozeile öffnen, in die ich dann auch gleich ipconfig /all eingab. Und schon wurde das nächste Problem offensichtlich: Es konnte keine Netzwerkkarte gefunden werden!

Die Lösung fand ich bei midteq.co.uk. Die fehlenden Netzwerkkartentreiber konnte ich wie folgt in das Image integrieren:

<em><a href="http://support.fujitsu-siemens.de/de/support/downloads.html" title="FSC Supportseite">LAN-Treiber</a> nach lan\ kopieren</em> mkdir build_install imagex /apply "AufzeichnungsabbildXP.wim" 1 build_install peimg /inf=lan\e1e5132.inf build_install\windows peimg /inf=lan\e1e6032.inf build_install\windows peimg /inf=lan\e1g6032.inf build_install\windows peimg /inf=lan\e1q6032.inf build_install\windows peimg /inf=lan\e1q5132.inf build_install\windows peimg /inf=lan\e1000325.inf build_install\windows imagex /capture build_install AufzeichnungsabbildXPInklLAN.wim "Aufzeichnungsabbild Windows XP inkl. LAN-Treiber" /boot /compress max

Nun konnte ich wie in obiger Anleitung beschrieben vom präparierten PC ein Image erstellen lassen und es auf dem WDS-Server speichern.

Ant-Buildscript für Tomcat-Applikationen

Ich arbeite mich gerade ein wenig in die Entwicklung von Webapplikationen mit Java und JSP auf dem Apache Tomcat ein und habe mir mal schnell ein kleines Ant-Buildscript gebastelt, das Applikationen direkt auf einem (Remote-)Server installieren kann. Es basiert auf dem Beispielscript aus der Tomcat-Dokumentation und kompiliert/installiert die Anwendung Simplex, die ich zu Testzwecken entwickle, sowohl lokal als auch auf dem Tomcat-Server: build.xml

Die folgende Ordnerstruktur muss vorliegen:

Ordnerstruktur der Simplex-Applikation

Die verwendeten Properties werden in der build.properties definiert:

app.name=Simplex app.version=0.1 app.path=/${app.name} src.home=${basedir}/src bin.home=${basedir}/bin build.home=${basedir}/build dist.home=${basedir}/dist release.home=${basedir}/release web.home=${basedir}/web docs.home=${basedir}/docs manager.url=<a href="http://tomcat-server:8080/manager" class="linkification-ext" title="Linkification: http://tomcat-server:8080/manager">http://tomcat-server:8080/manager</a> manager.username=administrator manager.password=passwort catalina.home=Z:\

Z:\ ist dabei ein Netzlaufwerk auf meinem Entwicklungsrechner, das mit dem Tomcat-Installationsverzeichnis auf dem Server verbunden ist.

Active Directory mit der PowerShell auslesen

Für einige PowerShell-Scripte (die ich auch hier veröffentlichen werde, sobald sie fertig sind) brauche ich eine Liste aller Computer, die in unserem Active Directory bekannt sind. Nichts einfacher als das:
# Returns a list of all computers (running Windows XP) in the local LDAP function GetComputersFromLDAP() { trap { write-host ("Error while retrieving computers from LDAP: " + $_.exception.message) -foregroundcolor "red"; return $false; } $pcs = @(); $ldapSearcher = new-object directoryservices.directorysearcher; $ldapSearcher.filter = "(objectclass=computer)"; $computers = $ldapSearcher.findall(); foreach ($computer in $computers) { if ($computer.properties["operatingsystem"] -eq "Windows XP Professional") { $pc = "" | select-object Name; $pc.Name = $computer.properties["name"]; $pcs += $pc; } } return ($pcs | sort-object Name); }

Über das zurückgegebene Array kann man dann wie folgt iterieren:
foreach ($pc in $pcs) { write-host $pc.Name; }

RIS-Installation eines ESPRIMO E5925 mit Intel 82562ET Netzwerkchips

Ich liebe RIS-Installationen! Insbesondere, wenn die zu installierenden PCs mit Netzwerkchips von Intel ausgestattet sind. Bislang gab es bei uns jedesmal Probleme mit den Intel-Chips. Aktuelles Beispiel ist der ESPRIMO E5925 von Fujitsu-Siemens, der einen Intel 82562ET-Chip verbaut hat. Wie erwartet schlug die RIS-Installation sowohl mit den Treibern von der FSC-CD als auch von der FSC-Website fehl. Ich verstehe nicht, warum die es nicht schaffen, ihren Business-PCs die korrekten RIS-Treiber beizulegen…

Nun denn. Nach einer ausgiebigen Suche im Netz und zahlreichen Versuchen mit unterschiedlichsten Treibern, entschloss ich mich, die FSC-Hotline zu bemühen. Dort erfuhr ich dann, das in unseren PCs nicht der Chip im Einsatz ist, den ich angenommen hatte (PHY 82566), sondern der erwähnte 82562ET. Mit den Treibern von hier klappte dann auch die Installation: Network Adapter Drivers 82562ET.

Ich musste nur noch das Standard-Vorgehen durchführen, das ich hier bereits beschrieben habe: RIS-Installation von Windows mit einer Marvell Yukon 88E8055 Netzwerkkarte.