Fix FMLAT manifest AccessTransformers, class loader fun! Closes #477
This commit is contained in:
parent
59c628f777
commit
4ed75fd963
2 changed files with 54 additions and 48 deletions
|
@ -106,41 +106,10 @@ public class AccessTransformer implements IClassTransformer
|
||||||
readMapFile(rulesFile);
|
readMapFile(rulesFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessTransformer(JarFile jar) throws IOException
|
|
||||||
{
|
|
||||||
Manifest manifest = jar.getManifest();
|
|
||||||
String atList = manifest.getMainAttributes().getValue("FMLAT");
|
|
||||||
if (atList == null) return;
|
|
||||||
for (String at : atList.split(" "))
|
|
||||||
{
|
|
||||||
JarEntry jarEntry = jar.getJarEntry("META-INF/"+at);
|
|
||||||
if (jarEntry != null)
|
|
||||||
{
|
|
||||||
processATFile(new JarByteSource(jar,jarEntry).asCharSource(Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer mod jar file %s\n", modifiers.size(), jar.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
AccessTransformer(Class<? extends AccessTransformer> dummyClazz)
|
AccessTransformer(Class<? extends AccessTransformer> dummyClazz)
|
||||||
{
|
{
|
||||||
// This is a noop
|
// This is a noop
|
||||||
}
|
}
|
||||||
private class JarByteSource extends ByteSource {
|
|
||||||
private JarFile jar;
|
|
||||||
private JarEntry entry;
|
|
||||||
public JarByteSource(JarFile jar, JarEntry entry)
|
|
||||||
{
|
|
||||||
this.jar = jar;
|
|
||||||
this.entry = entry;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public InputStream openStream() throws IOException
|
|
||||||
{
|
|
||||||
return jar.getInputStream(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
void readMapFile(String rulesFile) throws IOException
|
void readMapFile(String rulesFile) throws IOException
|
||||||
{
|
{
|
||||||
File file = new File(rulesFile);
|
File file = new File(rulesFile);
|
||||||
|
@ -156,7 +125,7 @@ public class AccessTransformer implements IClassTransformer
|
||||||
processATFile(Resources.asCharSource(rulesResource, Charsets.UTF_8));
|
processATFile(Resources.asCharSource(rulesResource, Charsets.UTF_8));
|
||||||
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer config file %s\n", modifiers.size(), rulesFile);
|
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer config file %s\n", modifiers.size(), rulesFile);
|
||||||
}
|
}
|
||||||
private void processATFile(CharSource rulesResource) throws IOException
|
protected void processATFile(CharSource rulesResource) throws IOException
|
||||||
{
|
{
|
||||||
rulesResource.readLines(new LineProcessor<Void>()
|
rulesResource.readLines(new LineProcessor<Void>()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,34 +1,71 @@
|
||||||
package cpw.mods.fml.common.asm.transformers;
|
package cpw.mods.fml.common.asm.transformers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import com.google.common.collect.Lists;
|
import java.util.jar.Manifest;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import com.google.common.io.CharSource;
|
||||||
|
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||||
|
|
||||||
public class ModAccessTransformer extends AccessTransformer {
|
public class ModAccessTransformer extends AccessTransformer {
|
||||||
private static List<AccessTransformer> embedded = Lists.newArrayList();
|
private static Map<String, String> embedded = Maps.newHashMap(); //Needs to be primitive so that both classloaders get the same class.
|
||||||
public ModAccessTransformer() throws IOException
|
public ModAccessTransformer() throws Exception
|
||||||
{
|
{
|
||||||
super(ModAccessTransformer.class);
|
super(ModAccessTransformer.class);
|
||||||
for (AccessTransformer at : embedded)
|
//We are in the new ClassLoader here, so we need to get the static field from the other ClassLoader.
|
||||||
{
|
ClassLoader classLoader = this.getClass().getClassLoader().getClass().getClassLoader(); //Bit odd but it gets the class loader that loaded our current class loader yay java!
|
||||||
mergeModifiers(at.getModifiers());
|
Class<?> otherClazz = Class.forName(this.getClass().getName(), true, classLoader);
|
||||||
}
|
Field otherField = otherClazz.getDeclaredField("embedded");
|
||||||
}
|
otherField.setAccessible(true);
|
||||||
|
embedded = (Map<String, String>)otherField.get(null);
|
||||||
|
|
||||||
private void mergeModifiers(Multimap<String, Modifier> modifiers)
|
for (Map.Entry<String, String> e : embedded.entrySet())
|
||||||
{
|
{
|
||||||
getModifiers().putAll(modifiers);
|
int old_count = getModifiers().size();
|
||||||
|
processATFile(CharSource.wrap(e.getValue()));
|
||||||
|
int added = getModifiers().size() - old_count;
|
||||||
|
if (added > 0)
|
||||||
|
{
|
||||||
|
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer mod jar file %s\n", added, e.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addJar(JarFile jar) throws IOException
|
public static void addJar(JarFile jar) throws IOException
|
||||||
{
|
{
|
||||||
AccessTransformer at = new AccessTransformer(jar);
|
Manifest manifest = jar.getManifest();
|
||||||
if (!at.isEmpty())
|
String atList = manifest.getMainAttributes().getValue("FMLAT");
|
||||||
|
if (atList == null) return;
|
||||||
|
for (String at : atList.split(" "))
|
||||||
{
|
{
|
||||||
embedded.add(at);
|
JarEntry jarEntry = jar.getJarEntry("META-INF/"+at);
|
||||||
|
if (jarEntry != null)
|
||||||
|
{
|
||||||
|
embedded.put(String.format("%s!META-INF/%s", jar.getName(), at),
|
||||||
|
new JarByteSource(jar,jarEntry).asCharSource(Charsets.UTF_8).read());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class JarByteSource extends ByteSource
|
||||||
|
{
|
||||||
|
private JarFile jar;
|
||||||
|
private JarEntry entry;
|
||||||
|
public JarByteSource(JarFile jar, JarEntry entry)
|
||||||
|
{
|
||||||
|
this.jar = jar;
|
||||||
|
this.entry = entry;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public InputStream openStream() throws IOException
|
||||||
|
{
|
||||||
|
return jar.getInputStream(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue