-
Notifications
You must be signed in to change notification settings - Fork 63
Description
Affected versions (it's strange, but javax.json.spi.JsonProvider is located both in javax.json:javax.json-api and org.glassfish:javax.json):
javax.json:javax.json-api:1.0 and org.glassfish:javax.json:1.0.4
JsonProvider.provide() is called from Json.createObjectBuilder() and does the following:
public static JsonProvider provider() {
ServiceLoader<JsonProvider> loader = ServiceLoader.load(JsonProvider.class);
Iterator<JsonProvider> it = loader.iterator();
...
}
As you can see it creates a new instance of ServiceLoader (via load(Class) method) each time the method provide() is invoked. Because of this cache of providers maintained by ServiceLoader is not used and loader.iterator() performs heavy search again and again...
The trace looks like
at java.util.zip.ZipFile.getEntry(Native Method)
at java.util.zip.ZipFile.getEntry(ZipFile.java:311)
- locked <0x00000000f801b3b8> (a java.util.jar.JarFile)
at java.util.jar.JarFile.getEntry(JarFile.java:240)
at java.util.jar.JarFile.getJarEntry(JarFile.java:223)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:841)
at sun.misc.URLClassPath$JarLoader.findResource(URLClassPath.java:819)
at sun.misc.URLClassPath$1.next(URLClassPath.java:226)
at sun.misc.URLClassPath$1.hasMoreElements(URLClassPath.java:236)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:589)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:587)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader$3.next(URLClassLoader.java:586)
at java.net.URLClassLoader$3.hasMoreElements(URLClassLoader.java:611)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at java.util.ServiceLoader$LazyIterator.hasNextService(ServiceLoader.java:354)
at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:393)
at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:474)
at javax.json.spi.JsonProvider.provider(JsonProvider.java:89)
at javax.json.Json.createObjectBuilder(Json.java:266)
In order to solve this performance problem one should create instance of ServiceLoader only once and reuse it in the JsonProvider.provide() method.
Environment
Oracle Java SE Runtime Environment (build 1.8.0-b132)
Affected Versions
[1.0.4]