diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2015-03-31 00:32:21 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2015-03-31 00:32:21 +0200 |
commit | d831aabf6cf04a793792fec712912e31d537d4c9 (patch) | |
tree | 6a01c7cbb91b76656ebb7ecf0fbe3023784e2e30 | |
parent | fa38498f793ae1af8a916a51de01735f727bc7fc (diff) | |
download | lombok-d831aabf6cf04a793792fec712912e31d537d4c9.tar.gz lombok-d831aabf6cf04a793792fec712912e31d537d4c9.tar.bz2 lombok-d831aabf6cf04a793792fec712912e31d537d4c9.zip |
We are getting some reports that might indicate there’s a race condition in loading shadowclassloader. This should fix that.
-rw-r--r-- | src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java | 2 | ||||
-rw-r--r-- | src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java | 79 |
2 files changed, 43 insertions, 38 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java index 8616e9bc..c137cb46 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java @@ -44,7 +44,7 @@ public class EclipseLoaderPatcher { .transplant() .request(StackRequest.THIS, StackRequest.PARAM1, StackRequest.PARAM2).build()); - sm.addScript(ScriptBuilder.addField().setPublic() + sm.addScript(ScriptBuilder.addField().setPublic().setVolatile() .fieldType("Ljava/lang/ClassLoader;") .fieldName("lombok$shadowLoader") .targetClass("org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader") diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java index f50e6987..b7268e01 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java @@ -55,44 +55,49 @@ public class EclipseLoaderPatcherTransplants { Field shadowLoaderField = original.getClass().getField("lombok$shadowLoader"); ClassLoader shadowLoader = (ClassLoader) shadowLoaderField.get(original); if (shadowLoader == null) { - String jarLoc = (String) original.getClass().getField("lombok$location").get(null); - JarFile jf = new JarFile(jarLoc); - InputStream in = null; - try { - ZipEntry entry = jf.getEntry("lombok/launch/ShadowClassLoader.class"); - in = jf.getInputStream(entry); - byte[] bytes = new byte[65536]; - int len = 0; - while (true) { - int r = in.read(bytes, len, bytes.length - len); - if (r == -1) break; - len += r; - if (len == bytes.length) throw new IllegalStateException("lombok.launch.ShadowClassLoader too large."); + synchronized ("lombok$shadowLoader$globalLock".intern()) { + shadowLoader = (ClassLoader) shadowLoaderField.get(original); + if (shadowLoader == null) { + String jarLoc = (String) original.getClass().getField("lombok$location").get(null); + JarFile jf = new JarFile(jarLoc); + InputStream in = null; + try { + ZipEntry entry = jf.getEntry("lombok/launch/ShadowClassLoader.class"); + in = jf.getInputStream(entry); + byte[] bytes = new byte[65536]; + int len = 0; + while (true) { + int r = in.read(bytes, len, bytes.length - len); + if (r == -1) break; + len += r; + if (len == bytes.length) throw new IllegalStateException("lombok.launch.ShadowClassLoader too large."); + } + in.close(); + Class classLoaderClass = Class.forName("java.lang.ClassLoader"); + Class shadowClassLoaderClass; { + Class[] paramTypes = new Class[4]; + paramTypes[0] = "".getClass(); + paramTypes[1] = new byte[0].getClass(); + paramTypes[2] = Integer.TYPE; + paramTypes[3] = paramTypes[2]; + Method defineClassMethod = classLoaderClass.getDeclaredMethod("defineClass", paramTypes); + defineClassMethod.setAccessible(true); + shadowClassLoaderClass = (Class) defineClassMethod.invoke(original, new Object[] {"lombok.launch.ShadowClassLoader", bytes, new Integer(0), new Integer(len)}); + } + Class[] paramTypes = new Class[4]; + paramTypes[0] = classLoaderClass; + paramTypes[1] = "".getClass(); + paramTypes[2] = paramTypes[1]; + paramTypes[3] = new String[0].getClass(); + Constructor constructor = shadowClassLoaderClass.getDeclaredConstructor(paramTypes); + constructor.setAccessible(true); + shadowLoader = (ClassLoader) constructor.newInstance(new Object[] {original, "lombok", jarLoc, new String[] {"lombok."}}); + shadowLoaderField.set(original, shadowLoader); + } finally { + if (in != null) in.close(); + jf.close(); + } } - in.close(); - Class classLoaderClass = Class.forName("java.lang.ClassLoader"); - Class shadowClassLoaderClass; { - Class[] paramTypes = new Class[4]; - paramTypes[0] = "".getClass(); - paramTypes[1] = new byte[0].getClass(); - paramTypes[2] = Integer.TYPE; - paramTypes[3] = paramTypes[2]; - Method defineClassMethod = classLoaderClass.getDeclaredMethod("defineClass", paramTypes); - defineClassMethod.setAccessible(true); - shadowClassLoaderClass = (Class) defineClassMethod.invoke(original, new Object[] {"lombok.launch.ShadowClassLoader", bytes, new Integer(0), new Integer(len)}); - } - Class[] paramTypes = new Class[4]; - paramTypes[0] = classLoaderClass; - paramTypes[1] = "".getClass(); - paramTypes[2] = paramTypes[1]; - paramTypes[3] = new String[0].getClass(); - Constructor constructor = shadowClassLoaderClass.getDeclaredConstructor(paramTypes); - constructor.setAccessible(true); - shadowLoader = (ClassLoader) constructor.newInstance(new Object[] {original, "lombok", jarLoc, new String[] {"lombok."}}); - shadowLoaderField.set(original, shadowLoader); - } finally { - if (in != null) in.close(); - jf.close(); } } |