Skip to content


Scala kommt

Ich habe letztes Jahr in der Java User Group HamburgJan Kriesten kennen gelernt, als er einen Vortrag zu Wicket gehalten hat. Dabei erwähnte er, dass er seine Projekte mit Scala umsetzt. Wenn man sein Haus umbauen möchte, ist es keine Gute Idee, alle Wände gleichzeitig einzureißen, als konzentrierte ich mich auf Wicket.

Heute habe ich gedacht, ich könnte diesen Kontakt ja mal aufleben lassen. Ich bekam prompt Antwort. Die Überraschung folgt auf den Fuss: Jan hat ebenfalls ein Buch geschrieben (es wird vermutlich zur selben Zeit erscheinen). Das Buch hat er auch noch beim selben Verlag geschrieben. Und offensichtlich hatten wir die selbe Intention, denn sein Buch ist ebenfalls auf die praktische Anwendung von (in diesem Fall) Scala ausgerichtet.

Ich habe das Buch natürlich nicht gelesen, aber ich habe ein gutes Gefühl. Es gibt hier jetzt keine Kaufempfehlung, außer an mich selbst.

Jan's Blog und das Buch:Praxisbuch Scala: Programmieren in Scala für Ein- und Umsteiger

Tags:

Veröffentlicht in scala, Wicket, .

Wicket und Scala - der Rückweg ist anstrengend

Ich habe mal ein wenig mit Scala rumgespielt und mit den Sprachmöglichkeiten, die Scala bietet, versucht aus einem Java-lastigen Wicket-Beispiel etwas zu machen, was sich wie Scala anfühlt. Zuerst der Java-Code:

package de.flapdoodle.incubator.scalawicket.web.pages;

import org.apache.wicket.Component;
import org.apache.wicket.IClusterable;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

public class StartJava extends WebPage
{
  public StartJava()
  {
    IModel messageModel=Model.of("Huiii");
    final Label label=new Label("message",messageModel);
    label.setOutputMarkupId(true);
    
    add(label);
  
    final Bean bean=new Bean();
    bean.setName("Klaus");
    bean.setAlter(12);
   
    final Component labelName = new Label("name",new PropertyModel(bean,"name")).setOutputMarkupId(true);
    final Component labelAlter = new Label("alter",new PropertyModel(bean,"name")).setOutputMarkupId(true);
    add(labelName);
    add(labelAlter);
    
    final Form form=new Form("form", new CompoundPropertyModel(bean));
    form.add(new TextField("name")).add(new TextField("alter"));
    form.setOutputMarkupId(true);
    add(form);
    
    add(new AjaxFallbackLink("link",messageModel)
    {
      public void onClick(AjaxRequestTarget target) 
      {
        getModel().setObject("Klick");
        bean.setName("Peter");
        target.addComponent(form);
        target.addComponent(label);
        target.addComponent(labelName);
        target.addComponent(labelAlter);
      }
    });
  
    add(new AjaxLink("link2",messageModel)
    {
      @Override
      public void onClick(AjaxRequestTarget target)
      {
        getModel().setObject("Klack");
        bean.setAlter(24);
        target.addComponent(form);
        target.addComponent(label);
        target.addComponent(labelName);
        target.addComponent(labelAlter);
      }
    });
  }
  
  class Bean implements IClusterable
  {
    String _name;
    int _alter;
    public String getName()
    {
      return _name;
    }
    public void setName(String name)
    {
      _name = name;
    }
    public int getAlter()
    {
      return _alter;
    }
    public void setAlter(int alter)
    {
      _alter = alter;
    }
  }
}

.. und nun das ganze in Scala

package de.flapdoodle.incubator.scalawicket.web.pages;

import org.apache.wicket.Component;
import org.apache.wicket.IClusterable;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import de.flapdoodle.incubator.scalawicket.web.wicket.WicketHelper._
import scala.reflect.BeanProperty;

class Start extends WebPage 
{
  val messageModel=Model.of("Huiii")
  val label=new Label("message",messageModel)
  label.enableAjax
  
  this+=label;

  val bean=new Bean
  bean.name="Klaus";
  bean.alter=12;

  val labelName = new Label("name",bean model {_.name}).enableAjax
  val labelAlter = new Label("alter",bean model {_.alter}).enableAjax
  this+=labelName
  this+=labelAlter
  
  val form=new Form[Bean]("form", new CompoundPropertyModel[Bean](bean));
  form+=(new TextField("name"),new TextField("alter"))
  form.enableAjax
  this+=form
  
  this+=new AjaxFallbackLink[String]("link",messageModel)
  {
    override def onClick(target: AjaxRequestTarget) = 
    {
      this.model set "Klick"
      bean.name="Peter"
      target.refresh(form,label,labelName,labelAlter)
    }
  };

  this+=new AjaxLink("link2",messageModel)
  {
    override def onClick(target: AjaxRequestTarget) =
    {
      this.model set "Klack"
      bean.alter=24
      target.refresh(form,label,labelName,labelAlter)
    }
  };

  class Bean extends IClusterable
  {
    @BeanProperty
    var name: String = _;
    @BeanProperty
    var alter: Integer = _;
  }
}

Zuerst zu den offensichtlichen Dingen:

  • Java: Zeilen=91, Wörter=155, Zeichen=2.567
  • Scala: Zeilen=69(75%), Wörter=126(81%), Zeichen=1.921(75%)

In diesem Beispiel kann Scala seine Vorteile vielleicht noch nicht richtig ausspielen. Wobei 25% weniger Schreibarbeit (wenn man vernachlässigt, dass ich einmalig etwas Scala-Code schreiben musste, was mir das ermöglicht) für dieses Beispiel vielleicht auch schon eine bemerkenswerte Menge ist.

Spannender ist folgender Umstand: Ich habe den Java-Code aus dem Scala-Code abgeleitet. Wenn ich das Beispiel direkt in Java geschrieben hätte, sähe der Code fast genauso aus. Als ich aber den Scala-Code rückübersetzte, fiel es mir sehr schwer, die ganzen Typ-Definitionen zu schreiben, die abschließende Semikolons zu setzen und Parameter in geschweifte Klammern einzubetten. Auch wenn die Unterstützung für Scala in Eclipse noch einiges Potential hat, kann man a) damit bereits erstaunlich gut arbeiten (wenn man bedenkt, welche interessanten Sprachmöglichkeiten (und damit Schwierigkeiten für eine IDE) Scala bietet).

Meine schönste Zeile Code ist in diesem Beispiel das Erzeugen eines AbstractReadOnlyModel durch den Aufruf von "bean model { _.alter }" , der in diesem Fall das selbe leistet wie ein PropertyModel, nur dass das Attribut nicht erst per Reflection ermittelt wird.

Ich warte eigentlich darauf, dass jemand Wicket nach Scala portiert, denn das Lift-Framework gefällt mir nicht so gut (da wird wieder Code in die Templates verlagert). Jetzt geht es erst einmal weiter mit Java, auch wenn der Rückweg jetzt schon ein beschwerlicher war.

Tags:

Veröffentlicht in Allgemein, Refactoring, scala, Wicket, .

Wicket Scala - der erste Versuch

So. Das klappt schon einmal. Das Aufsetzen einer Wicket-Anwendung mit Scala funktioniert wie erwartet. Label hinzufügen, einen AjaxLink einbinden und fertig ist der erste Test. Es fällt bereits angenehm auf, dass man die ganzen Typen weglassen kann. Unangenehm ist allerdings, dass das Scala-Plugin für Eclipse keine so ausgefeilte Code-Vervollständigung bietet, was sich in diesem ersten Test während des dann doch komplizierten Imports der passenden Klasse bemerkbar machte. Label liefert bei Java zuverlässig den richtigen Typ.

Veröffentlicht in Maven, scala, Wicket, .

Wicket und Scala

Vor kurzem habe ich mir das Buch Programming in Scala gekauft und durchgelesen. Dabei haben mir verschiedene Dinge von Anfang an sehr gut gefallen. Ich glaube, mit Scala kann man sehr elegant entwickeln. Das sollte sich auch z.B. beim Umfang der Quelltexte bemerkbar machen. Aber diese Sätze hätte ich so nicht geschrieben, wenn es nicht auch ein paar Probleme geben würde.

Die Frage, die mich intensiv beschäftigt, lautet: Bin ich mit Scala so viel schneller, dass ich Java mit einer hervorragenden Entwicklungsumgebung im Rücken, schlagen kann. Ich habe mir Netbeans und Eclipse angesehen. Der Scala-Support ist ähm.. naja. Da ist noch sehr viel Abstand zu den Dingen, die ich in einer IDE vermissen werde. Herausragend ist das das Thema Refactoring und dass was man in Eclipse "QuickFix" nennt.

Aber um ein besseres Gefühl dafür zu bekommen, werde ich in den nächsten Wochen wohl mal damit anfangen, den Wicket-Java-Stack auf Scala umzustellen. Ob ich dabei von Spring zu Guice wechsle ist eben so offen, wie ein geschickter Ansatz in Bezug auf Hibernate.

Veröffentlicht in scala, Wicket, .

Wicket ohne Template

Ich spiele seit einiger Zeit mit dem Gedanken, ob man basierend auf Wicket Komponenten entwickelt, die alle das entsprechende eigene Template mitbringen. Auf diese Weise könnte man dann Webanwendungen entwickeln, ohne eine Zeile Html-Code schreiben zu müssen. Verrückte Idee?

Normalerweise reduziert sich die Arbeit mit dem Html-Templates auf das Anordnen der Komponenten. Das was übrig bleibt (eine paar div-Tags), sollte man durch den Einsatz von Layout-Komponenten ersetzen können. Dann programmiert man wie für eine Desktopanwendung und das Ergebnis sieht gleich entsprechend gut aus, wenn man zu die passende CSS-Datei mitliefert.

Bis jetzt fehlt mir noch der geeignete Ansatz und die Entscheidung für ein CSS-Framework. Für Empfehlungen und Tipps bin ich in dieser Phase sehr empfänglich. :)

Tags:

Veröffentlicht in Refactoring, Technologie, Wicket, .

Wicket Praxis als Buch

Guter Wein braucht Zeit. Ein Buch zu schreiben ist vielleicht nicht ganz so zeitaufwendig, aber eben auch nicht mal so schnell gemacht. Ein Buch über Wicket zu schreiben ist aber vermutlich noch eine zusätzliche Herausforderung. Wenn ich vorher gewusst hätte, wie viel Arbeit ich in Praxisbuch Wicket stecken muss, hätte ich es vermutlich nicht angefangen. Aber zum Glück weiß man sowas vorher nicht und so hieß es immer wieder "Zähne zusammen beißen". Der nette Nebeneffekt: ich kenne Wicket jetzt schon sehr genau.

Und das was ich gesehen habe, verdient Respekt. Wicket ist ein sehr gut strukturiertes Softwareprojekt mit sehr guter Dokumentation in den Quelltexten und mit unglaublich vielen Möglichkeiten. Diese unglaubliche Flexibilität hat zwar dazu geführt, dass ich mehr Zeit als erwartet investieren musste, damit das Buch einen sinnvollen Rahmen findet. Aber es ist eben auch diese Flexibilität, die Wicket für so viele Webprojekte qualifiziert.

Warum habe ich das Buch geschrieben? Der Grund ist relativ einfach und indirekt egoistisch: Wenn mehr Leute Wicket benutzen, dann gibt es auch mehr Entwicklungen für Wicket (wie z.B. ein funktionierendes Plugin für Eclipse). Und das fände ich großartig. In dem ich ein Buch schreibe, in dem ich all meine Erfahrungen im Umgang mit Wicket einfließen lasse, beschleunige ich diesen Prozess, weil das Entwickeln mit Wicket wirklich Spass macht. Und wenn der Projektalltag mal nicht so viel Spaß macht, dann ist Wicket ein guter Freund, der Dir den Rücken frei hält.

Ich bin gespannt auf die Reaktionen und das Feedback. Ich danke allen die an mich geglaubt und mich unterstützt haben, und wenn es nur das beheben eines Fehlers war, der mir den Tag gerettet hat.

Michael Mosmann

Tags:

Veröffentlicht in Allgemein, Wicket, .

Die Ruhe vor dem Sturm

Wicket 1.4 nähert sich der Fertigstellung. Das ist ein gutes Zeichen, auch wenn ich Wicket 1.4-rc2 bereits längere Zeit ohne Probleme produktiv einsetze. Dieses Jahr wird ein Wicket-Jahr, denn so langsam beschäftigen sich immer mehr Entwickler mit dem Framework. Außerdem erscheinen in diesem Jahr einige Bücher rund um Wicket, so dass man gespannt sein darf, welche Auswirkung aktuelle Literatur zu diesem Thema haben wird.

Für mich steht diese Jahr auch im Zeichen von Scala. Die IDE-Unterstützung verbessert sich zunehmen, so dass man jetzt schon wieder zwischen Eclipse und Netbeans wählen kann. Wenn man dann Scala mit Wicket kombiniert, könnte man bei der Umsetzungsgeschwindigkeit auch Frameworks wie Grails den Platz auch gerade bei einfachen Projekten streitig machen. Das Wicket gerade bei komplexen Projekten punktet hat sich zwar auch noch nicht überall herumgesprochen, aber je mehr Anwendungen mit Wicket realisiert werden, desto schwieriger kann man diese Entwicklung ignorieren.

Damit bleiben für mich zwei Technologien übrig, mit denen man sinnvoll Java-basierte Webanwendungen entwickeln kann: GWT und Wicket. Für alle anderen Frameworks gibt es eigentlich keine Berechtigung, weil es keine guten Gründe mehr gibt, die für deren Einsatz sprechen. Wer andere Meinung ist, kann sich ja in einem Kommentar beschweren.

Am Ende des Jahres werden wir sehen, wie dicht ich dran lag:)

Tags:

Veröffentlicht in Allgemein, Technologie, Wicket, .

onclick statt Link

Was mir eigentlich nur durch Zufall auffiel, ist die Tatsache, dass man in Wicket einen Link auch an andere Tags als "a","area", etc binden kann. Netterweise macht Wicket dann daraus einen Javascript-Aufruf. Das geht mit einem Link und (wesentlich interessanter) auch mit einem AjaxFallbackLink.

Tags:

Veröffentlicht in Wicket, .

Wicket Migration von 1.3.5 auf 1.4-rc2

Soeben habe ich eine Migration auf Wicket 1.4-rc2 durchgeführt. Ausschlaggebend für die Migration war die Überarbeitung im Model-Bereich. Typisierte Modelle sind sehr viel handlicher und machen den Code sehr viel lesbarer. Da man die Komponenten ja auch schon generisch angelegt hat, ging diese Information bisher in den Modellen verloren.

Interessante Statistik:

  • Anzahl der Java-Dateien im Webprojekt: 376
  • Anzahl der Java-Dateien, die angepasst werden mussten: 32
  • Zeitaufwand für die Umstellung: 1h,30min

Ich glaube, das Risiko ist gering und der Vorteil ist groß. Meine Empfehlung: Umsteigen.

Tags:

Veröffentlicht in Refactoring, Wicket, .

Favicon mit HeaderContributor

Um seiner Wicket-Anwendung ein geeignetes Favicon zu verleihen, erstellt man einen HeaderContributor. Als Parameter dient eine ResourceReference auf das darzustellende Icon.

public class FavIconHeaderContributor implements IHeaderContributor
{
  ResourceReference _resourceReference;

  public FavIconHeaderContributor(ResourceReference resourceReference)
  {
    _resourceReference=resourceReference;
  }

  public void renderHead(IHeaderResponse response)
  {
    CharSequence url = RequestCycle.get().urlFor(_resourceReference);
    response.renderString(getFavIconReference(url));
  }

  private CharSequence getFavIconReference(CharSequence url)
  {
    StringBuilder sb=new StringBuilder();
    sb.append("<link rel=\"shortcut icon\" href=\"");
    sb.append(url);
    sb.append("\" type=\"image/x-icon\">\n");
    return sb.toString();
  }
}

Tags:

Veröffentlicht in Allgemein, Wicket, .