Neue JRebel Lizenz – weiterhin keine Redeployments mehr

Meine einjährige „JRebel Personal Lizenz“ (kostete 156 Dollar) läuft jetzt im Dezember ab und staunend musste ich feststellen, dass die Lizenz abgeschafft wurde und Zeroturnaround stattdessen die „JRebel Base Lizenz“ für 265 Dollar (+ 20% Steuern) anbietet. Eine Verlängerung der Lizenz wollte ich mir nach der erheblichen Preiserhöhung noch überlegen, aber als Besitzer einer „JRebel Personal Lizenz“ bekommt man von Zeroturnaround eine ermäßigte „JRebel Base Lizenz“ für 154 Dollar (+ 20% Steuern) – da musste ich natürlich gleich zuschlagen.

Wer JRebel nicht kennt, fragt sich sicherlich: „Warum gibt ein Java-Entwickler für Entwicklungswerkzeuge heutzutage noch Geld aus?“. Wir haben doch schon so viele gute kostenlose Frameworks, Werkzeuge und Servers: Spring, Eclipse, Git, Jenkins, Tomcat, JBoss usw.

JRebel: Vergleich mit JVM Hot Swap

JRebel: Vergleich mit JVM Hot Swap (Quelle: Zeroturnaround)

JRebel bietet nach der Vergleichsmatrix offenbar einige Features, für die Entwickler auch gerne bezahlen. Doch was bedeutet JRebel für den Alltag eines Java-Entwicklers? Weiterlesen

Luke – ein Blick in den Lucene-Index

Wer für seine Anwendung Volltextsuche benötigt, sollte den Einsatz der Java-Bibliothek Apache Lucene oder der darauf basierende Webanwendung Apache Solr ernsthaft in Erwägung ziehen. Egal für welche Technik man sich von beiden entscheidet, letztlich werden die indizierten Daten in einem Lucene-Index abgelegt. Der Lucene-Index kann zwar im Speicher gehalten werden, aber bei großen Datenmengen und für die Fehlersuche sollte man den Index im Dateisystem ablegen.

Mit dem Programm Luke kann sich der Entwickler die abgelegten Daten des Lucene-Index anschauen. Auch wenn das Programm etwas altbacken ausssieht, bietet es wertvolle Hilfe, wenn Dinge mal nicht wie erwünscht funktionieren:

  • Übersicht zu den wichtigsten Begriffen
  • anzeigen von Dokumenten mit den zugehörigen Index-Werten
  • ausführen von Suchen und anzeigen der Suchergebnisse
  • bearbeiten und optimieren des Lucene-Indexes

Luke: Übersicht

Luke: Übersicht

Weiterlesen

Lucene: Volltextsuche leicht gemacht

Wenn man in einem Datenbestand bestimmte Daten sucht, wird man zumeist die Möglichkeiten der jeweils eingesetzten Datenbank nutzen. Sobald man jedoch eine Volltextsuche benötigt, wird es mit einer reinen Datenbanklösung kompliziert. Dann sollte man im Java-Bereich einen Blick auf Apache Lucene und Apache Solr werfen.

Während es sich bei Lucene um eine Java-Bibliothek für Volltextsuche handelt, nutzt die Webanwendung Solr die Funktionen von Lucene und bietet komfortable Anfrage- und Verwaltungsmöglichkeiten über HTTP-Schnittstellen. In diesem Artikel stelle ich ein kleines Projekt mit Lucene vor, allerdings sollte man vor dem Einsatz von Lucene abwägen, ob sich die Anforderungen nicht mit Solr noch einfacher realisieren lassen. Lucene bietet für die Volltextsuche eine Vielzahl von Funktionen an:

  • wie DB-Suche: Felder, boolsche Ausdrücke, Wildcards: title:“rot“ AND desc:“Schuh“
  • Fuzzy Search (Unscharfe Suche): mahlen -> mahlen, malen, Wahlen
  • Stemming von Wörtern (Verwendung des Wortstamms): rote Schuhe -> rot, Schuh
  • Verstärkungsfaktoren (z.B. Produkt): Name*4, Eigenschaften*2, Beschreibung*1
  • Ignorieren von ‚Stopwords‘, z.B: einer, eine, eines, der, die“, das, wie, ohne
  • Unterstützung von vielen Sprachen: Klasse StandardAnalyzer ersetzen durch Klasse GermanAnalyzer für deutsche Sprache
  • vieles mehr

Weiterlesen

Test-Driven-Development (TDD) mit den passenden Eclipse-Plugins

Die Entwicklungsumgebung Eclipse bietet für das Testen mit JUnit die JUnit-View. Um allerdings testgetrieben entwickeln zu können (Test-Driven-Development – TDD)  ist das etwas wenig. Jeder Entwickler, der es mit TDD ernst meint, sollte sich für effektives testgetriebenes Entwickeln (und mehr Spaß 😉 ) weitere Eclipse-Plugins installieren.

Während ich schon seit vielen Jahren die Plugins MoreUnit und EclEmma einsetze, habe ich erst vor kurzem bei der Java-User-Group Bremen (XING – JUG Bremen) das Plugin Infinitest kennengelernt. Was machen diese Plugins denn Schönes?

  • MoreUnit: Tests + Testmethoden anlegen und einfaches Wechseln zwischen Produktionscode und Testcode
  • Infinitest: kontinuierliches Ausführen der Tests im Hintergrund mit Testergebnis-Anzeige (rot / grün)
  • EclEmma: Überprüfung der Testabdeckung

Mit installierten Plugins können wir uns über viele zusätzliche nützliche UI-Elemente freuen und unser Eclipse sieht dann etwa folgendermaßen aus:

Editor mit einer "Klasse unter Test"

Editor mit einer „Klasse unter Test“

Weiterlesen

PSI-Probe – ein besserer Tomcat-Manager

Schnell mal eine Web-Anwendung im Tomcat deployen, sich einen Überblick über den Speicherverbrauch verschaffen oder einen Blick in die Log-Dateien werfen – mit PSI-Probe ist das bequem und einfach. PSI-Probe dient der Administration und Überwachung von Tomcat-Servern und bildet damit eine ausgezeichnete Alternative zu dem hauseigenen Tomcat-Manager.

Bei den zahlreichen Features sollte jeder Tomcat-Nutzer PSI-Probe mal ausprobiert haben:

  • einfache Installation als Web-Anwendung
  • Status von Web-Anwendungen anzeigen
  • deploy, start, stop, undeploy von Web-Anwendungen
  • Statistiken zu Sessions und Requests anzeigen
  • Log-Dateien sich live anzeigen lassen
  • System-Properties auflisten
  • Statistiken zu JVM und Garbage Collection
  • Statistiken zu CPU, Speicher, Datei-System
  • und vieles, vieles mehr …
Probe - Applications

Probe – Applications

Weiterlesen

Freemarker: Behandlung von undefinierten Werten

Die Standard-Templatesprache zur Generierung von Webseiten mit Java bilden die
Java Server Pages (JSP). Eine gute Alternative zu JSPs ist die Templatesprache Freemarker, mit der sich eine striktere Trennung zwischen Anwendungslogik und View durchsetzen lässt. Wie die Integration von verschiedenen Templatesprachen mit Spring-MVC erfolgt, habe ich in diesem Artikel beschrieben: Velocity, Freemarker, Jade4J – Alternativen zu JSPs

Beim Einsatz von Freemarker muss man darauf achten, dass alle Modell-Werte korrekt gefüllt sind, damit die Platzhalter im Template korrekt ersetzt werden können. Falls ein Wert nicht vorhanden ist, wird mit der Freemarker-Standardkonfiguration Folgendes passieren:

  1. Freemarker wirft eine Exception: freemarker.core.InvalidReferenceException
  2. die Fehlermeldung wird geloggt
  3. das weitere Generieren der Seite wird abgebrochen
  4. die Webseite zeigt dann eventuell eine halb fertig generierte Seite oder einen Stacktrace der Exception an

Das ist zwar während der Entwicklung ganz praktisch, aber die Anwender sollten natürliche keine fehlerhafte Seite sehen. Zur Vermeidung von Fehlermeldungen, wenn ein Wert nicht gesetzt ist, können wir folgendes tun:

  • Default-Werte im Template definieren
  • einen anderen Freemarker-Exception-Handler verwenden

Weiterlesen

Java-Webanwendung mit Tomcat auf Port 80 ausliefern

Ich arbeite ja ganz gerne mit der JiffyBox und der aktuellsten Ubuntu Langzeit-Support Version (Precise Pangolin – 12.04 LTS). Wenn man eine Java-Webanwendung mit Tomcat auf dem Standardport für Webserver (Port 80) bereitstellen möchte, gibt es dafür verschiedene Wege.

Die schnellste Möglichkeit könnte es sein, Tomcat per apt-get zu installieren und in der server.xml den Tomcat-Standardport von 8080 auf 80 zu ändern. Allerdings wird dann beim Starten des Servers ein Fehler auftreten. Schließlich werden Root-Rechte benötigt, um einen der ersten 1024 Ports zu reservieren:

Jan 22, 2013 11:53:51 PM org.apache.coyote.http11.Http11Protocol init
SEVERE: Error initializing endpoint
java.net.BindException: Permission denied <null>:80
        at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:549)
        at org.apache.coyote.http11.Http11Protocol.init(Http11Protocol.java:176)
        at org.apache.catalina.connector.Connector.initialize(Connector.java:1049)
        at org.apache.catalina.core.StandardService.initialize(StandardService.java:703)
        at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:838)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:538)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:562)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:261)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: java.net.BindException: Permission denied
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:353)
        at java.net.ServerSocket.bind(ServerSocket.java:336)
        at java.net.ServerSocket.<init>(ServerSocket.java:202)
        at java.net.ServerSocket.<init>(ServerSocket.java:158)
        at org.apache.tomcat.util.net.DefaultServerSocketFactory.createSocket(DefaultServerSocketFactory.java:50)
        at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:538)
        ... 12 more
Jan 22, 2013 11:53:51 PM org.apache.catalina.core.StandardService initialize
SEVERE: Failed to initialize connector [Connector[HTTP/1.1-80]]
LifecycleException:  Protocol handler initialization failed: java.net.BindException: Permission denied <null>:80
        at org.apache.catalina.connector.Connector.initialize(Connector.java:1051)
        at org.apache.catalina.core.StandardService.initialize(StandardService.java:703)
        at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:838)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:538)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:562)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:261)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Jan 22, 2013 11:53:51 PM org.apache.catalina.startup.Catalina load

Natürlich gibt es viele Möglichkeiten, das Problem anzugehen. Hier jetzt eine dreckige und eine saubere Lösung:

  1. Schnell und unsicher (einfach dreckig): Eigenen Tomcat-Server installieren und als Root starten
  2. Aufwendiger und sicher (schöööön sauber): Standard Apache-Server und Tomcat installieren und per AJP (Apache JServ Protocol) miteinander verbinden

Weiterlesen

SMS versenden und empfangen mit BulkSMS

Die erste Kurzmitteilung des Short Message Service wurde am 3. Dezember 1992 (mit dem Text »Merry Christmas«) von einem PC an ein Mobiltelefon im britischen Vodafone-Netz gesendet.

[aus Wikipedia-Artikel zu ‚Short Message Service (SMS)‘: http://de.wikipedia.org/wiki/SMS]

Die erste SMS ist also schon fast 20 Jahre alt und ich habe noch nie eine SMS aus einer Anwendung heraus verschickt. Das wurde aber jetzt mal Zeit! Im Internet findet man eine Vielzahl von Anbietern, sodass man sich erst einmal überlegen sollte, welche Anforderungen eigentlich bestehen:

  • nur Senden von SMS oder auch Empfangen von SMS
  • wird Zuverlässigkeit beim Versand benötigt
  • Kosten der SMS (Einrichtungsgebühr, Anzahl der SMS)
  • API vorhanden für SMS-Versand/Empfang aus eigenem Programm
  • deutscher oder internationaler Anbieter
  • Zahlungsarten des Anbieters
  • Spezialwünsche: Anbieterkennung verschicken, eigene Rufnummer für den Empfang

Einen konkreten Vergleich der Anbieter habe ich im Internet nicht gefunden. Daher hier einen Verweis zu den Preislisten diverser Anbieter: sloono, SMSout, BulkSMS, SMS77. Von den Preisen und den angebotenen Leistungen unterscheiden sich die Anbieter nicht so sehr:

  • zuverlässig und schnell versendete SMS kosten 6-8 Cent/SMS
  • SMS mit unregelmäßiger Versanddauer kosten etwa 3 Cent
  • angebotene APIs sind beispielsweise HTTP, SOAP und E-Mail

Weiterlesen

Aufgaben zeitgesteuert ausführen mit Spring-TaskScheduler

Bei Geschäftsanwendungen wird häufig eine zeitgesteuerte Ausführung (Scheduling) von Aufgaben benötigt, wie beispielsweise das regelmäßige Abrufen eines Email-Kontos. Dabei unterscheidet man beim Scheduling prinzipiell zwischen zwei Arten:

  • eine Aufgabe zu einem bestimmten Zeitpunkt ausführen (z.B.: am 24.12.2012, um 18:00 Uhr)
  • Aufgaben in festgelegten zeitlichen Abständen wiederholt ausführen (z.B.: alle 20 Minuten)

Für Scheduling können wir im Java-Umfeld die Timer-Klassen (java.util.Timer + java.util.TimerTask) des JDKs benutzen oder eine Bibliothek einsetzen, wie den sehr mächtigen Quartz-Scheduler. Falls man allerdings in seiner Anwendung Spring 3 verwendet, sollte man sich auf jeden Fall dessen Möglichkeiten anschauen (Spring-Dokumentation: Task Executing and Scheduling):

  • Scheduling mit TaskScheduler und Runnable-Objekt
  • Scheduling mit Hilfe des Task-Namespaces von Spring
  • Scheduling aufgrund der Spring Scheduling-Annotations

Weiterlesen

Velocity, Freemarker, Jade4J – Alternativen zu JSPs

Webanwendungen auf Java-Basis werden heutzutage größtenteils mit Hilfe eines umfangreichen Webframeworks (wie Java Server Faces, Google Web Toolkit oder Wicket) realisiert. Viele dieser Technologien bringen ihre eigene Templatesprache mit, die HTML um eigene Elemente erweitern. Falls man allerdings die Web-Basistechnologien Servlets/JSPs nutzt oder das Webframework neben JSPs auch andere Templatesprachen unterstützt (wie Spring MVC), wird der Einsatz einer alternativen Templatesprache vielleicht mit höherer Produktivität und mehr Spaß belohnt.

Solange man nur auf eine Templatesprache wie JSP beschränkt ist, braucht man sich auch keine Gedanken um die Effizienz der eingesetzten Sprache zu machen. Aber in diesem Artikel möchte ich dazu animieren, andere Templatesprachen mal auszuprobieren. Deren produktiven Einsatz sollte man sich natürlich zuvor gut überlegen – einige Aspekte sind beispielsweise:

  • Sprache: Einfachheit und Klarheit versus Ausdrucksstärke und Komplexität
  • Erweiterungen: Erstellung und Einbindung von Bibliotheken (z.B.: Tag-Libraries für JSPs)
  • Werkzeuge: Unterstützung innerhalb von Editoren/IDEs (z.B.: Syntax-Highlighting)
  • Mitarbeiter: Know-How im Team und Bereitschaft neue Sprachen zu lernen

Weiterlesen