diff options
20 files changed, 755 insertions, 115 deletions
@@ -138,7 +138,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr </target> <target name="compile" depends="version, ensureBuildDeps, -unpackLibs" description="Compiles the code."> - <!-- ant includes the destination dir on the classpath (and there are good reason to do this), but that also means + <!-- ant includes the destination dir on the classpath (and there are good reasons to do this), but that also means the bleeding edge lombok from the previous build is run, which means if there are bugs in it, you can't compile anymore until you 'ant clean'. That's very much not desired, so we kill the processor, which stops lombok from running. We re-create the file at the end of this target. --> @@ -155,16 +155,14 @@ the common tasks and can be called on to run the main aspects of all the sub-scr </ivy:compile> <ivy:compile destdir="build/lombok-utils" source="1.5" target="1.5" includeantruntime="false"> - <compilerarg value="-Xbootclasspath/p:lib/openJDK6Environment/rt-openjdk6.jar" /> - <compilerarg value="-Xbootclasspath/p:build/stubs" /> + <compilerarg value="-Xbootclasspath/p:build/stubs${path.separator}lib/openJDK6Environment/rt-openjdk6.jar" /> <src path="src/utils" /> <exclude name="lombok/javac/**" /> <classpath refid="build.path" /> </ivy:compile> <ivy:compile destdir="build/lombok-utils" source="1.6" target="1.6" includeantruntime="false"> - <compilerarg value="-Xbootclasspath/p:lib/openJDK6Environment/rt-openjdk6.jar" /> - <compilerarg value="-Xbootclasspath/p:build/stubs" /> + <compilerarg value="-Xbootclasspath/p:build/stubs${path.separator}lib/openJDK6Environment/rt-openjdk6.jar" /> <src path="src/utils" /> <include name="lombok/javac/**" /> <classpath location="build/lombok-utils" /> @@ -176,8 +174,8 @@ the common tasks and can be called on to run the main aspects of all the sub-scr </copy> <ivy:compile destdir="build/lombok" source="1.5" target="1.5" includeantruntime="false"> - <compilerarg value="-Xbootclasspath/p:lib/openJDK6Environment/rt-openjdk6.jar" /> - <compilerarg value="-Xbootclasspath/p:build/stubs" /> + <compilerarg value="-Xbootclasspath/p:build/stubs${path.separator}lib/openJDK6Environment/rt-openjdk6.jar" /> + <src path="src/launch" /> <src path="src/core" /> <src path="src/installer" /> <src path="src/eclipseAgent" /> @@ -187,8 +185,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr </ivy:compile> <ivy:compile destdir="build/lombok" source="1.6" target="1.6" includeantruntime="false"> - <compilerarg value="-Xbootclasspath/p:lib/openJDK6Environment/rt-openjdk6.jar" /> - <compilerarg value="-Xbootclasspath/p:build/stubs" /> + <compilerarg value="-Xbootclasspath/p:build/stubs${path.separator}lib/openJDK6Environment/rt-openjdk6.jar" /> <src path="src/core" /> <src path="src/delombok" /> <include name="lombok/javac/**" /> @@ -198,7 +195,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr </ivy:compile> <mkdir dir="build/lombok/META-INF" /> <mkdir dir="build/lombok/META-INF/services" /> - <echo file="build/lombok/META-INF/services/javax.annotation.processing.Processor">lombok.core.AnnotationProcessor</echo> + <echo file="build/lombok/META-INF/services/javax.annotation.processing.Processor">lombok.launch.AnnotationProcessorHider.AnnotationProcessor</echo> </target> <target name="dist" description="Builds THE lombok.jar file which contains everything." depends="version, compile"> @@ -208,25 +205,40 @@ the common tasks and can be called on to run the main aspects of all the sub-scr <format property="releaseTimestamp" pattern="yyyy-MM-dd" /> </tstamp> <echo file="release-timestamp.txt">${releaseTimestamp}</echo> - <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="lib/build/com.googlecode.jarjar-jarjar.jar" /> - <jarjar destfile="dist/lombok-${lombok.version}.jar"> - <fileset dir="build/lombok"> - <exclude name="com/sun/tools/javac/**"/> - </fileset> + <zip destfile="dist/lombok-${lombok.version}.jar"> <fileset dir="build" includes="changelog.txt" /> <fileset dir="." includes="LICENSE" /> <fileset dir="." includes="AUTHORS" /> <fileset dir="." includes="release-timestamp.txt" /> - <rule pattern="com.zwitserloot.cmdreader.**" result="lombok.libs.com.zwitserloot.cmdreader.@1" /> - <rule pattern="org.objectweb.asm.**" result="lombok.libs.org.objectweb.asm.@1" /> + <fileset dir="build/lombok"> + <include name="lombok/*.class" /> + <include name="lombok/experimental/**" /> + <include name="lombok/extern/**" /> + <include name="lombok/launch/**" /> + </fileset> + <mappedresources> + <fileset dir="build/lombok"> + <exclude name="com/sun/tools/javac/**" /> + <exclude name="lombok/*.class" /> + <exclude name="lombok/experimental/**" /> + <exclude name="lombok/extern/**" /> + <exclude name="lombok/launch/**" /> + </fileset> + <firstmatchmapper> + <globmapper from="*.class" to="*.SCL.lombok" /> + <identitymapper /> + </firstmatchmapper> + </mappedresources> + </zip> + <jar destfile="dist/lombok-${lombok.version}.jar" update="true"> <manifest> - <attribute name="Premain-Class" value="lombok.core.Agent" /> - <attribute name="Agent-Class" value="lombok.core.Agent" /> + <attribute name="Premain-Class" value="lombok.launch.Agent" /> + <attribute name="Agent-Class" value="lombok.launch.Agent" /> <attribute name="Can-Redefine-Classes" value="true" /> - <attribute name="Main-Class" value="lombok.core.Main" /> + <attribute name="Main-Class" value="lombok.launch.Main" /> <attribute name="Lombok-Version" value="${lombok.version}" /> </manifest> - </jarjar> + </jar> <delete file="release-timestamp.txt" /> <copy file="dist/lombok-${lombok.version}.jar" tofile="dist/lombok.jar" /> <property name="lombok.dist.built" value="true" /> @@ -251,6 +263,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr <conf name="test" sources="contrib" /> <module name="lombok" depends="build, test"> <srcdir dir="src/core" /> + <srcdir dir="src/launch" /> <srcdir dir="src/utils" /> <srcdir dir="src/eclipseAgent" /> <srcdir dir="src/installer" /> @@ -280,6 +293,7 @@ the common tasks and can be called on to run the main aspects of all the sub-scr <target name="eclipse" depends="-addEclipseDeps, deps, contrib" description="Creates eclipse project files and downloads all dependencies. Open this directory as project in eclipse after running this target. This will NOT let you start a debug session for eclipse; use target 'eclipseForDebugging' instead to do that."> <ivy:eclipsegen source="1.6"> <srcdir dir="src/core" /> + <srcdir dir="src/launch" /> <srcdir dir="src/utils" /> <srcdir dir="src/eclipseAgent" /> <srcdir dir="src/installer" /> @@ -610,6 +624,7 @@ You can also create your own by writing a 'testenvironment.properties' file. The </jar> <jar destfile="dist/lombok-${lombok.version}-sources.jar"> <fileset dir="src/core" /> + <fileset dir="src/launch" /> <fileset dir="src/utils" /> <fileset dir="src/eclipseAgent" /> <fileset dir="src/installer" /> diff --git a/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.15.xml b/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.16.xml index df00b1c6..6e10702b 100644 --- a/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.15.xml +++ b/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.16.xml @@ -1,5 +1,5 @@ <ivy-module version="2.0"> - <info organisation="org.projectlombok" module="lombok.patcher" revision="0.15" publication="20140522015400"> + <info organisation="org.projectlombok" module="lombok.patcher" revision="0.16" publication="20141204000000"> <license name="MIT License" url="http://www.opensource.org/licenses/mit-license.php" /> <ivyauthor name="rzwitserloot" url="http://zwitserloot.com/" /> <ivyauthor name="rspilker" url="http://github.com/rspilker" /> @@ -9,6 +9,6 @@ <conf name="default" /> </configurations> <publications> - <artifact conf="default" url="http://projectlombok.org/downloads/lombok.patcher-0.15.jar" /> + <artifact conf="default" url="http://projectlombok.org/downloads/lombok.patcher-0.16.jar" /> </publications> </ivy-module> diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml index 41f58632..1cc249e7 100644 --- a/buildScripts/ivy.xml +++ b/buildScripts/ivy.xml @@ -15,7 +15,7 @@ <conf name="javac7" /> </configurations> <dependencies> - <dependency org="org.projectlombok" name="lombok.patcher" rev="0.15" conf="buildBase->default; runtime->default" /> + <dependency org="org.projectlombok" name="lombok.patcher" rev="0.16" conf="buildBase->default; runtime->default" /> <dependency org="zwitserloot.com" name="cmdreader" rev="1.2" conf="buildBase->runtime; runtime" /> <dependency org="junit" name="junit" rev="4.8.2" conf="test->default; contrib->sources" /> diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 72b6e24c..e4a004af 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -1,8 +1,8 @@ Lombok Changelog ---------------- -### v1.14.9 "Edge Guinea Pig" -* edge +### v1.14.9.shadow "<del>Edgy</del> Shadowy Guinea Pig" +* Added a launcher to the lombok boot process which removes the need for `-Xbootclasspath` to be in your `eclipse.ini` file, and removes all non-public API and third party dependencies (such as ASM) from the lombok jar, thus removing them from your IDE's auto complete offerings in any project that uses lombok. For those debugging lombok, the launcher enables hot code replace which makes debugging a lot easier, as previously one was required to shut down the IDE, rebuild the jar, and relaunch. Add `-Dshadow.override.lombok=/path/to/lombok/bin` to the launch target for hot code replace. ### v1.14.8 (September 15th, 2014) * PERFORMANCE: The configuration system typically hit the filesystem twice per read configuration key instead of hardly ever. This is a continuation of [Issue #682](https://code.google.com/p/projectlombok/issues/detail?id=682). diff --git a/src/core/lombok/core/Agent.java b/src/core/lombok/core/AgentLauncher.java index 49c03bf3..1d5ab3e6 100644 --- a/src/core/lombok/core/Agent.java +++ b/src/core/lombok/core/AgentLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Project Lombok Authors. + * Copyright (C) 2009-2014 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 @@ -21,45 +21,32 @@ */ package lombok.core; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; import java.lang.instrument.Instrumentation; -import java.security.ProtectionDomain; import java.util.Arrays; import java.util.Collections; import java.util.List; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; - -public abstract class Agent { - protected abstract void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception; - - public static void agentmain(String agentArgs, Instrumentation instrumentation) throws Throwable { - runAgents(agentArgs, instrumentation, true); +public class AgentLauncher { + public interface AgentLaunchable { + void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected, Class<?> launchingContext) throws Exception; } - public static void premain(String agentArgs, Instrumentation instrumentation) throws Throwable { - runAgents(agentArgs, instrumentation, false); - } - - private static final List<AgentInfo> AGENTS = Collections.unmodifiableList(Arrays.asList( - new NetbeansPatcherInfo(), - new EclipsePatcherInfo() - )); - - private static void runAgents(String agentArgs, Instrumentation instrumentation, boolean injected) throws Throwable { + public static void runAgents(String agentArgs, Instrumentation instrumentation, boolean injected, Class<?> launchingContext) throws Throwable { for (AgentInfo info : AGENTS) { try { Class<?> agentClass = Class.forName(info.className()); - Agent agent = (Agent) agentClass.newInstance(); - agent.runAgent(agentArgs, instrumentation, injected); + AgentLaunchable agent = (AgentLaunchable) agentClass.newInstance(); + agent.runAgent(agentArgs, instrumentation, injected, launchingContext); } catch (Throwable t) { info.problem(t, instrumentation); } } } + private static final List<AgentInfo> AGENTS = Collections.unmodifiableList(Arrays.<AgentInfo>asList( + new EclipsePatcherInfo() + )); + private static abstract class AgentInfo { abstract String className(); @@ -91,45 +78,6 @@ public abstract class Agent { } } - private static class NetbeansPatcherInfo extends AgentInfo { - @Override String className() { - return "lombok.netbeans.agent.NetbeansPatcher"; - } - - @Override void problem(Throwable in, Instrumentation instrumentation) throws Throwable { - try { - super.problem(in, instrumentation); - } catch (InternalError ie) { - throw ie; - } catch (Throwable t) { - final String error; - - if (t instanceof UnsupportedClassVersionError) { - error = "Lombok only works on netbeans if you start netbeans using a 1.6 or higher JVM.\n" + - "Change your platform's default JVM, or edit etc/netbeans.conf\n" + - "and explicitly tell netbeans your 1.6 JVM's location."; - } else { - error = "Lombok disabled due to error: " + t; - } - - instrumentation.addTransformer(new ClassFileTransformer() { - @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { - if ("org/netbeans/modules/java/source/parsing/JavacParser".equals(className)) { - //If that class gets loaded, this is definitely a netbeans(-esque) environment, and thus we SHOULD tell the user that lombok is not in fact loaded. - SwingUtilities.invokeLater(new Runnable() { - @Override public void run() { - JOptionPane.showMessageDialog(null, error, "Lombok Disabled", JOptionPane.ERROR_MESSAGE); - } - }); - } - - return null; - } - }); - } - } - } - private static class EclipsePatcherInfo extends AgentInfo { @Override String className() { return "lombok.eclipse.agent.EclipsePatcher"; diff --git a/src/core/lombok/core/Main.java b/src/core/lombok/core/Main.java index d62fe3e4..0856d3b3 100644 --- a/src/core/lombok/core/Main.java +++ b/src/core/lombok/core/Main.java @@ -38,6 +38,7 @@ public class Main { )); public static void main(String[] args) throws IOException { + Thread.currentThread().setContextClassLoader(Main.class.getClassLoader()); int err = new Main(SpiLoadUtil.readAllFromIterator( SpiLoadUtil.findServices(LombokApp.class)), Arrays.asList(args)).go(); System.exit(err); diff --git a/src/core/lombok/core/PostCompiler.java b/src/core/lombok/core/PostCompiler.java index 11091cb8..237867cb 100644 --- a/src/core/lombok/core/PostCompiler.java +++ b/src/core/lombok/core/PostCompiler.java @@ -24,6 +24,8 @@ package lombok.core; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.Collections; import java.util.List; @@ -55,10 +57,12 @@ public final class PostCompiler { transformations = SpiLoadUtil.readAllFromIterator(SpiLoadUtil.findServices(PostCompilerTransformation.class, PostCompilerTransformation.class.getClassLoader())); } catch (IOException e) { transformations = Collections.emptyList(); - diagnostics.addWarning("Could not load post-compile transformers: " + e.getMessage()); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + diagnostics.addWarning("Could not load post-compile transformers: " + e.getMessage() + "\n" + sw.toString()); } } - + public static OutputStream wrapOutputStream(final OutputStream originalStream, final String fileName, final DiagnosticsReceiver diagnostics) throws IOException { if (System.getProperty("lombok.disablePostCompiler", null) != null) return originalStream; return new ByteArrayOutputStream() { diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index 9f810525..02bc1af0 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -30,7 +30,7 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "1.14.9"; + private static final String VERSION = "1.14.9.shadow"; private static final String RELEASE_NAME = "Edgy Guinea Pig"; // private static final String RELEASE_NAME = "Branching Cobra"; diff --git a/src/core/lombok/eclipse/handlers/HandlePrintAST.java b/src/core/lombok/eclipse/handlers/HandlePrintAST.java index 0b61bc4d..234e29b8 100644 --- a/src/core/lombok/eclipse/handlers/HandlePrintAST.java +++ b/src/core/lombok/eclipse/handlers/HandlePrintAST.java @@ -59,7 +59,7 @@ public class HandlePrintAST extends EclipseAnnotationHandler<PrintAST> { try { stream.close(); } catch (Exception e) { - Lombok.sneakyThrow(e); + throw Lombok.sneakyThrow(e); } } } diff --git a/src/core/lombok/javac/handlers/HandlePrintAST.java b/src/core/lombok/javac/handlers/HandlePrintAST.java index 9a52b9d9..0826d1d1 100644 --- a/src/core/lombok/javac/handlers/HandlePrintAST.java +++ b/src/core/lombok/javac/handlers/HandlePrintAST.java @@ -59,7 +59,7 @@ public class HandlePrintAST extends JavacAnnotationHandler<PrintAST> { try { stream.close(); } catch (Exception e) { - Lombok.sneakyThrow(e); + throw Lombok.sneakyThrow(e); } } } diff --git a/src/delombok/lombok/delombok/DelombokApp.java b/src/delombok/lombok/delombok/DelombokApp.java index 276bd7de..aa753fc8 100644 --- a/src/delombok/lombok/delombok/DelombokApp.java +++ b/src/delombok/lombok/delombok/DelombokApp.java @@ -88,7 +88,7 @@ public class DelombokApp extends LombokApp { // Since we only read from it, not closing it should not be a problem. @SuppressWarnings({"resource", "all"}) final JarFile toolsJarFile = new JarFile(toolsJar); - ClassLoader loader = new ClassLoader() { + ClassLoader loader = new ClassLoader(DelombokApp.class.getClassLoader()) { private Class<?> loadStreamAsClass(String name, boolean resolve, InputStream in) throws ClassNotFoundException { try { try { @@ -107,16 +107,24 @@ public class DelombokApp extends LombokApp { } finally { in.close(); } - } catch (IOException e2) { + } catch (Exception e2) { throw new ClassNotFoundException(name, e2); } } @Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { - String rawName = name.replace(".", "/") + ".class"; + String rawName, altName; { + String binName = name.replace(".", "/"); + rawName = binName + ".class"; + altName = binName + ".SCL.lombok"; + } JarEntry entry = toolsJarFile.getJarEntry(rawName); if (entry == null) { - if (name.startsWith("lombok.")) return loadStreamAsClass(name, resolve, super.getResourceAsStream(rawName)); + if (name.startsWith("lombok.")) { + InputStream res = getParent().getResourceAsStream(rawName); + if (res == null) res = getParent().getResourceAsStream(altName); + return loadStreamAsClass(name, resolve, res); + } return super.loadClass(name, resolve); } diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java new file mode 100644 index 00000000..0d21c212 --- /dev/null +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java @@ -0,0 +1,106 @@ +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; +import lombok.patcher.ScriptManager; +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"; + + public static void patchEquinoxLoaders(ScriptManager sm, Class<?> launchingContext) { + sm.addScript(ScriptBuilder.exitEarly() + .target(new MethodTarget("org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader", "loadClass", + "java.lang.Class", "java.lang.String", "boolean")) + .target(new MethodTarget("org.eclipse.osgi.framework.adapter.core.AbstractClassLoader", "loadClass", + "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")) + .transplant() + .request(StackRequest.THIS, StackRequest.PARAM1, StackRequest.PARAM2).build()); + + sm.addScript(ScriptBuilder.addField().setPublic() + .fieldType("Ljava/lang/ClassLoader;") + .fieldName("lombok$shadowLoader") + .targetClass("org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader") + .targetClass("org.eclipse.osgi.framework.adapter.core.AbstractClassLoader") + .targetClass("org.eclipse.osgi.internal.loader.ModuleClassLoader") + .build()); + + sm.addScript(ScriptBuilder.addField().setPublic().setStatic().setFinal() + .fieldType("Ljava/lang/String;") + .fieldName("lombok$location") + .targetClass("org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader") + .targetClass("org.eclipse.osgi.framework.adapter.core.AbstractClassLoader") + .targetClass("org.eclipse.osgi.internal.loader.ModuleClassLoader") + .value(ClassRootFinder.findClassRootOfClass(launchingContext)) + .build()); + } +} diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index e14d1367..96f253f2 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -28,13 +28,13 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import lombok.core.Agent; +import lombok.core.AgentLauncher; + import lombok.patcher.Hook; import lombok.patcher.MethodTarget; import lombok.patcher.ScriptManager; import lombok.patcher.StackRequest; import lombok.patcher.TargetMatcher; -import lombok.patcher.equinox.EquinoxClassLoader; import lombok.patcher.scripts.ScriptBuilder; /** @@ -44,13 +44,12 @@ import lombok.patcher.scripts.ScriptBuilder; * classes in this package for more information about which classes are transformed and how they are * transformed. */ -public class EclipsePatcher extends Agent { +public class EclipsePatcher implements AgentLauncher.AgentLaunchable { // At some point I'd like the agent to be capable of auto-detecting if its on eclipse or on ecj. This class is a sure sign we're not in ecj but in eclipse. -ReinierZ @SuppressWarnings("unused") private static final String ECLIPSE_SIGNATURE_CLASS = "org/eclipse/core/runtime/adaptor/EclipseStarter"; - @Override - public void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception { + @Override public void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected, Class<?> launchingContext) throws Exception { String[] args = agentArgs == null ? new String[0] : agentArgs.split(":"); boolean forceEcj = false; boolean forceEclipse = false; @@ -69,15 +68,14 @@ public class EclipsePatcher extends Agent { else if (forceEclipse) ecj = false; else ecj = injected; - registerPatchScripts(instrumentation, injected, ecj); + registerPatchScripts(instrumentation, injected, ecj, launchingContext); } - private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses, boolean ecjOnly) { + private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses, boolean ecjOnly, Class<?> launchingContext) { ScriptManager sm = new ScriptManager(); sm.registerTransformer(instrumentation); if (!ecjOnly) { - EquinoxClassLoader.addPrefix("lombok."); - EquinoxClassLoader.registerScripts(sm); + EclipseLoaderPatcher.patchEquinoxLoaders(sm, launchingContext); } if (!ecjOnly) { diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java index 8eec27fb..44adb333 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java @@ -224,7 +224,8 @@ public class PatchExtensionMethod { if (methodCall.arguments != null) arguments.addAll(Arrays.asList(methodCall.arguments)); List<TypeBinding> argumentTypes = new ArrayList<TypeBinding>(); for (Expression argument : arguments) { - argumentTypes.add(argument.resolvedType); + if (argument.resolvedType != null) argumentTypes.add(argument.resolvedType); + // TODO: Instead of just skipping nulls entirely, there is probably a 'unresolved type' placeholder. THAT is what we ought to be adding here! } MethodBinding fixedBinding = scope.getMethod(extensionMethod.declaringClass, methodCall.selector, argumentTypes.toArray(new TypeBinding[0]), methodCall); if (fixedBinding instanceof ProblemMethodBinding) { diff --git a/src/installer/lombok/installer/InstallerGUI.java b/src/installer/lombok/installer/InstallerGUI.java index 5717948a..41832e5d 100644 --- a/src/installer/lombok/installer/InstallerGUI.java +++ b/src/installer/lombok/installer/InstallerGUI.java @@ -820,9 +820,8 @@ public class InstallerGUI { private static final String HOW_I_WORK_EXPLANATION = "<html><h2>Eclipse</h2><ol>" + "<li>First, I copy myself (lombok.jar) to your Eclipse install directory.</li>" + - "<li>Then, I edit the <i>eclipse.ini</i> file to add the following two entries:<br>" + - "<pre>-Xbootclasspath/a:lombok.jar<br>" + - "-javaagent:lombok.jar</pre></li></ol>" + + "<li>Then, I edit the <i>eclipse.ini</i> file to add the following entry:<br>" + + "<pre>-javaagent:lombok.jar</pre></li></ol>" + "On Mac OS X, eclipse.ini is hidden in<br>" + "<code>Eclipse.app/Contents/MacOS</code> so that's where I place the jar files.</html>"; diff --git a/src/installer/lombok/installer/eclipse/EclipseLocation.java b/src/installer/lombok/installer/eclipse/EclipseLocation.java index e347cd98..0fe60c05 100644 --- a/src/installer/lombok/installer/eclipse/EclipseLocation.java +++ b/src/installer/lombok/installer/eclipse/EclipseLocation.java @@ -337,8 +337,6 @@ public class EclipseLocation extends IdeLocation { newContents.append(String.format( "-javaagent:%s", escapePath(fullPathToLombok + "lombok.jar"))).append(OS_NEWLINE); - newContents.append(String.format( - "-Xbootclasspath/a:%s", escapePath(fullPathToLombok + "lombok.jar"))).append(OS_NEWLINE); FileOutputStream fos = new FileOutputStream(eclipseIniPath); try { @@ -360,8 +358,7 @@ public class EclipseLocation extends IdeLocation { } return "If you start " + getTypeName() + " with a custom -vm parameter, you'll need to add:<br>" + - "<code>-vmargs -Xbootclasspath/a:lombok.jar -javaagent:lombok.jar</code><br>" + - "as parameter as well."; + "<code>-vmargs -javaagent:lombok.jar</code><br>as parameter as well."; } |
