aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java8
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java5
-rw-r--r--src/launch/lombok/launch/Main.java5
-rw-r--r--src/launch/lombok/launch/ShadowClassLoader.java46
4 files changed, 43 insertions, 21 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java
index b1327216..ea72f56a 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java
@@ -26,6 +26,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.Arrays;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
@@ -92,14 +93,15 @@ public class EclipseLoaderPatcherTransplants {
jf.close();
}
}
- Class[] paramTypes = new Class[4];
+ Class[] paramTypes = new Class[5];
paramTypes[0] = classLoaderClass;
paramTypes[1] = "".getClass();
paramTypes[2] = paramTypes[1];
- paramTypes[3] = new String[0].getClass();
+ paramTypes[3] = Class.forName("java.util.List");
+ paramTypes[4] = paramTypes[3];
Constructor constructor = shadowClassLoaderClass.getDeclaredConstructor(paramTypes);
constructor.setAccessible(true);
- shadowLoader = (ClassLoader) constructor.newInstance(new Object[] {original, "lombok", jarLoc, new String[] {"lombok."}});
+ shadowLoader = (ClassLoader) constructor.newInstance(new Object[] {original, "lombok", jarLoc, Arrays.asList(new Object[] {"lombok."}), Arrays.asList(new Object[] {"lombok.patcher.Symbols"})});
shadowLoaderField.set(original, shadowLoader);
}
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index 28e8d0c1..6e5871e6 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -75,8 +75,9 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
ScriptManager sm = new ScriptManager();
sm.registerTransformer(instrumentation);
sm.setTransplantMapper(new TransplantMapper() {
- public String getPrefixFor(int classFileFormatVersion) {
- return classFileFormatVersion > 49 ? "Class50/" : "";
+ public String mapResourceName(int classFileFormatVersion, String resourceName) {
+ if (classFileFormatVersion < 50) return resourceName;
+ return "Class50/" + resourceName;
}
});
diff --git a/src/launch/lombok/launch/Main.java b/src/launch/lombok/launch/Main.java
index 63d97d48..b81b6268 100644
--- a/src/launch/lombok/launch/Main.java
+++ b/src/launch/lombok/launch/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Project Lombok Authors.
+ * Copyright (C) 2014-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
@@ -22,10 +22,11 @@
package lombok.launch;
import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
class Main {
static ClassLoader createShadowClassLoader() {
- return new ShadowClassLoader(Main.class.getClassLoader(), "lombok");
+ return new ShadowClassLoader(Main.class.getClassLoader(), "lombok", null, Arrays.<String>asList(), Arrays.asList("lombok.patcher.Symbols"));
}
public static void main(String[] args) throws Throwable {
diff --git a/src/launch/lombok/launch/ShadowClassLoader.java b/src/launch/lombok/launch/ShadowClassLoader.java
index 8cfd5e39..83f64370 100644
--- a/src/launch/lombok/launch/ShadowClassLoader.java
+++ b/src/launch/lombok/launch/ShadowClassLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Project Lombok Authors.
+ * Copyright (C) 2014-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
@@ -37,6 +37,8 @@ import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -79,7 +81,7 @@ import java.util.jar.JarFile;
*/
class ShadowClassLoader extends ClassLoader {
private static final String SELF_NAME = "lombok/launch/ShadowClassLoader.class";
- private volatile static Class<?> lombokPatcherSymbols;
+ private static final ConcurrentMap<String, Class<?>> highlanderMap = new ConcurrentHashMap<String, Class<?>>();
private final String SELF_BASE;
private final File SELF_BASE_FILE;
@@ -88,21 +90,16 @@ class ShadowClassLoader extends ClassLoader {
private final List<File> override = new ArrayList<File>();
private final String sclSuffix;
private final List<String> parentExclusion = new ArrayList<String>();
-
- /**
- * Calls the {@link ShadowClassLoader(ClassLoader, String, String, String[]) constructor with no exclusions and the source of this class as base.
- */
- ShadowClassLoader(ClassLoader source, String sclSuffix) {
- this(source, sclSuffix, null);
- }
+ private final List<String> highlanders = new ArrayList<String>();
/**
* @param source The 'parent' classloader.
* @param sclSuffix The suffix of the shadowed class files in our own jar. For example, if this is {@code lombok}, then the class files in your jar should be {@code foo/Bar.SCL.lombok} and not {@code foo/Bar.class}.
* @param selfBase The (preferably absolute) path to our own jar. This jar will be searched for class/SCL.sclSuffix files.
* @param parentExclusion For example {@code "lombok."}; upon invocation of loadClass of this loader, the parent loader ({@code source}) will NOT be invoked if the class to be loaded begins with anything in the parent exclusion list. No exclusion is applied for getResource(s).
+ * @param highlanders SCL will put in extra effort to ensure that these classes (in simple class spec, so {@code foo.bar.baz.ClassName}) are only loaded once as a class, even if many different classloaders try to load classes, such as equinox/OSGi.
*/
- ShadowClassLoader(ClassLoader source, String sclSuffix, String selfBase, String... parentExclusion) {
+ ShadowClassLoader(ClassLoader source, String sclSuffix, String selfBase, List<String> parentExclusion, List<String> highlanders) {
super(source);
this.sclSuffix = sclSuffix;
if (parentExclusion != null) for (String pe : parentExclusion) {
@@ -110,6 +107,9 @@ class ShadowClassLoader extends ClassLoader {
if (!pe.endsWith("/")) pe = pe + "/";
this.parentExclusion.add(pe);
}
+ if (highlanders != null) for (String hl : highlanders) {
+ this.highlanders.add(hl);
+ }
if (selfBase != null) {
SELF_BASE = selfBase;
@@ -362,8 +362,12 @@ class ShadowClassLoader extends ClassLoader {
if (alreadyLoaded != null) return alreadyLoaded;
}
- if (lombokPatcherSymbols != null && name.equals("lombok.patcher.Symbols")) return lombokPatcherSymbols;
- String fileNameOfClass = name.replace(".", "/") + ".class";
+ if (highlanders.contains(name)) {
+ Class<?> c = highlanderMap.get(name);
+ if (c != null) return c;
+ }
+
+ String fileNameOfClass = name.replace(".", "/") + ".class";
URL res = getResource_(fileNameOfClass, true);
if (res == null) {
if (!exclusionListMatch(fileNameOfClass)) return super.loadClass(name, resolve);
@@ -394,8 +398,22 @@ class ShadowClassLoader extends ClassLoader {
throw new ClassNotFoundException("I/O exception reading class " + name, e);
}
- Class<?> c = defineClass(name, b, 0, p);
- if (name.equals("lombok.patcher.Symbols")) lombokPatcherSymbols = c;
+ Class<?> c;
+ try {
+ c = defineClass(name, b, 0, p);
+ } catch (LinkageError e) {
+ if (highlanders.contains(name)) {
+ Class<?> alreadyDefined = highlanderMap.get(name);
+ if (alreadyDefined != null) return alreadyDefined;
+ }
+ throw e;
+ }
+
+ if (highlanders.contains(name)) {
+ Class<?> alreadyDefined = highlanderMap.putIfAbsent(name, c);
+ if (alreadyDefined != null) c = alreadyDefined;
+ }
+
if (resolve) resolveClass(c);
return c;
}