RFR (S) 8057936: java.net.URLClassLoader.findClass uses exceptions in control flow
Hi, please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader. bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/ /Claes
On 09/10/2014 02:11 PM, Claes Redestad wrote:
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/
Looks good. Any performance data for this abbreviated patch? I see only the improvement for the stackless version of it. Thanks, -Aleksey.
On 10/09/2014 11:11, Claes Redestad wrote:
Hi,
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/ I think this looks okay. I assume FoundClassResult doesn't strictly need to encapsulate the class name.
-Alan.
If a lambda were used instead of an anonymous class, it would save us one line of code :-) Sincerely yours, Ivan On 10.09.2014 14:11, Claes Redestad wrote:
Hi,
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/ /Claes
I think lambda would not help much since target type is ambiguous (PrivilegedAction vs PrivilegedExceptionAction)? -Aleksey. On 09/10/2014 02:55 PM, Ivan Gerasimov wrote:
If a lambda were used instead of an anonymous class, it would save us one line of code :-)
Sincerely yours, Ivan
On 10.09.2014 14:11, Claes Redestad wrote:
Hi,
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/ /Claes
On 10.09.2014 14:58, Aleksey Shipilev wrote:
I think lambda would not help much since target type is ambiguous (PrivilegedAction vs PrivilegedExceptionAction)?
It could be explicitly cast as (PrivilegedAction<FindClassResult>) () -> {...} Would still be on the same line :-) Ivan
-Aleksey.
On 09/10/2014 02:55 PM, Ivan Gerasimov wrote:
If a lambda were used instead of an anonymous class, it would save us one line of code :-)
Sincerely yours, Ivan
On 10.09.2014 14:11, Claes Redestad wrote:
Hi,
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/ /Claes
On 10/09/2014 11:55, Ivan Gerasimov wrote:
If a lambda were used instead of an anonymous class, it would save us one line of code :-)
I don't know if a lambda would help here but I think changing would require a lot of testing to make sure that there aren't any side effects. We've had a couple of cases where code using lambdas early in the startup has lead to recursive initialization issues (due to various code paths in the lambda meta factory code). In this case, the system and extensions class loaders are URLClassLoader so this code is likely to be executed early. So if the intention is to push this to jdk8u-dev (which I think it is) then we would just need to make sure that it is well tested. -Alan.
or how about just returning a null Class<?> from the privileged block instead of the new result type only in the case where URLClassPath.getResource() returns null? That's the main "normal" case where the resource doesn't exist, I think. If defineClass() throws an IOException, then that is more likely to be a "genuine" exception - Michael diff --git a/src/java.base/share/classes/java/net/URLClassLoader.java b/src/java.base/share/classes/java/net/URLClassLoader.java --- a/src/java.base/share/classes/java/net/URLClassLoader.java +++ b/src/java.base/share/classes/java/net/URLClassLoader.java @@ -356,8 +356,9 @@ protected Class<?> findClass(final String name) throws ClassNotFoundException { + final Class<?> result; try { - return AccessController.doPrivileged( + result = AccessController.doPrivileged( new PrivilegedExceptionAction<Class<?>>() { public Class<?> run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(".class"); @@ -369,13 +370,17 @@ throw new ClassNotFoundException(name, e); } } else { - throw new ClassNotFoundException(name); + return null; } } }, acc); } catch (java.security.PrivilegedActionException pae) { throw (ClassNotFoundException) pae.getException(); } + if (result == null) { + throw new ClassNotFoundException(name); + } + return result; } /* On 10/09/14 11:55, Ivan Gerasimov wrote:
If a lambda were used instead of an anonymous class, it would save us one line of code :-)
Sincerely yours, Ivan
On 10.09.2014 14:11, Claes Redestad wrote:
Hi,
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/ /Claes
Yes, this saves creating the type and wrapper object altogether, while testing suggest it's only the getResource() == null cases wecommonly seehurting startup in our tests. I'd say let's go with your patch. New webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.4/ Benchmark referred to in bug (java -jar benchmarks.jar -f 4 -wi 5 -i 10 -p file=classes.jar)show similar benefits (somewhere in the 4-12% range, statistically): Benchmark (file) Mode Samples Score Score error Units baseline: o.o.ClassLoaderBenchmark.loadAll classes.jar avgt 40 0.679 0.037 s/op patched: o.o.ClassLoaderBenchmark.loadAll classes.jar avgt 40 0.598 0.007 s/op /Claes ps. I think lambdas give little or no benefit here, and as Alan points out it could lead to tricky classloading bugs. On 09/10/2014 01:21 PM, Michael McMahon wrote:
or how about just returning a null Class<?> from the privileged block instead of the new result type only in the case where URLClassPath.getResource() returns null? That's the main "normal" case where the resource doesn't exist, I think.
If defineClass() throws an IOException, then that is more likely to be a "genuine" exception
- Michael
diff --git a/src/java.base/share/classes/java/net/URLClassLoader.java b/src/java.base/share/classes/java/net/URLClassLoader.java --- a/src/java.base/share/classes/java/net/URLClassLoader.java +++ b/src/java.base/share/classes/java/net/URLClassLoader.java @@ -356,8 +356,9 @@ protected Class<?> findClass(final String name) throws ClassNotFoundException { + final Class<?> result; try { - return AccessController.doPrivileged( + result = AccessController.doPrivileged( new PrivilegedExceptionAction<Class<?>>() { public Class<?> run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(".class"); @@ -369,13 +370,17 @@ throw new ClassNotFoundException(name, e); } } else { - throw new ClassNotFoundException(name); + return null; } } }, acc); } catch (java.security.PrivilegedActionException pae) { throw (ClassNotFoundException) pae.getException(); } + if (result == null) { + throw new ClassNotFoundException(name); + } + return result; }
/*
On 10/09/14 11:55, Ivan Gerasimov wrote:
If a lambda were used instead of an anonymous class, it would save us one line of code :-)
Sincerely yours, Ivan
On 10.09.2014 14:11, Claes Redestad wrote:
Hi,
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/ /Claes
On 09/10/2014 03:53 PM, Claes Redestad wrote:
Yes, this saves creating the type and wrapper object altogether, while testing suggest it's only the getResource() == null cases we commonly see hurting startup in our tests. I'd say let's go with your patch.
New webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.4/
+1. This is much cleaner. Thanks, -Aleksey.
Hi Claes, On 10/09/2014 8:11 PM, Claes Redestad wrote:
Hi,
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/
I read the bug report and looked at the patch. I'm all for reducing the exception overhead, but why not just return the exception object directly and avoid the need to create a wrapper? Return object and check for a Class or Throwable - and rethrow the Throwable. David
/Claes
On 10/09/2014 10:30 PM, David Holmes wrote:
Hi Claes,
On 10/09/2014 8:11 PM, Claes Redestad wrote:
Hi,
please review this simple patch to avoid raising PrivilegedActionExceptions when failing to find a class in URLClassLoader.
bug: https://bugs.openjdk.java.net/browse/JDK-8057936 webrev: http://cr.openjdk.java.net/~redestad/8057936/webrev.2/
I read the bug report and looked at the patch. I'm all for reducing the exception overhead, but why not just return the exception object directly and avoid the need to create a wrapper? Return object and check for a Class or Throwable - and rethrow the Throwable.
Sorry email lag - just saw the later version. If the null resource case buys you enough then fine. Otherwise next step is to return the Throwables :) David
David
/Claes
participants (6)
-
Alan Bateman
-
Aleksey Shipilev
-
Claes Redestad
-
David Holmes
-
Ivan Gerasimov
-
Michael McMahon