-
Bug
-
Resolution: Unresolved
-
P4
-
9
-
None
As mentioned in [1], it's required for a custom factory to provide getDefault() method. At a runtime this is "checked" in [2] and [3]. But the java.lang.Class.getMethod has a tricky contract, namely:
"1. C is searched for any matching methods. If no matching method is found, the algorithm of step 1 is invoked recursively on the superclass of C.
2. If no method was found in step 1 above, the superinterfaces of C are searched for a matching method. If any such method is found, it is reflected."
Thus if one accidentally forgets to define a getDefault() method in a custom socket factory, the method will still be found. But it will be the method of javax.net.SocketFactory rather than of a custom factory. Currently this leads to a bizarre and non-obvious exception:
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.jndi.ldap.Connection.createSocket(Connection.java:328)
at com.sun.jndi.ldap.Connection.<init>(Connection.java:203)
... 18 more
Since getDefault() is a static method, it cannot be inherited. And the compiler doesn't enforce it to be "overridden". This check should be provided at a runtime.
-------------------------------------------------
[1] http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html
[2] http://hg.openjdk.java.net/jdk9/dev/jdk/file/7028bbbbdc6f/src/share/classes/com/sun/jndi/ldap/Connection.java#l283
[3] http://hg.openjdk.java.net/jdk9/dev/jdk/file/7028bbbbdc6f/src/share/classes/com/sun/jndi/ldap/ClientId.java#l92
"1. C is searched for any matching methods. If no matching method is found, the algorithm of step 1 is invoked recursively on the superclass of C.
2. If no method was found in step 1 above, the superinterfaces of C are searched for a matching method. If any such method is found, it is reflected."
Thus if one accidentally forgets to define a getDefault() method in a custom socket factory, the method will still be found. But it will be the method of javax.net.SocketFactory rather than of a custom factory. Currently this leads to a bizarre and non-obvious exception:
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.jndi.ldap.Connection.createSocket(Connection.java:328)
at com.sun.jndi.ldap.Connection.<init>(Connection.java:203)
... 18 more
Since getDefault() is a static method, it cannot be inherited. And the compiler doesn't enforce it to be "overridden". This check should be provided at a runtime.
-------------------------------------------------
[1] http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html
[2] http://hg.openjdk.java.net/jdk9/dev/jdk/file/7028bbbbdc6f/src/share/classes/com/sun/jndi/ldap/Connection.java#l283
[3] http://hg.openjdk.java.net/jdk9/dev/jdk/file/7028bbbbdc6f/src/share/classes/com/sun/jndi/ldap/ClientId.java#l92