aboutsummaryrefslogtreecommitdiff
path: root/src/eclipseAgent
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2015-02-08 14:16:59 +0100
committerReinier Zwitserloot <reinier@zwitserloot.com>2015-02-08 14:18:34 +0100
commit65de4693eb19a60e472b6e04aec0b9e083a648f4 (patch)
treeb9d86ddd51cb1087c526c090049a3456bf6dc789 /src/eclipseAgent
parentfd12196eea80f622686e049597eb5e86d4c98e7a (diff)
downloadlombok-65de4693eb19a60e472b6e04aec0b9e083a648f4.tar.gz
lombok-65de4693eb19a60e472b6e04aec0b9e083a648f4.tar.bz2
lombok-65de4693eb19a60e472b6e04aec0b9e083a648f4.zip
[shadowloader] Fix for lombok v1.16.0 no longer working in eclipses that use -target 1.4 style class files (such as eclipse indigo). It’s a doozy.
Diffstat (limited to 'src/eclipseAgent')
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java90
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java117
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java1
3 files changed, 141 insertions, 67 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java
index 0d21c212..8616e9bc 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java
@@ -1,13 +1,26 @@
+/*
+ * Copyright (C) 2015 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse.agent;
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-
import lombok.patcher.ClassRootFinder;
import lombok.patcher.Hook;
import lombok.patcher.MethodTarget;
@@ -16,62 +29,7 @@ import lombok.patcher.StackRequest;
import lombok.patcher.scripts.ScriptBuilder;
public class EclipseLoaderPatcher {
- public static boolean overrideLoadDecide(ClassLoader original, String name, boolean resolve) {
- return name.startsWith("lombok.");
- }
-
- public static Class<?> overrideLoadResult(ClassLoader original, String name, boolean resolve) throws ClassNotFoundException {
- try {
- 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.");
- }
- in.close();
- Class<?> shadowClassLoaderClass; {
- Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
- defineClassMethod.setAccessible(true);
- shadowClassLoaderClass = (Class<?>) defineClassMethod.invoke(original, "lombok.launch.ShadowClassLoader", bytes, 0, len);
- }
- Constructor<?> constructor = shadowClassLoaderClass.getDeclaredConstructor(ClassLoader.class, String.class, String.class, String[].class);
- constructor.setAccessible(true);
- shadowLoader = (ClassLoader) constructor.newInstance(original, "lombok", jarLoc, new String[] {"lombok."});
- shadowLoaderField.set(original, shadowLoader);
- } finally {
- if (in != null) in.close();
- jf.close();
- }
- }
-
- if (resolve) {
- Method m = shadowLoader.getClass().getDeclaredMethod("loadClass", String.class, boolean.class);
- m.setAccessible(true);
- return (Class<?>) m.invoke(shadowLoader, name, true);
- } else {
- return shadowLoader.loadClass(name);
- }
- } catch (Exception ex) {
- Throwable t = ex;
- if (t instanceof InvocationTargetException) t = t.getCause();
- if (t instanceof RuntimeException) throw (RuntimeException) t;
- if (t instanceof Error) throw (Error) t;
- throw new RuntimeException(t);
- }
- }
-
- private static final String SELF_NAME = "lombok.eclipse.agent.EclipseLoaderPatcher";
+ private static final String TRANSPLANTS_CLASS_NAME = "lombok.eclipse.agent.EclipseLoaderPatcherTransplants";
public static void patchEquinoxLoaders(ScriptManager sm, Class<?> launchingContext) {
sm.addScript(ScriptBuilder.exitEarly()
@@ -81,8 +39,8 @@ public class EclipseLoaderPatcher {
"java.lang.Class", "java.lang.String", "boolean"))
.target(new MethodTarget("org.eclipse.osgi.internal.loader.ModuleClassLoader", "loadClass",
"java.lang.Class", "java.lang.String", "boolean"))
- .decisionMethod(new Hook(SELF_NAME, "overrideLoadDecide", "boolean", "java.lang.ClassLoader", "java.lang.String", "boolean"))
- .valueMethod(new Hook(SELF_NAME, "overrideLoadResult", "java.lang.Class", "java.lang.ClassLoader", "java.lang.String", "boolean"))
+ .decisionMethod(new Hook(TRANSPLANTS_CLASS_NAME, "overrideLoadDecide", "boolean", "java.lang.ClassLoader", "java.lang.String", "boolean"))
+ .valueMethod(new Hook(TRANSPLANTS_CLASS_NAME, "overrideLoadResult", "java.lang.Class", "java.lang.ClassLoader", "java.lang.String", "boolean"))
.transplant()
.request(StackRequest.THIS, StackRequest.PARAM1, StackRequest.PARAM2).build());
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java
new file mode 100644
index 00000000..f50e6987
--- /dev/null
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.agent;
+
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+/**
+ * Contains all the code to be transplanted into eclipse.
+ *
+ * Do not use:
+ *
+ * * Annotations
+ * * Generics
+ * * Varargs
+ * * Auto (un)boxing
+ * * class literals
+ *
+ * The above because this code is compiled with -source 1.4, and is transplanted.
+ *
+ * NB: The suppress warnings will be stripped out before compilation.
+ */
+@SuppressWarnings("all")
+public class EclipseLoaderPatcherTransplants {
+ public static boolean overrideLoadDecide(ClassLoader original, String name, boolean resolve) {
+ return name.startsWith("lombok.");
+ }
+
+ public static Class overrideLoadResult(ClassLoader original, String name, boolean resolve) throws ClassNotFoundException {
+ try {
+ 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.");
+ }
+ 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();
+ }
+ }
+
+ if (resolve) {
+ Class[] paramTypes = new Class[2];
+ paramTypes[0] = "".getClass();
+ paramTypes[1] = Boolean.TYPE;
+ Method m = shadowLoader.getClass().getDeclaredMethod("loadClass", new Class[] {String.class, boolean.class});
+ m.setAccessible(true);
+ return (Class) m.invoke(shadowLoader, new Object[] {name, Boolean.TRUE});
+ } else {
+ return shadowLoader.loadClass(name);
+ }
+ } catch (Exception ex) {
+ Throwable t = ex;
+ if (t instanceof InvocationTargetException) t = t.getCause();
+ if (t instanceof RuntimeException) throw (RuntimeException) t;
+ if (t instanceof Error) throw (Error) t;
+ throw new RuntimeException(t);
+ }
+ }
+}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index efc7ce94..b8e3a955 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -29,7 +29,6 @@ import java.util.Collections;
import java.util.List;
import lombok.core.AgentLauncher;
-
import lombok.patcher.Hook;
import lombok.patcher.MethodTarget;
import lombok.patcher.ScriptManager;