Tool mit dem man die Major version im Bytecode patchen kann..?

sirbender

Top Contributor
Hi,

ich experimentiere gerne ein bischen rum - im Moment mit dem OpenJDK - und da waere es im Moment sehr hilfreich wenn ich zu Experimentierzwecken einen Haufen .class Dateien in version 53 (Java9) auf version 52 (Java8) patchen und dann mit einem Java8 ausfuehren koennte. Die Sourcen (die ich groesstenteils eh nicht habe) zu kompilieren waere sehr problematisch.

Koennte ihr mir weiterhelfen? Gibt es ein Tool, dass dies im Batch kann? Klar koennte ich jetzt ein paar Tage ASM oder BCEL oder so studieren und es per Hand machen. Vielleicht habt ihr ja einen Tip weil es schon existiert.
 

mihe7

Top Contributor
https://en.wikipedia.org/wiki/Java_class_file

Quick & Dirty:

Java:
import java.io.RandomAccessFile;
import java.io.IOException;

public class Patch {
    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("Usage: <class-file-version> <class-file> ...");
            System.exit(1);
        }

        try {
            int version = Integer.parseInt(args[0]);
            for (int i = 1; i < args.length; i++) {
                patch(version, args[I]);
            }
        } catch (NumberFormatException ex) {
            System.err.printf("%s is not a valid class-file-version\n", args[0]);
            System.exit(2);
        }
    }

    private static void patch(int version, String filename) {
        try(RandomAccessFile raf = new RandomAccessFile(filename, "rw")) {
            byte[] header = new byte[8];
            raf.readFully(header);
            if (magic(header)) {
                header[7] = (byte)(version & 0xff);
                raf.seek(0);
                raf.write(header);
            } else {
                System.err.printf("Ingoring '%s': not a valid Java class file.\n", filename);
            }
        } catch (IOException ex) {
            System.err.printf("Got exception while processing file '%s': ", filename);
            ex.printStackTrace();
        }
    }

    private static boolean magic(byte[] data) {
        return data.length > 3 && data[0] == (byte)0xca && data[1] == (byte)0xfe &&
                data[2] == (byte)0xba && data[3] == (byte)0xbe;
    }
}

java Patch 52 build/*.class macht aus den class-Dateien im Verzeichnis build Java 8 class files.
 

sirbender

Top Contributor
Vielen Dank! Scheint zu funktionieren. Super!

Apropos, falls du es weisst:
Laut dem Wikipedia-Artikel zum class file layout werden ja zwei bytes fuer die Major Version vorgesehen. Warum ist man im Wikipedia-Artikel oder auch hier https://docs.oracle.com/javase/specs/jvms/se6/html/ClassFile.doc.html
eigentlich nicht erwaehnt, dass nur das byte an Position 7 genutzt wird und nicht 6 und 7 zusammen? Wozu ist 6 da? Fuer die Zukunft, falls groessere Zahlen noetig werden? Und wie werden die beiden bytes (Position 6 und 7) dann zu einer Major Version kombiniert?
 

mihe7

Top Contributor
Täusche Dich nicht, die Spec ist da ganz genau: u2 major_version;

u2 steht für eine eine vorzeichenlose, 2 Byte (also 16 Bit) breite Ganzzahl. Da mehr als ein Byte verwendet wird, ist die Reihenfolge wichtig. Lt. Spec werden die Werte in Big-Endian abgespeichert, d. h. das höherwertige Byte kommt zuerst.

Für Versionsnummern < 256 ist das höherwertige Byte immer 0 - daher habe ich nur das 7. Byte im Header gesetzt :) Korrekt wäre es, den int auf zwei Bytes abzubilden:
Java:
header[6] = (byte)((version >> 8) & 0xff);
header[7] = (byte)(version & 0xff);

D. h. das höherwertige Byte (most significant byte - MSB) ist das Ergebnis der Division der Versionsnummer durch 256 ohne Rest. Das niederwertige Byte (LSB) ist der Rest. Umgekehrt: Versionsnummer = MSB * 256 + LSB
 

httpdigest

Top Contributor
Bedenke auch, dass du natürlich nicht uneingeschränkt jede Java 9 Classdatei durch Anpassen der Classfile-Version auf einem JRE 8 ausführen kannst, da eventuell wichtige APIs fehlen, die erst in 9 eingeführt wurden, wie z.B. in der Stream API, der Process API, Variable Handles sowie Immutable Sets; oder tatsächlich Sprachfeatures nicht unterstützt werden, die in Java 9 hinzukamen, wie etwa Interface Private Methods.
 

sirbender

Top Contributor
Bedenke auch, dass du natürlich nicht uneingeschränkt jede Java 9 Classdatei durch Anpassen der Classfile-Version auf einem JRE 8 ausführen kannst, da eventuell wichtige APIs fehlen, die erst in 9 eingeführt wurden, wie z.B. in der Stream API, der Process API, Variable Handles sowie Immutable Sets; oder tatsächlich Sprachfeatures nicht unterstützt werden, die in Java 9 hinzukamen, wie etwa Interface Private Methods.

Machmal aendert sich das class-Format ja wirklich...zum Beispiel wenn neue keywords dazukommen (invokedynamic zum Beispiel). Irre ich mich, oder ist der Versionssprung (Major-Zahl) manchmal eigentlich auch unnoetig weil sich nichts geaendert hat?
 

mihe7

Top Contributor
"The class file version has been changed from 53 (or 44 + 9) to 54 (44 +10), even though JDK 10 did not introduce other changes to the class file format.

The OpenJDK community has adopted a new time-based release model, in which major releases of the Java platform occur every 6 months. As a consequence, it is anticipated that class file changes will also occur more rapidly. To ensure predictability for the tooling that processes class file bytes, the class file version will be incremented every major release even if there are no other changes to the class file format. In effect, the class file version will be 44 + $FEATURE, where $FEATURE is the feature-release counter (previously referred to as the major number) of the Java SE Platform and the JDK version string." (http://www.oracle.com/technetwork/java/javase/10-relnote-issues-4108729.html#Remaining)
 

httpdigest

Top Contributor
Die Classfile-Version soll wohl nicht nur Änderungen im Classfile-Format reflektieren, wie etwa:
- Neue Opcodes (z.B. invokedynamic in 51.0)
- Neue Attribut-Sektionen (z.B. Stackmap Frames in 50.0)
- Neue Constant Pool Einträge (z.B. Methodhandles in 51.0 oder dynamic constants in 55.0)
- Erweiterung von möglichen Constant Pool Argumenten für Opcodes (z.B. Classenreferenzen für LDC in 50.0)

sondern soll auch die Möglichkeiten der Java-Plattform, z.B. der Classlibrary widerspiegeln. Also, welche Klassen sind überhaupt vorhanden. Zusätzlich soll sie auch die operationalen Semantiken für zwar classfile-format-syntaktisch nicht neue aber von der Java-Version neu unterstützte Sprach-Features wie etwa synthetische Bridge-Methoden für Covariant Return Types (in 49.0 bzw. Java 1.5) reflektieren.
Zusätzlich dazu gibt es auch noch neue, sowohl Java- als auch JVM-spezifische Features, wie eben Interface Private Methods in 53.0 bzw. Java 9.
 

sirbender

Top Contributor
Puhhh...Java wird immer komplexer. Wer heute einsteigt hat deutlich groessere Probleme Code zu lesen ohne sich vorher ausgiebig einzuarbeiten - wobei die IDEs heutzutage viel helfen. Ich liebe viele der neuen Features, aber insgesamt koennte das Java auf lange Sicht auch schaden. Geht ja nicht nur um Neulinge sondern auch wie stabil die Tools um die Sprache rum sind. Komplexitaet ist da nicht immer foerderlich.
Der ewige Stillstand seit vielen Jahren war natuerlich auch nicht gut. Ich will nur nicht dahin kommen wo C++ ist...das jede erdenkliche Idee und jeder Sonderwunsch umgesetzt wird.
 

mrBrown

Super-Moderator
Mitarbeiter
Puhhh...Java wird immer komplexer. Wer heute einsteigt hat deutlich groessere Probleme Code zu lesen ohne sich vorher ausgiebig einzuarbeiten - wobei die IDEs heutzutage viel helfen.
Ehrlich gesagt - ich finde aktuelles Java nicht schwieriger zu lesen als alte Versionen, in vielen Fällen sogar deutlich einfacher.


Ich würde meinen Einstieg eher als „heut“ als als „gestern“ bezeichnen, in Java-Versionen gerechnet, und habe so einige Einsteiger mitbekommen.
In alten Versionen ist einfach viel mehr Boiler-Plate. Grad wenns um sowas wie irgendwas generisches mit Closeable oder in Richtung funktional geht.
 

JuKu

Top Contributor
##und da waere es im Moment sehr hilfreich wenn ich zu Experimentierzwecken einen Haufen .class Dateien in version 53 (Java9) auf version 52 (Java8) patchen und dann mit einem Java8 ausfuehren koennte. Die Sourcen (die ich groesstenteils eh nicht habe) zu kompilieren waere sehr problematisch.

Also wenn du die Sources nicht hast, ist erst einmal die Frage, ob du das darfst.
Wenn das Projekt nicht Open Source ist und du keine Bearbeitungsrechte besitzt, ist das ganze schon eine Urheberrechtsverletzung.

Desweiteren ist dein Vorgehen sehr fragwürdig:
Du gehst also davon aus, dass sich abgesehen von der Versionsnummer nichts im Bytecode ändert?
Ich glaube da denkst du falsch. Gerade Java 9 ist eine Version mit vielen Kompatibilitätsproblemen (Jigsaw usw.), da ist ein einfaches überschreiben der Versionsnummer in der Classdatei sicherlich keine gute Idee.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
O Produziert das Tool "jpackage" (ab JDK 14) .exe Dateien, die auf einer Zielumgebung ohne JRE lauffähig sind ?` Allgemeine Java-Themen 7
S Java-Task-Management-Tool für Windows und Mac selber programmieren Allgemeine Java-Themen 4
W IDEA IntelliJ Build-Management-Tool selbst programmieren Allgemeine Java-Themen 2
M eigenes Seekarten-Tool (oder PlugIn?) Allgemeine Java-Themen 2
S Klassen Abstract, Interface und ein Chat Tool Allgemeine Java-Themen 1
D Tool zum skalieren von bildern Allgemeine Java-Themen 4
O Freies Tool zum Jar-File obfuscaten gesucht! Allgemeine Java-Themen 5
E Tool um Methodenaufrufe aus bestimmten Pkg zu finden Allgemeine Java-Themen 2
S Tool um mehrere Klassen in einer Klasse vereinen? Allgemeine Java-Themen 6
J Suche: Tool zum Auffinden gleichnamiger Klassen (Name und Package gleich) in unteschiedlichen JARs Allgemeine Java-Themen 5
fastjack Gutes kostenloses Coverage-Tool mit Ignorefunktionen Allgemeine Java-Themen 4
E Tool/Programm zum Zeichnen von UML Diagrammen Allgemeine Java-Themen 14
S jConsole oder anderes Monitoring Tool Allgemeine Java-Themen 5
C Midlet Tool Allgemeine Java-Themen 24
W Requirements an ein Continuous Integration Tool Allgemeine Java-Themen 21
I Tool um Gegenstände zu tauschen Allgemeine Java-Themen 11
S Video Tracking Tool Allgemeine Java-Themen 3
I Statistic-Tool Allgemeine Java-Themen 4
G Java Tool startet von heute auf morgen nicht mehr? Allgemeine Java-Themen 7
C Tool zum verkleinern der Jars? Allgemeine Java-Themen 23
Zed Tool zum drucken von Sourcecode Allgemeine Java-Themen 9
T Suche Tool Allgemeine Java-Themen 11
N Gutes Java to UML Tool Allgemeine Java-Themen 8
W Einfaches Installer/setup tool für java programme das. Allgemeine Java-Themen 4
M Cobertura Code Coverage Tool Allgemeine Java-Themen 5
S VideoStreaming-Tool gesucht! Allgemeine Java-Themen 2
L Java Performance Check Tool Allgemeine Java-Themen 3
J Kleines Tool in Java erstellen? Allgemeine Java-Themen 20
B Tool zum Zeichnen von Systemarchitektur Allgemeine Java-Themen 2
WMaerz Der neue JDK 6 enthält keine javac.exe, tool.jar usw. Allgemeine Java-Themen 6
M Tool zum autom. Client-Update Allgemeine Java-Themen 2
T Tool für Zugriff auf Outlook? Allgemeine Java-Themen 5
M cheat tool für java Allgemeine Java-Themen 11
W VersionsVerwaltung welches Tool Verwendet ihr Allgemeine Java-Themen 12
M Programmierstill: Bitte testen anhand HTML-Tool Allgemeine Java-Themen 18
K eigenes Tool jar - maskieren der Methoden Allgemeine Java-Themen 3
J Java Parser Tool verfügbar? Allgemeine Java-Themen 3
T Warum mein such-tool schneller als Windows such-tool? Allgemeine Java-Themen 5
J Tool gesucht Allgemeine Java-Themen 7
Linad Windows Tool mit Java steuern Allgemeine Java-Themen 9
G Link zu JCreator oder anderem Tool Allgemeine Java-Themen 2
D Linux, Java-Version wird nicht erkannt bzw. welche Einstellung fehlt noch? Allgemeine Java-Themen 19
izoards Java Home Pfad unabhängig von der Version Allgemeine Java-Themen 7
J c Programm läuft nicht in compilierter Version des Java Projektes Allgemeine Java-Themen 7
D SHA-3 für Java-version 1.8 Allgemeine Java-Themen 1
F Reason: Missing Constraint: Import-Package: okhttp3.internal.http; version="0.0.0" Allgemeine Java-Themen 0
S @version in Kommentaren aktualisieren Allgemeine Java-Themen 10
bueseb84 Wget mit Wildcards - oder wie lädt man bei JFrog die letzte Version eines Artifacts herunter Allgemeine Java-Themen 3
hello_autumn Java_Home geändert auf Java 13, trotzdem wird Java Version 8 angezeigt. Allgemeine Java-Themen 2
L Java Version ändernhi icj Allgemeine Java-Themen 9
G Wiedereinstieg, welche Java Version empfehlt ihr Allgemeine Java-Themen 7
G GUI-basiertes Java-Program in Command-line Version umwandeln Allgemeine Java-Themen 1
I Geeignete Java-Version herusfinden Allgemeine Java-Themen 7
D Aktuell installierte Java Version auslesen unter Windows Allgemeine Java-Themen 5
F Netbeans Version Allgemeine Java-Themen 2
M Windows 98 - Mit welchem JDK (Version) kann noch Programm dafür erstellt werden Allgemeine Java-Themen 6
P Java Fehler auf Win2008 Server java.io.FilePermission IE8 Version JRE 1.7.0_51 Allgemeine Java-Themen 7
Developer_X Java Version aufrüsten Allgemeine Java-Themen 6
J Firefox - Java Version Wechseln Allgemeine Java-Themen 2
B Input/Output version.cfg konnte nicht im Klassenpfad gefunden werden, ist aber dort. Allgemeine Java-Themen 0
L Java Version aus Tomcat ermitteln Allgemeine Java-Themen 3
P JDK und JVM: 64bit Version UND 32bit Version gleichzeitig? Allgemeine Java-Themen 5
P Check, welche Java Version installiert bevor ein Programm ausgeführt wird. Allgemeine Java-Themen 12
N Java Version Prüfen lassen Allgemeine Java-Themen 11
M Umgebungsvariable Version des Programms Allgemeine Java-Themen 10
B A newer version of Java is needed to view the application. Allgemeine Java-Themen 17
N iText-Nutzung (Version 2.1.7) in kommerzieller Website Allgemeine Java-Themen 8
E Java Version Details ermitteln Allgemeine Java-Themen 5
G Java ME Version Allgemeine Java-Themen 2
J Alte version nutzen Allgemeine Java-Themen 4
D Problem mit Java version? Allgemeine Java-Themen 4
E Probleme beim Umstieg auf Version 1.6.0_12 Allgemeine Java-Themen 4
ARadauer welche java version wird benutzt Allgemeine Java-Themen 4
E Welche Java-Version kennt isEmpty() ? Allgemeine Java-Themen 2
H java version Allgemeine Java-Themen 6
B suche Deutsche Übersetzung für neuste Eclipse Version Allgemeine Java-Themen 6
A Apache License, Version 2.0 Allgemeine Java-Themen 7
E welche standalone Version von Tomcat benutzen? Allgemeine Java-Themen 6
D Probleme beim Umstellen von iText 1.4.4 auf Version 2.1.2 Allgemeine Java-Themen 5
G Auslesen mit welcher Java-Version Anwendung kompiliert wurde Allgemeine Java-Themen 2
X Version von der überladenen Methode/Klasse Allgemeine Java-Themen 10
W Programm prüft auf webserver ob neue version vorhanden? Allgemeine Java-Themen 3
B Java Buch zu welcher Version empfehlenswert? Allgemeine Java-Themen 6
J Windows Version von javacomm Allgemeine Java-Themen 2
S Bad version number in .class file Allgemeine Java-Themen 5
G Nachdem die neuste Version v. Java installiert-Fehlermeldung Allgemeine Java-Themen 22
G Prüfen welche JRE-Version gebraucht wird Allgemeine Java-Themen 19
L Wie für ein bestimmte JVM-Version kompilieren? Allgemeine Java-Themen 2
C Auswahl einer Version, bei mehreren installierten Versionen Allgemeine Java-Themen 3
A serial Version UID field of type long Allgemeine Java-Themen 5
P welche java version für javax.mail? Allgemeine Java-Themen 7
B Welche Java-Version? Allgemeine Java-Themen 7
D Java Version Allgemeine Java-Themen 2
G Aktuelle JRE Version? Allgemeine Java-Themen 7
M java.lang.UnsupportedClassVersionError: Bad version number i Allgemeine Java-Themen 5
vogella Version von Java ermitteln Allgemeine Java-Themen 2
B jre version in der html-datei für ein applet abfragen Allgemeine Java-Themen 5
A Java Version verstellen Allgemeine Java-Themen 2
F JRE Version ermitteln Allgemeine Java-Themen 2
K Java Version ermitteln (über System.getProperty hinaus) Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben