Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8319436

Proxy.newProxyInstance throws NPE if loader is null and interface not visible from class loader

XMLWordPrintable

    • b23
    • generic
    • generic
    • Verified

        ADDITIONAL SYSTEM INFORMATION :
        Seen since JDK 21 and JDK 17.0.8

        A DESCRIPTION OF THE PROBLEM :
        Ref: https://bugs.openjdk.org/browse/JDK-8302791
        This changed the exception handling to include the classloader name in the IllegalArgumentException.

        If the caller passes null as the classloader, and an IllegalArgument exception is raised, an NPE is thrown since JDK 17.0.8 ...

        Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.ClassLoader.nameAndId()" because "loader" is null
        at java.base/java.lang.System$2.getLoaderNameID(System.java:2456)
        at java.base/java.lang.reflect.Proxy$ProxyBuilder.ensureVisible(Proxy.java:884)
        at java.base/java.lang.reflect.Proxy$ProxyBuilder.validateProxyInterfaces(Proxy.java:721)

        Previously the IllegalArgumentException was thrown.

        Null is a valid classloader argument, and the change here is not safe.


        REGRESSION : Last worked in JDK 20 and JDK 17.0.7

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Run test case provided as "java TestProxy an.interace.name a.jar"
        Use any jar you have, so long as the interface class isn't on the boot classpath.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        IllegalArgumentException from ensureVisible if classloader is null
        Test case should produce - GOOD - JDK 17.0.7 or earlier gets here
        ACTUAL -
        NPE from ensureVisible if classloader is null
        Test case produces - BAD - JDK 17.0.8 or later gets here

        ---------- BEGIN SOURCE ----------
        import java.lang.reflect.InvocationHandler;
        import java.lang.reflect.Method;
        import java.lang.reflect.Proxy;
        import java.net.URL;
        import java.net.URLClassLoader;

        /**
         * Run as ...
         *
         * TestProxy an.interface a.jar
         *
         * ... where an.interface is any interface in the jar that isn't on the boot classpath.
         *
         */
        public class TestProxy
        {
            public static void main(String[] args)
            {
                String iclz = args[0]; // An interface class (not on the boot class
                                       // path)
                String jar = args[1]; // A jar file containing the interface class

                try
                {
                    URL[] urls =
                    { new URL("jar:file:" + jar + "!/") };
                    URLClassLoader cl = URLClassLoader.newInstance(urls);
                    Class clazz = cl.loadClass(iclz);

                    Object str = Proxy.newProxyInstance(null, new Class<?>[]
                    { clazz }, new InvocationHandler()
                    {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
                        {
                            System.out.println("Invoked " + method.getName());
                            return null;
                        }

                    });

                    System.out.println(str.toString());
                }
                catch (IllegalArgumentException ex)
                {
                    System.err.println("GOOD - JDK 17.0.7 or earlier gets here");
                }
                catch (NullPointerException ex)
                {
                    System.err.println("BAD - JDK 17.0.8 or later gets here");
                }
                catch (Throwable t)
                {
                    System.err.println("Test is broken, shouldn't get here");
                }
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Tolerate the NPE in calling code.

        FREQUENCY : always


              mchung Mandy Chung
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              10 Start watching this issue

                Created:
                Updated:
                Resolved: