Das vergessene Erbe

“Erben heißt genießen, was man bekommt,
und vergessen, von wem.”

Paul Mommertz

Dieses Beitrag handelt nicht von dem bekannten Code Smell Refused Bequest (dem ausgeschlagenen Erbe), sondern von den vielen Featuren bekannter und unbekannter Bibliotheken, die in Vergessenheit geraten.

Bei manchen dieser Bibliotheken wird man irgendwann auf die unangenehme Art auf die vergessenen Möglichkeiten hingewiesen. So wie jüngst die Bibliothek Log4j2 mit den Security Vulnerabilities CVE-2021-44228, CVE-2021-45046 und CVE-2021-45105. In diesem Fall waren Message Lookups ein Einfallstor für Angreifer. Viele Entwickler, wie auch der Autor, waren da ganz froh auf logback im Backend zu setzen.

In diesem Beitrag soll es auch nicht um Gründe gehen, durch den diese Einfallstore entstanden sind. Vielmehr um den Umstand, dass kaum ein Entwickler über Message Lookups in Log4j informiert ist.

Fast alle Entwickler nutzen Logging Frameworks nur von der API Seite aus. D.h. eine Logger Instanz wird erstellt und dann Log-Meldungen erzeugt.

class Example {
  private static final Logger logger = LogFactory.getLogger(Example.class) 

  Example() {
    logger.debug("constructor");
  }
}

Hier ein simples und nutzloses Beispiel. Im Konstruktor wird im Debug-Level eine Log-Meldung ausgegeben. Welcher Logger hier verwendet wird, ist nicht klar, denn die Factory Methoden aller Frameworks haben sich mittlerweile auf einen Quasi-Standard angeglichen. Der angenehmer Vorteil, die Logger können automatisiert im Quell Code ausgetauscht werden.

Mit der Backend Seite der Logging Frameworks kommt ein Entwickler selten in Berührung. Manchmal wird die Ausgabe-Datei oder bei echten Fanatikern auch schon mal das Log-Format umgestellt. Den mancher kann sich von einem 20 Jahre alten Log-Format so wenig trennen, wie von der Kommandozeile neben seiner IDE.

Das Nutzen von Bibliotheken, ohne mehr als einen Bruchteil ihrer Möglichkeiten und Risiken zu kennen ist hier ein Problem. Zu den Aufgaben eines jeden Entwicklers gehört es, verwendete Bibliotheken für sich kennenzulernen oder zumindest neue Bibliotheken bzw. neue Versionen vor der ersten Nutzung zu prüfen. Häufig werden auch zusätzliche Bibliotheken wie Apache Commons, Hamcrest oder AssertJ verwendet, obwohl das JDK, bzw. JUnit 5 ausreichende oder elegantere Methoden zur Verfügung stellt.

Andererseits sollten Entwickler darauf achten unerwartete Features nicht in ihre Code einzubauen. Denn die Kollegen suchen selten nach neuen Stilblüten im verwendeten Code. Stattdessen erwarten sie konsistente, geradlinige APIs ohne Schnörkel wie eigene Log Wrapper, Exceptions mit implementierten Interfaces, Utility Methoden in Basisklassen und anderer exotischen Ergänzungen. In der Regel gehen diese skurrilen Ansätze im Quell Code unter, weil entweder anderen ihr Nutzen nicht vermittelt werden kann, oder der erhoffte Nutzen sich nicht einstellt. Dann dauert es nicht mehr lange und sie verschwinden bei einem Refactoring aus der Code Basis ohne großen Schaden zu hinterlassen.

Leave a Comment