aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lombok/eclipse/TransformEclipseAST.java12
-rw-r--r--src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java83
2 files changed, 73 insertions, 22 deletions
diff --git a/src/lombok/eclipse/TransformEclipseAST.java b/src/lombok/eclipse/TransformEclipseAST.java
index ff40c110..9bc3326f 100644
--- a/src/lombok/eclipse/TransformEclipseAST.java
+++ b/src/lombok/eclipse/TransformEclipseAST.java
@@ -96,7 +96,17 @@ public class TransformEclipseAST {
EclipseAST.addProblemToCompilationResult(ast, false, message, 0, 0);
t.printStackTrace();
} catch ( Throwable t2 ) {
- Eclipse.error(ast, "Can't create an error in the problems dialog while adding: " + t.toString(), t2);
+ try {
+ Eclipse.error(ast, "Can't create an error in the problems dialog while adding: " + t.toString(), t2);
+ } catch ( Throwable t3 ) {
+ //This seems risky to just silently turn off lombok, but if we get this far, something pretty
+ //drastic went wrong. For example, the eclipse help system's JSP compiler will trigger a lombok call,
+ //but due to class loader shenanigans we'll actually get here due to a cascade of
+ //ClassNotFoundErrors. This is the right action for the help system (no lombok needed for that JSP compiler,
+ //of course). 'disableLombok' is static, but each context classloader (e.g. each eclipse OSGi plugin) has
+ //it's own edition of this class, so this won't turn off lombok everywhere.
+ disableLombok = true;
+ }
}
}
}
diff --git a/src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java b/src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java
index f804ef1d..42eeb02d 100644
--- a/src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java
+++ b/src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java
@@ -26,6 +26,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
/**
@@ -48,24 +50,65 @@ public class ClassLoaderWorkaround {
throw (T)t;
}
- private static boolean initialized;
- private static Method transform;
+ private static final Map<ClassLoader, Method> transform = new HashMap<ClassLoader, Method>();
public static void transformCompilationUnitDeclaration(Object parser, Object cud) throws Exception {
- initialize(cud);
+ Method transformMethod = getTransformMethod(cud);
try {
- transform.invoke(null, parser, cud);
+ checkTypeCompatible(parser.getClass(), "org.eclipse.jdt.internal.compiler.parser.Parser");
+ checkTypeCompatible(cud.getClass(), "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration");
+ try {
+ transformMethod.invoke(null, parser, cud);
+ } catch ( IllegalArgumentException ex ) {
+ checkTypeCompatible2(parser.getClass(), "org.eclipse.jdt.internal.compiler.parser.Parser");
+ checkTypeCompatible2(cud.getClass(), "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration");
+ throw ex;
+ }
} catch ( InvocationTargetException e ) {
throw sneakyThrow(e.getCause());
}
}
- private static void initialize(Object cud) throws ClassNotFoundException {
- if ( initialized ) {
- if ( transform == null ) throw new ClassNotFoundException("lombok.eclipse.TransformEclipseAST");
- return;
+ private static void checkTypeCompatible(Class<? extends Object> c, String expected) {
+ StringBuilder sb = new StringBuilder();
+ while ( c != null ) {
+ if ( c.getName().equals(expected) ) return;
+ sb.append(" ").append(c.getName());
+ c = c.getSuperclass();
+ }
+
+ System.err.println("Not a match to " + expected);
+ System.err.println(sb.toString());
+ }
+
+ private static void checkTypeCompatible2(Class<? extends Object> c, String expected) {
+ StringBuilder sb = new StringBuilder();
+ while ( c != null ) {
+ sb.append(" ").append(c.getName());
+ c = c.getSuperclass();
}
+ System.err.println("Expecting " + expected);
+ System.err.println(sb.toString());
+ }
+
+ private static Method getTransformMethod(Object cud) throws ClassNotFoundException {
+ ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
+
+ synchronized ( transform ) {
+ if ( !transform.containsKey(contextLoader)) {
+ System.out.println("Creating classloader: " + Thread.currentThread());
+ transform.put(contextLoader, findTransformMethod(cud));
+ }
+
+ Method m = transform.get(contextLoader);
+ if ( m == null ) throw new ClassNotFoundException("lombok.eclipse.TransformEclipseAST");
+ return m;
+
+ }
+ }
+
+ private static Method findTransformMethod(Object cud) throws ClassNotFoundException {
final ClassLoader parent = cud.getClass().getClassLoader();
ClassLoader loader = new ClassLoader() {
@Override public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
@@ -103,19 +146,17 @@ public class ClassLoaderWorkaround {
}
};
- try {
- Class<?> c = loader.loadClass("lombok.eclipse.TransformEclipseAST");
- for ( Method m : c.getMethods() ) {
- if ( m.getName().equals("transform") ) {
- Class<?>[] types = m.getParameterTypes();
- if ( types.length != 2 ) continue;
- if ( !types[0].getName().equals("org.eclipse.jdt.internal.compiler.parser.Parser") ) continue;
- if ( !types[1].getName().equals("org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration") ) continue;
- transform = m;
- break;
- }
+ Class<?> c = loader.loadClass("lombok.eclipse.TransformEclipseAST");
+ for ( Method method : c.getMethods() ) {
+ if ( method.getName().equals("transform") ) {
+ Class<?>[] types = method.getParameterTypes();
+ if ( types.length != 2 ) continue;
+ if ( !types[0].getName().equals("org.eclipse.jdt.internal.compiler.parser.Parser") ) continue;
+ if ( !types[1].getName().equals("org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration") ) continue;
+ return method;
}
- } catch ( ClassNotFoundException ignore ) {}
- initialized = true;
+ }
+
+ throw new ClassNotFoundException("lombok.eclipse.TransformEclipseAST");
}
}