diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/ClassFileVersion.java b/byte-buddy-dep/src/main/java/net/bytebuddy/ClassFileVersion.java index e3d54f2ac8..b72fed9249 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/ClassFileVersion.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/ClassFileVersion.java @@ -212,6 +212,17 @@ public static ClassFileVersion ofMinorMajor(int versionNumber) { * @return The appropriate class file version. */ public static ClassFileVersion ofJavaVersionString(String javaVersionString) { + return ofJavaVersionString(javaVersionString, OpenedClassReader.EXPERIMENTAL); + } + + /** + * Returns the Java class file by its representation by a version string in accordance to the formats known to javac. + * + * @param javaVersionString The Java version string. + * @param experimental {@code true} if unknown version strings should be parsed as if they were known. + * @return The appropriate class file version. + */ + public static ClassFileVersion ofJavaVersionString(String javaVersionString, boolean experimental) { if (javaVersionString.equals("1.1")) { return JAVA_V1; } else if (javaVersionString.equals("1.2")) { @@ -259,7 +270,7 @@ public static ClassFileVersion ofJavaVersionString(String javaVersionString) { } else if (javaVersionString.equals("1.23") || javaVersionString.equals("23")) { return JAVA_V23; } else { - if (OpenedClassReader.EXPERIMENTAL) { + if (experimental) { try { int version = Integer.parseInt(javaVersionString.startsWith("1.") ? javaVersionString.substring(2) @@ -282,6 +293,18 @@ public static ClassFileVersion ofJavaVersionString(String javaVersionString) { * @return A wrapper for the given Java class file version. */ public static ClassFileVersion ofJavaVersion(int javaVersion) { + return ofJavaVersion(javaVersion, OpenedClassReader.EXPERIMENTAL); + } + + /** + * Creates a class file version for a given major release of Java. Currently, all versions reaching from + * Java 1 to Java 9 are supported. + * + * @param javaVersion The Java version. + * @param experimental {@code true} if unknown Java versions should also be considered. + * @return A wrapper for the given Java class file version. + */ + public static ClassFileVersion ofJavaVersion(int javaVersion, boolean experimental) { switch (javaVersion) { case 1: return JAVA_V1; @@ -330,7 +353,7 @@ public static ClassFileVersion ofJavaVersion(int javaVersion) { case 23: return JAVA_V23; default: - if (OpenedClassReader.EXPERIMENTAL && javaVersion > 0) { + if (experimental && javaVersion > 0) { return new ClassFileVersion(BASE_VERSION + javaVersion); } else { throw new IllegalArgumentException("Unknown Java version: " + javaVersion); diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/utility/AsmClassReader.java b/byte-buddy-dep/src/main/java/net/bytebuddy/utility/AsmClassReader.java index 3f1c11d009..cd74d0b4a7 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/utility/AsmClassReader.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/utility/AsmClassReader.java @@ -56,6 +56,15 @@ interface Factory { */ AsmClassReader make(byte[] binaryRepresentation); + /** + * Creates a class reader for a given class file. + * + * @param binaryRepresentation The class file's binary representation. + * @param experimental {@code true} if unknown Java class files versions should also be considered. + * @return A class reader representation for the supplied class file. + */ + AsmClassReader make(byte[] binaryRepresentation, boolean experimental); + /** * A default implementation that creates a pure ASM {@link ClassReader}. */ @@ -72,6 +81,13 @@ enum Default implements Factory { public AsmClassReader make(byte[] binaryRepresentation) { return new AsmClassReader.Default(OpenedClassReader.of(binaryRepresentation)); } + + /** + * {@inheritDoc} + */ + public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) { + return new AsmClassReader.Default(OpenedClassReader.of(binaryRepresentation, experimental)); + } } } diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/utility/OpenedClassReader.java b/byte-buddy-dep/src/main/java/net/bytebuddy/utility/OpenedClassReader.java index eb721ae594..2bf3fdc37d 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/utility/OpenedClassReader.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/utility/OpenedClassReader.java @@ -65,6 +65,13 @@ public AsmClassReader make(byte[] binaryRepresentation) { return new AsmClassReader.Default(of(binaryRepresentation)); } + /** + * {@inheritDoc} + */ + public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) { + return new AsmClassReader.Default(of(binaryRepresentation, experimental)); + } + /** * A proxy for {@code java.security.AccessController#doPrivileged} that is activated if available. * @@ -77,6 +84,7 @@ private static T doPrivileged(PrivilegedAction action) { return action.run(); } + /** * Creates a class reader for the given binary representation of a class file. * @@ -84,9 +92,20 @@ private static T doPrivileged(PrivilegedAction action) { * @return An appropriate class reader. */ public static ClassReader of(byte[] binaryRepresentation) { + return of(binaryRepresentation, EXPERIMENTAL); + } + + /** + * Creates a class reader for the given binary representation of a class file. + * + * @param binaryRepresentation The binary representation of a class file to read. + * @param experimental {@code true} if unknown class file versions should also be processed. + * @return An appropriate class reader. + */ + public static ClassReader of(byte[] binaryRepresentation, boolean experimental) { ClassFileVersion classFileVersion = ClassFileVersion.ofClassFile(binaryRepresentation), latest = ClassFileVersion.latest(); if (classFileVersion.isGreaterThan(latest)) { - if (EXPERIMENTAL) { + if (experimental) { binaryRepresentation[4] = (byte) (latest.getMinorVersion() >>> 8); binaryRepresentation[5] = (byte) latest.getMinorVersion(); binaryRepresentation[6] = (byte) (latest.getMajorVersion() >>> 8);