From e61f2d3e7ab003b2baa7fa2c743ab02b67c4a5d6 Mon Sep 17 00:00:00 2001 From: Angelos Bimpoudis Date: Mon, 24 Jun 2024 15:31:06 +0200 Subject: [PATCH] Fix NPE for null ClassLoader --- src/java.base/share/classes/java/lang/Class.java | 10 ++++++++-- .../Deconstructor/SimpleDeconstructorsTest.java | 11 +++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index dc6272d54b6..70156584bc4 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -112,6 +112,7 @@ import sun.reflect.annotation.*; import sun.reflect.misc.ReflectUtil; +import static java.lang.ClassLoader.getPlatformClassLoader; import static java.lang.constant.ConstantDescs.CD_void; /** @@ -2308,7 +2309,7 @@ public Constructor[] getConstructors() throws SecurityException { private Method[] filterOutDeconstructorsFromMethods(Method[] in) { Set isPattern = new HashSet<>(); ClassModel cm = null; - try (InputStream resource = ClassLoader.getSystemResourceAsStream(getName() + ".class")) { + try (InputStream resource = ClassLoader.getSystemResourceAsStream(getResourcePath())) { if (resource == null) { return in; } @@ -2413,7 +2414,8 @@ public Deconstructor[] getDeclaredDeconstructors() throws SecurityException { private Deconstructor[] getDeclaredDeconstructors0(Class[] params, int which) { ArrayList> decs = new ArrayList<>(); - try(InputStream is = ClassLoader.getSystemResourceAsStream(getName() + ".class")) { + if (this.isPrimitive()) return new Deconstructor[0]; + try(InputStream is = ClassLoader.getSystemResourceAsStream(getResourcePath())) { byte[] bytes = is.readAllBytes(); ClassModel cm = ClassFile.of().parse(bytes); for (MethodModel mm : cm.methods()) { @@ -2489,6 +2491,10 @@ private Deconstructor[] getDeclaredDeconstructors0(Class[] params, int whi return decs.toArray(new Deconstructor[decs.size()]); } + private String getResourcePath() { + return this.getName().replace('.', '/') + ".class"; + } + private static ByteBuffer getAnnotationContents(boolean exists, BoundAttribute boundAttribute) { if (exists) { byte rvpaBytes[] = boundAttribute.contents(); diff --git a/test/jdk/java/lang/reflect/Deconstructor/SimpleDeconstructorsTest.java b/test/jdk/java/lang/reflect/Deconstructor/SimpleDeconstructorsTest.java index e0ff73c5417..e22b83d7868 100644 --- a/test/jdk/java/lang/reflect/Deconstructor/SimpleDeconstructorsTest.java +++ b/test/jdk/java/lang/reflect/Deconstructor/SimpleDeconstructorsTest.java @@ -54,6 +54,7 @@ public static void main(String[] args) throws NoSuchPatternException, IllegalAcc testDeconstructorAnnotations(); testGenericString(); testGetDeclaredDeconstructors_bug1(); + testGetDeclaredDeconstructors_bug2(); } public static void testGetMethods() { @@ -174,6 +175,16 @@ public static void testGetDeclaredDeconstructors_bug1() { assertEquals(methods.length, 1); } + public static void testGetDeclaredDeconstructors_bug2() { + Deconstructor[] methods = null; + + methods = String.class.getDeclaredDeconstructors(); + assertEquals(methods.length, 0); + + methods = int.class.getDeclaredDeconstructors(); + assertEquals(methods.length, 0); + } + static void assertEquals(Object actual, Object expected) { if (!Objects.equals(expected, actual)) { throw new AssertionError("Expected: " + expected + ", but got: " + actual);