Skip to content

Commit 93a276b

Browse files
committed
Add initial support for new Java 9 class file format (JDK-8148785) (#97)
Add initial support for new Java 9 class file format (Java 9 b119, see JDK-8148785, JDK-8150011)
1 parent de96b66 commit 93a276b

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

src/main/java/de/thetaphi/forbiddenapis/AsmUtils.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,20 @@
1616

1717
package de.thetaphi.forbiddenapis;
1818

19+
import java.io.EOFException;
20+
import java.io.IOException;
21+
import java.io.InputStream;
22+
import java.io.PushbackInputStream;
1923
import java.net.URISyntaxException;
2024
import java.net.URL;
25+
import java.nio.ByteBuffer;
26+
import java.nio.ByteOrder;
2127
import java.util.Locale;
2228
import java.util.regex.Pattern;
2329

30+
import org.objectweb.asm.ClassReader;
31+
import org.objectweb.asm.Opcodes;
32+
2433
/** Some static utilities for analyzing with ASM, also constants. */
2534
public final class AsmUtils {
2635

@@ -146,5 +155,27 @@ public static String getModuleName(URL jrtUrl) {
146155
return null;
147156
}
148157
}
158+
159+
private static void patchClassMajorVersion(byte[] header, int versionFrom, int versionTo) {
160+
final ByteBuffer buf = ByteBuffer.wrap(header).order(ByteOrder.BIG_ENDIAN);
161+
if (buf.getShort(6) == versionFrom) {
162+
buf.putShort(6, (short) versionTo);
163+
}
164+
}
165+
166+
/** Utility method to load class files of Java 9 by patching them, so ASM can read them. */
167+
public static ClassReader readAndPatchClass(InputStream in) throws IOException {
168+
final byte[] b = new byte[8];
169+
final PushbackInputStream pbin = new PushbackInputStream(in, b.length);
170+
for (int upto = 0; upto < b.length;) {
171+
final int read = pbin.read(b, upto, b.length - upto);
172+
if (read == -1)
173+
throw new EOFException("Not enough bytes available to read header of class file.");
174+
upto += read;
175+
}
176+
patchClassMajorVersion(b, Opcodes.V1_8 + 1, Opcodes.V1_8);
177+
pbin.unread(b);
178+
return new ClassReader(pbin);
179+
}
149180

150181
}

src/main/java/de/thetaphi/forbiddenapis/Checker.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ private ClassSignature loadClassFromJigsaw(String classname) throws IOException
245245
}
246246

247247
try {
248-
return new ClassSignature(new ClassReader(in), AsmUtils.isRuntimeModule(moduleName), false);
248+
return new ClassSignature(AsmUtils.readAndPatchClass(in), AsmUtils.isRuntimeModule(moduleName), false);
249249
} finally {
250250
in.close();
251251
}
@@ -297,7 +297,7 @@ private ClassSignature getClassFromClassLoader(final String clazz) throws ClassN
297297
final boolean isRuntimeClass = isRuntimeClass(conn);
298298
final InputStream in = conn.getInputStream();
299299
try {
300-
classpathClassCache.put(clazz, c = new ClassSignature(new ClassReader(in), isRuntimeClass, false));
300+
classpathClassCache.put(clazz, c = new ClassSignature(AsmUtils.readAndPatchClass(in), isRuntimeClass, false));
301301
} finally {
302302
in.close();
303303
}
@@ -528,7 +528,7 @@ private void parseSignaturesFile(Reader reader, boolean isBundled) throws IOExce
528528
public void addClassToCheck(final InputStream in) throws IOException {
529529
final ClassReader reader;
530530
try {
531-
reader = new ClassReader(in);
531+
reader = AsmUtils.readAndPatchClass(in);
532532
} finally {
533533
in.close();
534534
}

src/tools/java/de/thetaphi/forbiddenapis/DeprecatedGen.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ protected boolean isDeprecated(int access) {
6969
protected void parseClass(InputStream in) throws IOException {
7070
final ClassReader reader;
7171
try {
72-
reader = new ClassReader(in);
72+
reader = AsmUtils.readAndPatchClass(in);
7373
} catch (IllegalArgumentException iae) {
7474
// unfortunately the ASM IAE has no message, so add good info!
7575
throw new IllegalArgumentException("The class file format of your runtime seems to be too recent to be parsed by ASM (may need to be upgraded).");

0 commit comments

Comments
 (0)