aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2015-03-31 00:32:21 +0200
committerReinier Zwitserloot <reinier@zwitserloot.com>2015-03-31 00:32:21 +0200
commitd831aabf6cf04a793792fec712912e31d537d4c9 (patch)
tree6a01c7cbb91b76656ebb7ecf0fbe3023784e2e30
parentfa38498f793ae1af8a916a51de01735f727bc7fc (diff)
downloadlombok-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.java2
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java79
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();
}
}