Africa Studio - stock.adobe.com

Das Java-Tool JDeps zum Löschen interner API-Aufrufe nutzen

Enthält Java-Code interne API-Aufrufe wird er bald nicht mehr funktionieren. JDeps ist ein Tool, das diese Aufrufe identifiziert und alternativen Code vorschlägt.

Der Java Class Loader ist ein ziemlich einfaches Tool. Beim Aufruf einer Java-Klasse prüft der Class Loader, ob die Datei im Dateisystem vorhanden ist. Ist dies der Fall, wird die Klasse geladen. Der Class Loader ist also nicht sehr anspruchsvoll.

Ein Problem ist allerdings die mangelnde Differenzierungsfähigkeit des Class Loader. So gibt es keine Option, die Zugriffsmöglichkeiten einer Anwendung auf bestimmte Java-Komponenten einzuschränken, obwohl es bestimmte Pakete und JAR-Dateien gibt, die Anbieter der Java-Programmiersprache besser in Ruhe lassen sollten. Ein Paradebeispiel sind interne Java-APIs.

Entwickler dürfen keinen internen Code aufrufen, der das Java Development Kit (JDK) startet. Tatsächlich stellt Oracle sogar das Java 8 Tool JDeps (Java Dependency Analysis) zur Verfügung, um Entwickler zu warnen, wenn solche API-Aufrufe stattfinden.

Leider gibt es eine Reihe von äußerst hilfreichen Klassen, die den Entwicklern das Leben erleichtern. Sie ermöglichen es ihnen zum Beispiel, einige codebasierte Tricks auszuführen, die sonst nicht umsetzbar wären. Referenzen auf Klassen wie Unsafe oder Base64Encoder sollten in einer gut gebauten Java-Anwendung niemals vorkommen. Aber trotzdem gibt es zahlreiche Referenzen auf interne Java-APIs.

Java-Abhängigkeiten und neue Java-Versionen

Die Sache ist: Seit mit Java 9 Module eingeführt wurden, haben sich die Regeln des Class Loaders komplett geändert. Mit Modulen können Entwickler die Fähigkeit von Anwendungen, die auf der virtuellen Java-Maschine ausgeführt werden, einschränken, auf bestimmte Bibliotheken zuzugreifen. Genau das hat Oracle mit internen Java-APIs gemacht.

Seit der Modularisierung der Plattform kann Oracle nun einen Schalter umlegen und jede interne Java-API-Referenz beenden. Der Schalter wurde bisher noch nicht umgelegt, aber Oracle hat die Community bereits gewarnt, dass sie dies in einer künftigen Version machen werden. Infolgedessen müssen Entwickler alle internen Java-API-Aufrufe aus ihrem Code entfernen.

Das Java-Tool JDeps, das als Teil jeder neuen Java-Version mitgeliefert wird, kann gegen eine JAR-Datei oder eine bestimmte Codebasis eingesetzt werden. JDeps identifiziert nicht nur die Codeteile, die die Oracle-Regeln verletzen, sondern schlägt auch Alternativen vor. Letztendlich ist es ein einfach zu bedienendes Tool, das Teil jeder Maven Build oder Continuous Integration Pipeline sein sollte.

JDeps Beispiel

JDeps ist ein Befehlszeilenprogramm, das man im Verzeichnis \bin des JDK findet. Es verfügt über eine ganze Reihe von Switches. Diese stellen Berichte über die verschiedenen Abhängigkeiten bereit, die innerhalb einer Java-Anwendung bestehen. Die Option -jdkinternals berichtet über den Missbrauch der Java-API.

Hier ist ein Beispiel für die Funktionsweise des Java 8 Tools JDeps. Nehmen wir an, ein die Regeln verletzender Code ruft interne Java-APIs auf. Hier ist eine Klasse, die sowohl Unsafe als auch BASE64Encoder aufruft:

package com.mcnz.jdeps;

import java.lang.reflect.Field;

import sun.misc.BASE64Encoder;

import sun.misc.Unsafe;

 

/* Java 8 JDeps example */

public class UnsafeAtAnySpeed {

 

  public static void main(String[] args) throws Exception {

 

    /* The Java JDeps tool will flag calls to Base64Encoder */

    BASE64Encoder encoder = new sun.misc.BASE64Encoder();

    String s = encoder.encode("JDeps Example".getBytes());

 

    /* The Java JDeps tool will flag calls to Unsafe */

    Field f = Unsafe.class.getDeclaredField("More-JDeps");

    System.out.println(s + f);

  }

}

Ein Maven Build dieses Codes, der auf GitHub zu finden ist, erzeugt eine JAR-Datei namens jdeps-example.jar. Der Befehl, mit dem JDeps Aufrufe an interne APIs identifizieren kann, lautet:

$ jdeps –verbose –jdkinternals jdeps-example.jar

Wenn der Befehl JDeps ausgeführt wird, markiert er die Referenz auf Unsafe und BASE64Encoder und gibt die folgende Warnung aus: JDK internal APIs are unsupported and private to the JDK implementation. They are subject to be removed or changed incompatibly and could break your application.

BU: Abbildung 1: JDeps kann verwendet werden, um störende interne APs auszusortieren.
BU: Abbildung 1: JDeps kann verwendet werden, um störende interne APs auszusortieren.

Darüber hinaus kann das Java-Tool sogar eine Alternative zu einem BASE64Encoder-Aufruf vorschlagen. Stattdessen sollte der Entwickler die Klasse java.util.Base64 verwenden, die seit dem Release 1.5 Teil des JDK ist.

Die internen Java-APIs haben zwar ihren Reiz, da Entwickler damit Dinge machen können, die sonst mit ihren Standardbibliotheken nicht möglich sind.

Aber es ist an der Zeit, dieser Versuchung zu widerstehen – denn diese Möglichkeit wird es bald nicht mehr geben. Integrieren Sie stattdessen JDeps in Ihre Maven Build- und CI-Routinen – und entfernen Sie alle Referenzen auf interne APIs.

Nächste Schritte

Diese Tools helfen beim Aufbau von Microservices in Java.

Funktionale Programmierung in Java 8 oder Microsoft .NET.

Immer mehr Schwachstellen: Wie sich Java sicherer machen lässt.

Erfahren Sie mehr über Softwareentwicklung