diff --git a/common/cpw/mods/fml/relauncher/IFMLLoadingPlugin.java b/common/cpw/mods/fml/relauncher/IFMLLoadingPlugin.java index 972d9706f1..9349273189 100644 --- a/common/cpw/mods/fml/relauncher/IFMLLoadingPlugin.java +++ b/common/cpw/mods/fml/relauncher/IFMLLoadingPlugin.java @@ -1,5 +1,9 @@ package cpw.mods.fml.relauncher; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.Map; /** @@ -52,4 +56,23 @@ public interface IFMLLoadingPlugin * "coremodLocation" : the file this coremod loaded from, */ void injectData(Map data); + + + /** + * Annotate your load plugin with a list of package prefixes that will *not* be + * processed by the ASM transformation stack. + * + * Your plugin, and any transformers should *definitely* be in this list, because + * otherwise you can face problems with the classloader trying to transform classes + * with your transformer, whilst it is *loading* your transformer. Not pretty. + * + * @author cpw + * + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + public @interface TransformerExclusions + { + public String[] value() default ""; + } } diff --git a/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java b/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java index f5c818452c..3e17d947eb 100644 --- a/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java +++ b/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java @@ -9,27 +9,28 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Level; public class RelaunchClassLoader extends URLClassLoader { - private static String[] excludedPackages = { - "java.", "sun.", - "cpw.mods.fml.relauncher.", "net.minecraftforge.classloading." - }; + // Left behind for CCC/NEI compatibility + private static String[] excludedPackages = new String[0]; + // Left behind for CCC/NEI compatibility + private static String[] transformerExclusions = new String[0]; - private static String[] transformerExclusions = - { - "org.objectweb.asm.", "com.google.common.", "cpw.mods.fml.", "javax." - }; private List sources; private ClassLoader parent; private List transformers; private Map cachedClasses; + private Set classLoaderExceptions = new HashSet(); + private Set transformerExceptions = new HashSet(); + public RelaunchClassLoader(URL[] sources) { super(sources, null); @@ -39,6 +40,18 @@ public class RelaunchClassLoader extends URLClassLoader this.transformers = new ArrayList(2); // ReflectionHelper.setPrivateValue(ClassLoader.class, null, this, "scl"); Thread.currentThread().setContextClassLoader(this); + + // standard classloader exclusions + addClassLoaderExclusion("java."); + addClassLoaderExclusion("sun."); + addClassLoaderExclusion("cpw.mods.fml.relauncher."); + addClassLoaderExclusion("net.minecraftforge.classloading."); + + // standard transformer exclusions + addTransformerExclusion("javax."); + addTransformerExclusion("cpw.mods.fml."); + addTransformerExclusion("org.objectweb.asm."); + addTransformerExclusion("com.google.common."); } public void registerTransformer(String transformerClassName) @@ -55,7 +68,19 @@ public class RelaunchClassLoader extends URLClassLoader @Override public Class findClass(String name) throws ClassNotFoundException { - for (String st : excludedPackages) + // NEI/CCC compatibility code + if (excludedPackages.length != 0) + { + classLoaderExceptions.addAll(Arrays.asList(excludedPackages)); + excludedPackages = new String[0]; + } + if (transformerExclusions.length != 0) + { + transformerExceptions.addAll(Arrays.asList(transformerExclusions)); + transformerExclusions = new String[0]; + } + + for (String st : classLoaderExceptions) { if (name.startsWith(st)) { @@ -68,7 +93,7 @@ public class RelaunchClassLoader extends URLClassLoader return cachedClasses.get(name); } - for (String st : transformerExclusions) + for (String st : transformerExceptions) { if (name.startsWith(st)) { @@ -181,4 +206,14 @@ public class RelaunchClassLoader extends URLClassLoader { return Collections.unmodifiableList(transformers); } + + private void addClassLoaderExclusion(String toExclude) + { + classLoaderExceptions.add(toExclude); + } + + void addTransformerExclusion(String toExclude) + { + transformerExceptions.add(toExclude); + } } diff --git a/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java b/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java index 7143f86a74..c5bd92a96d 100644 --- a/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java +++ b/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java @@ -25,6 +25,8 @@ import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.logging.Level; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions; + public class RelaunchLibraryManager { private static String[] rootPlugins = { "cpw.mods.fml.relauncher.FMLCorePlugin" , "net.minecraftforge.classloading.FMLForgePlugin" }; @@ -319,7 +321,16 @@ public class RelaunchLibraryManager try { downloadMonitor.updateProgressString("Loading coremod %s", coreMod.getName()); + classLoader.addTransformerExclusion(fmlCorePlugin); Class coreModClass = Class.forName(fmlCorePlugin, true, classLoader); + TransformerExclusions trExclusions = coreModClass.getAnnotation(IFMLLoadingPlugin.TransformerExclusions.class); + if (trExclusions!=null) + { + for (String st : trExclusions.value()) + { + classLoader.addTransformerExclusion(st); + } + } IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) coreModClass.newInstance(); loadPlugins.add(plugin); pluginLocations .put(plugin, coreMod);