Startseite > Wilkommen > Logbuch > Linux, Java-Binärdateien und hart codierte Windows-Pfade

Linux, Java-Binärdateien und hart codierte Windows-Pfade

Sonntag 2. April 2023, von Mathieu Brèthes

Alle Fassungen dieses Artikels: [Deutsch] [English] [français]

Ich schreibe das hier für die Nachwelt auf. Ich bin manchmal ein bisschen ein Geek.

Stellen Sie sich folgende Situation vor: Jemand hat Ihnen ein Java-Programm vermacht, dessen Quellcode Sie nicht haben, und Sie denken sich: "Das ist ja toll, Java ist eine plattformunabhängige Sprache, ich kann es unter Linux laufen lassen"! Und wenn Sie es dann starten, tritt ein schrecklicher Fehler dieser Art auf:

Exception in thread "main" java.io.FileNotFoundException: c:\hello.txt (Keine Datei oder Ordner dieses Typs).

Dies ist ein fest codierter Windows-Pfad in der Anwendung. Natürlich haben Sie nicht den Quellcode, um diesen dummen Fehler selbst zu beheben. Ihnen kommen verschiedene Lösungen in den Sinn: Windows starten, den Wine-Emulator verwenden usw.

Aber wie wäre es, wenn Sie die Java Virtual Machine (JVM) so modifizieren, dass sie selbst Windows-Pfade in Linux-Pfade umwandelt? "Einfach so?"

Zufällig ist das die Lösung, die Chase Siebert, Leiter der Technikabteilung bei Dropbox, vorschlägt. In seinem Blogbeitrag erklärt er, dass dies durch das Ändern einer einzigen Datei möglich ist! Jippie, also! Sie folgen freudig seinen Anweisungen, die immerhin verlangen, dass Sie den Quellcode der JVM herunterladen (sudo apt-get install openjdk-src), ihn im Installationsordner /usr/lib/jvm/openjdk-11/lib/src. zip, dann entpacken Sie es und bearbeiten Sie die Datei File.java in java.base/java/io, dann kompilieren Sie es (und hier müssen Sie die richtigen Parameter finden, damit es funktioniert) und dann fügen Sie das resultierende Archiv als Kommandozeilenparameter hinzu... Und dann funktioniert es natürlich nicht mehr:

-Xbootclasspath/p ist keine unterstützte Option mehr.

Das ist das ganze Problem eines Blogbeitrags von vor 13 Jahren, der mit java 8 funktionierte. Jetzt haben Sie Java 11. Um es jetzt zu tun, ist es sowohl einfacher als auch komplizierter...

Schritt 1: Das Projekt organisieren

Erstellen Sie ein Verzeichnis build für Ihren Build, ein Verzeichnis sdk für den sdk und ein Verzeichnis run für Ihr Programm.

Das sieht dann so aus:

./build
./run
./sdk

Entpacken Sie die sdk in sdk.

Kopieren Sie Ihre auszuführende java-Binärdatei in run.

Schritt 2: Kompilieren Sie File.java mit den richtigen Optionen

Bearbeiten Sie die Datei File.java wie in dem oben verlinkten Blogbeitrag beschrieben. Fügen Sie am Anfang der Datei einen "import java.util.regex.Pattern;" hinzu, der im Blogbeitrag nicht erwähnt wird.

Führen Sie im Wurzelverzeichnis der SDK (das den Ordner java.base enthält) die folgende Befehlszeile aus:

javac -XDstringConcat=inline -d ../build/java.base --patch-module java.base=. java.base/java/io/File.java

Dies wird Ihren "Patch" von File.java in den Ordner build/java.base kompilieren. -XDstringConcat=inline ist notwendig, um einen Fehler bei der Ausführung zu vermeiden (es ist hier dokumentiert, warum, und ich habe mich sehr bemüht, diese Seite zu finden...).

Schritt 3. Starten Sie Ihr Programm!

Wechseln Sie nun in das Verzeichnis run und starten Sie Ihr Programm mit der folgenden lustigen Befehlszeile:

java --patch-module java.base=../build/java.base meinprogramm.

Und schon ist Ihr c:\hello.txt in /hello.txt umgewandelt, das mit etwas Glück auf Ihrer Festplatte existiert...

Ein letzter Link, ich habe die Syntax von --patch-module richtig erklärt gefunden auf dieser Seite (ganz unten auf der Seite).

So, jetzt gibt es also zwei Seiten, die über dieses Problem berichten!

Übersetzt mit www.DeepL.com/Translator (kostenlose Version)


Online ansehen : Java hack to deal with Windows file paths in Linux