Java – Sebastians Blog https://sgaul.de Neues aus den Softwareminen Sat, 29 Nov 2014 20:35:44 +0000 de-DE hourly 1 https://wordpress.org/?v=6.1.1 https://sgaul.de/wp-content/uploads/2019/02/cropped-sgaul-2-1-32x32.jpg Java – Sebastians Blog https://sgaul.de 32 32 Bracket-Balancing in Ruby https://sgaul.de/2014/11/29/bracket-balancing-in-ruby/ Sat, 29 Nov 2014 20:35:44 +0000 https://sgaul.de/?p=2712 Bracket-Balancing in Ruby weiterlesen]]> Ich kann mir nicht helfen, nach zwei Jahren Ruby sieht Java manchmal nur noch umständlich aus. Gerade bei kleinen, in sich geschlossenen Programmen sollte man die Sprache mit Bedacht wählen. Wie aufwendig kann es sein herauszufinden, ob die verschiedenen Klammerarten in einem String ausbalanciert sind? Diese Frage stellte sich auch Code Corner und lieferte diese Lösung in Java:

http://www.corejavainterviewquestions.com/code-corner-bracket-balancing/
http://www.corejavainterviewquestions.com/code-corner-bracket-balancing/

Als Rubyist juckt es da in den Fingern, das muss doch schneller gehen.

require 'test/unit/assertions'
extend MiniTest::Assertions

class String

  BRACKETS = {
    "(" => ")",
    "[" => "]",
    "{" => "}",
  }

  def balanced?
    stack = []
    each_char do |char|
      if BRACKETS.keys.include? char
        stack.push char
      elsif BRACKETS.values.include? char
        return false if BRACKETS[stack.pop] != char
      end
    end
    stack.empty?
  end

end

assert "".balanced?
assert "([Hell{} T(h(e[r]e))]boom)".balanced?
assert not("(a[b{c)d]e}".balanced?)
assert not("([{".balanced?)
assert not("}])".balanced?)
]]>
Ubuntu: Java-Standardversion festlegen https://sgaul.de/2013/03/06/ubuntu-java-standardversion-festlegen/ Wed, 06 Mar 2013 15:17:15 +0000 https://sgaul.de/?p=1998 Ubuntu: Java-Standardversion festlegen weiterlesen]]> Ein kürzlich installiertes Paket hatte das Java JDK 7 als Abhängigkeit. Netterweise hat es dies gleich als Standard eingestellt, so dass meine Java-6-Projekte nun nicht mehr richtig wollten. Statt alle Projekte umzustellen war es einfacher, den Standard im System wieder zurückzudrehen:

sudo update-alternatives --config java

Das ganze stellt dann alle Alternativen zur Wahl:

Es gibt 2 Auswahlmöglichkeiten für die Alternative java (welche /usr/bin/java bereitstellen).

  Auswahl      Pfad                                            Priorität Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      Auto-Modus
  1            /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java   1061      manueller Modus
  2            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      manueller Modus

Drücken Sie die Eingabetaste, um die aktuelle Wahl[*] beizubehalten,
oder geben Sie die Auswahlnummer ein: 

Hier im Beispiel die 1 eingeben, mit Enter bestätigen und Java 6 ist wieder der Standard.

]]>
Compiler-Sicherheit für Wicket: Bindgen und Wicket-ID-Bindings-Generator https://sgaul.de/2013/03/02/compiler-sicherheit-fur-wicket-bindgen-und-wicket-id-bindings-generator/ Sat, 02 Mar 2013 14:01:16 +0000 https://sgaul.de/?p=1962 Compiler-Sicherheit für Wicket: Bindgen und Wicket-ID-Bindings-Generator weiterlesen]]> Eine zentrale Schwachstelle von Apache Wicket ist die fehlende Sicherheit zur Übersetzungszeit. Viele Dinge werden als Strings angegeben, so dass simple Tippfehler erst zur Laufzeit und somit schlimmstenfalls erst beim Kunden auffallen. Betroffen sind vor allem drei Bereiche:

  • PropertyModels, in denen Objektattribute als Strings notiert werden:
    new PropertyModel<String>(person, "name");
  • Wicket-ID-Referenzen, die Komponenten mit ihrem Template verbinden:
    <span wicket:id="myLabel"></span> <-> new Label("myLabel")
  • Propertynamen, die vor allem für Übersetzungen benötigt werden:
    new StringResourceModel("page.welcome", this, null);

Bindgen für Wicket

Für das Model-Problem gibt es mit Bindgen Wicket eine verhältnismäßig prominente Lösung. Hier wurde bereits angefragt, ob das Tool nicht offizieller Teil von Wicket 7 werden könnte.

http://wicket.apache.org/
http://wicket.apache.org/

Bindgen ist ein Annotation Processing Tool. Es erzeugt Meta-Klassen, welche die vom Nutzer geschriebenen Klassen und deren Eigenschaften beschreiben. Property-Models können somit compilersicher beschrieben werden:

// ohne Bindgen:
PropertyModel<String>(person, "name");

// mit Bindgen:
BindingModel.of(person, new PersonBinding().name());

// auch über Objektgrenzen hinweg:
BindingModel.of(person, new PersonBinding().address().street());

Kein wackliger String, sondern sichere, generierte Bindingklassen, welche die Attribute der Basisklasse beschreiben.

Annotationprocessing ist mittlerweile fester Bestandteil moderner IDEs, so dass Bindgen nach der einmaligen Einrichtung in etwa Eclipse keiner weiteren Interaktion bedarf. Die Bindings werden stets automatisch aktualisiert.

Wicket-ID-Bindings-Generator für Property-Dateien und HTML-Templates

Von Bindgen inspiriert, hat Ole Langbehn eine analoge Lösung für Property-Dateien und HTML-Templates geschaffen.

// WelcomePage.html
<h1 wicket:id="heading"></h1>

// WelcomePage_de.properties.xml:
<entry key="greetings">Willkommen</entry>

// ohne Wicket-ID-Bindings-Generator
add(new Label("heading", 
    new StringResourceModel("greetings", this, null));

// mit Wicket-ID-Bindings-Generator
add(new Label(WelcomePageWID.heading,
    new StringResourceModel(WelcomePageI18n.greetings, this, null));

Das offizielle Repository auf Github ist momentan nicht mit Wicket > 1.4 kompatibel. Eine Variante für neuere Versionen habe ich in meinem Fork bereitgestellt:

Ole hat angedeutet die Änderungen zu übernehmen, so dass die Updates auch bald im offiziellen Repo zu finden sein sollten.

Die Autovervollständigung nimmt nun noch mehr Arbeit ab und eine potentielle Fehlerquelle ist eliminiert. Bleibt nur noch zu hoffen, dass Wicket diese oder ähnliche Lösungen zukünftig schon von Haus aus mitbringt.

]]>
Nighthacking auf Youtube https://sgaul.de/2013/03/01/nighthacking-auf-youtube/ Fri, 01 Mar 2013 21:54:42 +0000 https://sgaul.de/?p=1986 Nighthacking auf Youtube weiterlesen]]> Eine kleine Empfehlung für Software-Entwickler: Der Youtube-Kanal Java hat viele sogenannter Nighthacking-Videos, in denen professionelle Programmierer frei und locker über für sie interessante Themen erzählen und direkt in Code gießen. Es wirkt nicht aufgesetzt und oft funktioniert nicht alles auf Anhieb. Eine Mischung aus charmant und lehrreich, die ich sehr unterhaltsam finde.

Ein Beispiel: Venkat Subramaniam zeigt Scala und Groovy, Rekursionsprobleme, wie diese teilweise vom Compiler selbst eliminiert werden und wie man ihnen dabei helfen kann:

[youtube clip_id=“4tEi86h8-TM“]

]]>
Alles schon da: Vielseitige Runtime-Exceptions in Java https://sgaul.de/2013/02/23/alles-schon-da-vielseitige-runtime-exceptions-in-java/ https://sgaul.de/2013/02/23/alles-schon-da-vielseitige-runtime-exceptions-in-java/#comments Sat, 23 Feb 2013 11:25:06 +0000 https://sgaul.de/?p=1937 Alles schon da: Vielseitige Runtime-Exceptions in Java weiterlesen]]> Ich kann es nicht mehr sehen: Try-Catch-Throw, Try-Catch-Throw. Gecheckte Exceptions sind so gut wie tot, helfen wir bei der schnellen Beerdigung. Java bietet von Haus aus ein kleines aber feines Portfolio an Runtime-Exceptions. Diese decken fast alle Fälle des täglichen Bedarfs ab und belästigen den Aufrufer nicht mit möglichen Fehlern, die er ohnehin nicht ordentlich behandeln kann…

Try-Catch-Throw
Try-Catch-Throw

IllegalArgumentException

Passt immer, wenn die Argumente, die an Konstruktor oder Methode übergeben wurden, nicht den Erwartungen entsprechen.

NullPointerException

Keine Spezialisierung der IllegalArgumentException, dennoch ein naher Verwandter: Teilt mit, dass ein Argument null ist, obwohl dies so nicht vorgesehen ist.

IllegalStateException

Wird immer dann benötigt, wenn Methoden nur in einer speziellen Reihenfolge verwendet werden dürfen und ein Abweichen zu einem ungültigen Zustand führen kann. Besser ist es natürlich, solche unsichtbaren Reihenfolgezwänge zu vermeiden. Möglich ist dies jedoch nicht immer.

IndexOutOfBoundsException

Der Klassiker für alles, was einen potentiell ungültigen Index haben kann.

StringIndexOutOfBoundsException

Eine spezielle Variante für die Manipulation von Strings.

UnsupportedOperationException

Nicht immer sind Interfaces so sauber und feingranular aufgebaut, dass man wirklich jede vorgegebene Methode implementieren kann. Diese Exception macht dies unmissverständlich deutlich. Dennoch eine Notlösung, denn die Erkenntnis zur Laufzeit ist eigentlich etwas spät.

Checked Exceptions sind tot

Die klassischen, gecheckten Java-Exceptions wirken heute wie ein Relikt aus früheren Zeiten. Die Java-Macher scheinen dem zuzustimmen und bieten eine Auswahl an ungecheckten Runtime-Exceptions, die fast alle Problemfälle abdeckt.

Das Pflegen unzähliger, hochspezialisierter Exceptions in einem Software-Projekt wirkt heute nicht zeitgemäß: Ausnahmen sollen keine Kontrollstrukturen ersetzen; in den meisten Fällen sind es schlicht fehlerhafte Zustände, die vor dem Programmabbruch geloggt werden müssen. Ein falsch eingegebenes Passwort ist keine Ausnahme, sondern eher die Regel; etwas das andauernd passiert: Wird eine Exception regelmäßig geworfen, wird das Exception-Konzept missbraucht und sollte durch Bedingungen ersetzt werden.

Wichtig sind präzise und ausführliche Meldungen, die das Problem und mögliche Ursachen beschreiben. Fehler lassen sich somit effizient beseitigen und vermeiden dank ihrer Fokussierung auf die Laufzeit das oft übliche Fangen-Kapseln-und-Weiterwerfen, wie es bei gecheckten Exceptions üblich ist.

]]>
https://sgaul.de/2013/02/23/alles-schon-da-vielseitige-runtime-exceptions-in-java/feed/ 2
Mikro-Webframework Spark https://sgaul.de/2013/01/31/mikro-webframework-spark/ Thu, 31 Jan 2013 20:57:53 +0000 https://sgaul.de/?p=1918 Mikro-Webframework Spark weiterlesen]]> Für Node und Co. sieht man sie überall, aber auch für Java gibt nette Minimal-Frameworks, wenn es um eine kleine Webanwendung geht. Spark ist einer der Vertreter, über den ich gerade gestolpert bin. Nicht ewig mit Umherkonfigurieren, keine neue Template-Sprache lernen, kein stundenlanges API-Lesen. Wenn der Großteil der Webapp ohnehin aus Javascript besteht, ist so eine Lösung oft genau das, was man braucht:

public static void main(String[] args) {

  get(new Route("/hello") {
     @Override
     public Object handle(Request req, Response res) {
         return "Hello World!";
     }
  });

}


Das ganze Ding unterstützt nur wesentliche Sachen wie Routing und Request-Response-Verarbeitung. Alles andere kann man sich entsprechend eigener Vorlieben zusammensuchen oder einfach weglassen – je nach Einsatzzweck.

Das Ergebnis läuft dann  mit Hilfe von Jetty selbstständig als Webserver (was die Entwicklung vereinfacht), lässt sich aber natürlich auch in einem Tomcat unterbringen.

spark-micro-webframework

]]>
Dateien relativ zur aktuellen Klasse adressieren https://sgaul.de/2013/01/19/dateien-relativ-zur-aktuellen-klasse-adressieren/ https://sgaul.de/2013/01/19/dateien-relativ-zur-aktuellen-klasse-adressieren/#comments Sat, 19 Jan 2013 10:58:41 +0000 https://sgaul.de/?p=1892 Dateien relativ zur aktuellen Klasse adressieren weiterlesen]]> Eine der Sachen, die ich mir nie merken kann: Wie adressiere ich eine Datei (z.B. Properties), die neben der zugehörigen Klasse im Paket liegt? Die Meta-Klasse der Klasse enthält den gesuchten Pfad:

final File file = 
    new File( MyClass.class.getResource( "myfile" ).getPath() );

Textdatei in String lesen

Will man eine solche Datei lesen und in einen String schreiben, helfen Apaches FileUtils:

public String getFileContent( final String fileName ) {
    final File file = new File( MyClass.class.getResource( fileName ).getPath() );
    try {
        return FileUtils.readFileToString( file );
    } catch ( final IOException e ) {
        throw new RuntimeException( "Cannot find file: " + file.getAbsolutePath(), e );
    }
}
]]>
https://sgaul.de/2013/01/19/dateien-relativ-zur-aktuellen-klasse-adressieren/feed/ 2
Binding mit Google Guice https://sgaul.de/2012/12/06/binding-mit-google-guice/ Thu, 06 Dec 2012 15:10:41 +0000 https://sgaul.de/?p=1791 Binding mit Google Guice weiterlesen]]> Die Projektseite von Google Guice und ihr Wiki empfinde ich als selten hilfreich. Besser macht sich da das zugehörige Javadoc, dass meine Fragen meist direkter zu beantworten wusste.

Beispiel Binding-Möglichkeiten

Implementierung an Interface binden

Üblicherweise bindet man ein Interface an seine Implementierung:

bind(Map.class).to(ArrayMap.class);

Implementierung an sich selbst

Was aber tun, wenn man gar kein Interface hat? Blauäugig dachte ich, dass das doch genauso gehen müsste:

// Fehlerhafter Beispielcode
bind(MyClass.class).to(MyClass.class);

Aber dem ist nicht so. Stattdessen bricht Guice den Startvorgang ohne verwertbare Fehlermeldung ab. Die Lösung ist stattdessen viel einfacher:

bind(MyClass.class);

Typ an Provider binden

Ein weitere interessante Möglichkeit ist die Bindung eines Typs an einen Provider, welcher Instanzen des Typs bei Nachfrage erzeugt und zurückgibt.

bind(MyClass.class).toProvider(MyClassProvider.class);

Generics und mehr

Solche und weitere Möglichkeiten, wie das leider etwas unschöne Binden generischer Klassen, lässt sich in den Javadocs nachlesen. Diese sind auch online verfügbar.

]]>
Java: Nicht-Null- oder Default-Wert https://sgaul.de/2012/12/04/java-nicht-null-oder-default-wert/ Tue, 04 Dec 2012 14:28:26 +0000 https://sgaul.de/?p=1772 Java: Nicht-Null- oder Default-Wert weiterlesen]]> Ein typisch-nerviges Java-Szenario ist das ewige Nullgeprüfe. Oft will man den Wert aus einem Parameter oder aber eine Alternative nutzen, wenn der Parameter null ist. Klassisches Beispiel: Ist ein String null, gib einen leeren String aus, wenn nicht, gib den String selbst aus. Eine einfache Lösung dafür bietet beispielsweise Apache Commons in der Funktionssammlung ObjectUtils.

ObjectUtils.defaultIfNull

System.out.println((String) null);
// "null"
System.out.println(ObjectUtils.defaultIfNull(null, ""));
// ""
System.out.println(ObjectUtils.defaultIfNull("a", ""));
// "a"

In der mir noch stets unterkommenden Variante 2.4 ist recht nervig, dass die Funktion schlicht Object zurückgibt und man seine Ergebnisse stets umständlich casten musste. In 3.1 ist der Rückgabetyp endlich generisch und kann direkt weiterverwendet werden.

ObjectUtils.firstNonNull

In eine ähnliche Kerbe schlägt die Funktion firstNonNull aus dem selben Paket. Sie liefert aus einer Liste optionaler Werte den ersten, der nicht null ist.

System.out.println(ObjectUtils.firstNonNull(null, null, "a", null, "b"));
// "a"
]]>
Echtzeit-Semantikprüfung für Java https://sgaul.de/2012/11/12/echtzeit-semantikprufung-java/ Mon, 12 Nov 2012 20:24:25 +0000 https://sgaul.de/?p=1625 Echtzeit-Semantikprüfung für Java weiterlesen]]> Fast schon unscheinbar kommt es daher, bahnbrechend könnte die Idee sein: Das Eclipse-Plugin JUnitLoop prüft in Echtzeit, welche Unittests von gerade gemachten Änderungen betroffen sind und führt diese automatisch aus. Der Entwickler bekommt mit dem Speichern eine Rückmeldung, ob und wo seine Änderungen zu Problemen geführt haben. Das Tool ist in etwas so einfach zu bedienen, wie es die Einbild-Bedienungsanleitung vermuten lässt. Zudem ist das Plugin frei und der Code bei GitHub zu finden.

Nach der vollständigen Syntaxanalyse, die man von Eclipse schon heute gewohnt ist, ist dies ein weiterer Schritt mit großem Effizienzsteigerungspotential. Und für Testmuffel werden Unittests um einiges interessanter…

]]>