Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[shadowloader] Fix for lombok v1.16.0 no longer working in eclipses t…
…hat use -target 1.4 style class files (such as eclipse indigo). It’s a doozy.
- Loading branch information
1 parent
fd12196
commit 65de469
Showing
5 changed files
with
160 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters