Slackspace Tutorials
Posted 24.07.2011 by Christian
Ihr kennt das bestimmt, man hat während der Programmierung eines neuen Systems irgendein Problem und denkt sich: “Das hab ich doch schonmal gelöst. Wie ging das nochmal.”
Genau so geht es mir auch öfters. Man wird älter und das Gedächtnis lässt nach ;)
Deshalb bin ich jetzt dazu übergegangen mir den Lösungsweg für bestimmte wiederkehrende Problem aufzuschreiben um die Lösung so jederzeit nachschlagen zu können.
Dazu habe ich eine eigene Seite für Tutorials gebaut und diese unter tutorials.slackspace.de gelauncht. Es geht derzeit hauptsächlich um Java und Spring. Vielleicht hilft es ja dem einen oder anderen auch noch.
Gwt UiBinder mit Java 1.5 verwenden
Posted 24.08.2010 by Christian
Seit neuestem verwende ich den UiBinder von GWT um deklarativ das Layout der GWT-Seiten zu beschreiben. Das funktioniert soweit auch ganz gut und hält vor allem den Quellcode sauber.
Nun, bin ich aber aufgrund von diversen Rahmenbedingen dazu gezwungen eine etwas ältere Version von Java zu benutzen. Nämlich Java 1.5. Normales GWT funktioniert damit auch ohne Probleme. Allerdings seitdem ich den UiBinder verwende bekomme ich immer folgende Exception:
java.lang.VerifyError: (class: com/google/gwt/core/client/Scheduler, method:
Irgendwie kommt also der UiBinder von GWT nicht mit Java 1.5 zurecht. Zum Glück gibt es dafür einen Workaround. Im EntryPoint eurer Applikation muss ein DeferredCommand benutzt werden um Methoden auf dem RootPanel aufzurufen. Wird das DefferedCommand eingesetzt, funktioniert der UiBinder auch mit Java 1.5.
Das ganze sieht dann in etwa so aus:
Java
- public class TestUiBinderGwt implements EntryPoint {
- public void onModuleLoad() {
- DeferredCommand.addCommand(new Command() {
- public void execute() {
- start();
- }
- });
- }
- private void start() {
- //put your code here
- RootPanel.get().add(new TestPage());
- }
- }
Java InstanceOf mit Objekten verwenden
Posted 18.08.2010 by Christian
Heute hatte ich ein kleines Java Problem. Stellt euch mal vor ihr habt 3 Klassen. Eine abstrakte Klasse Planet, die nur eine Methode besitzt.
Dann gibt es 2 konkrete Klassen Mars und Venus. Die konkreten Klassen sollen mittels der Methode getImplClazz() die Klasse angeben welche zur Implementierung genutzt werden soll. Im Beispiel verweisen die Klassen immer auf sich selbst, es könnten hier aber im Prinzip beliebige Klassen zurückgegeben werden.
Java
- public abstract class Planet {
- protected abstract Class getImplClazz();
- }
- public class Venus extends Planet {
- public Class getImplClazz() {
- return Venus.class;
- }
- }
- public class Mars extends Planet {
- @Override
- protected Class getImplClazz() {
- return Mars.class;
- }
- }
Nun werden die Klassen instanziiert und ihr möchtet testen ob ein Objekt vom Typ Venus oder Mars ist.
Man sollte meinen, dies geht mittels instanceOf(). Es kommt aber zu einem Compilerfehler bei der Prüfung.
Java
- public static void main(String[] args) {
- Planet mars = new Mars();
- Planet venus = new Venus();
- if(mars instanceof venus.getImplClazz()) { //Compilerfehler
- }
- }
Warum ist das so?
Der Trick ist, dass hier nicht instanceOf() verwendet werden darf, da instanceOf() nur mit referenzierten Typen arbeitet, nicht jedoch mit Objekten.
Wie lässt sich das Problem beheben?
Ganz einfach, es muss die Methode isInstance() auf die Klasse angewendet werden.
Java
- public static void main(String[] args) {
- Planet mars = new Mars();
- Planet venus = new Venus();
- if(venus.getImplClazz().isInstance(mars)) { //OK
- }
- }
Ich hoffe dieses kleine Lösung hilft dem ein oder anderen, die vielleicht mal auf dieses Problem stoßen.
Speicherauslastung in Java einfach überwachen
Posted 10.07.2010 by Christian
Wenn ein Programm öfter mal OutOfMemoryExceptions wirft oder man einfach mal so den Speicherverbrauch eines Java Programmes wissen möchte gibt es dazu seit Java 5 eine sehr einfache Möglichkeit.
Mittels jConsole lässt sich die Speicherauslastung eines Programmes schnell ermitteln und grafisch darstellen. jConsole ist seit Java 5 im JDK mit dabei und verbirgt sich im Ordner “bin” der JDK Installation.
Um ein Programm mit der jConsole überwachen zu können muss das Java Programm einfach mit dem VM Parameter “-Dcom.sun.management.jmxremote” gestartet werden. In Eclipse geht das ganze in den Run Configurations.

Danach kann die jConsole gestartet werden indem man entweder die entsprechende jConsole.exe Datei im Java Installationsordner startet oder den Befehl jConsole einfach in der Box “Ausführen als…” eingibt.

Danach startet die jConsole und fragt mit welcher JVM man sich verbinden möchte. Wenn zuvor das Java Programm mit dem VM Parameter gestartet wurde, sollte hier bereits ein Eintrag zu sehen sein. Wurde die Verbindung erfolgreich hergestellt, lässt sich mit der jConsole ganz bequem die Speicherauslastung, wieviele Klassen geladen sind usw. überwachen.

Kommentare [1]
Mit Ant Dateien beim Deployment verändern
Posted 11.05.2010 by Christian
Wenn man unter Java ein Logging-Framework wie zum Beispiel log4j einsetzt, muss dieses konfiguriert werden. Typischerweise wird dazu eine Konfigurationsdatei eingesetzt. Diese könnte beispielsweise so aussehen:
- log4j.rootLogger = DEBUG, console
- log4j.appender.console = org.apache.log4j.ConsoleAppender
- log4j.appender.console.layout = org.apache.log4j.PatternLayout
- log4j.appender.console.layout.conversionPattern = %d [%t] %-5p %c %m%n
Beim Deployment von Anwendungen muss diese Konfigurationsdatei mit der Applikation ausgeliefert werden. Das Blöde ist nun, das während der Entwicklung der Anwendung ein anderes Logging-Level verwendet werden soll als in der Auslieferung an den Kunden.
Um zu vermeiden, dass die Konfigurationsdatei beim Deployment manuell angepasst werden muss und um ein automatisches Deployment zu ermöglichen, gibt es einen kleinen Trick.
Mit Ant ist es möglich, während dem Deployment die Konfigurationsdatei zu verändern.
Dazu muss als erstes die Konfigurationsdatei so verändert werden, dass das Logging-Level nicht mehr fest als String in der Datei steht sondern durch einen Platzhalter ersetzt wird. Platzhalter für Ant werden mit @ gekennzeichnet. Folglich sieht die Konfigurationsdatei nun so aus:
- log4j.rootLogger = @LOGGINGLEVEL@, console
- log4j.appender.console = org.apache.log4j.ConsoleAppender
- log4j.appender.console.layout = org.apache.log4j.PatternLayout
- log4j.appender.console.layout.conversionPattern = %d [%t] %-5p %c %m%n
Nun wird nur noch ein Ant-Task benötigt, der das Logging-Level beim Deployment ändert.
Der Ant-Task könnte folgendermaßen aussehen:
- <property name="app.loggingLevel" value="WARN" />
- <property name="app.log4jFile" value="log4j.properties" />
- <target name="log4j">
- <copy file="${app.log4jFile}"
- tofile="dist/${app.log4jFile}" >
- <filterchain>
- <striplinecomments>
- <comment value="!"/>
- </striplinecomments>
- <replacetokens>
- <token key="LOGGINGLEVEL" value="${app.loggingLevel}"/>
- </replacetokens>
- </filterchain>
- </copy>
- </target>
Um das Logging-Level zu ändern muss nun nur noch die erste Zeile verändert werden.
Previous