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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
File file = new File(rulesFile);
|
||||
|
@ -156,7 +125,7 @@ public class AccessTransformer implements IClassTransformer
|
|||
processATFile(Resources.asCharSource(rulesResource, Charsets.UTF_8));
|
||||
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>()
|
||||
{
|
||||
|
|
|
@ -1,34 +1,71 @@
|
|||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
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 com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.util.jar.Manifest;
|
||||
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 {
|
||||
private static List<AccessTransformer> embedded = Lists.newArrayList();
|
||||
public ModAccessTransformer() throws IOException
|
||||
private static Map<String, String> embedded = Maps.newHashMap(); //Needs to be primitive so that both classloaders get the same class.
|
||||
public ModAccessTransformer() throws Exception
|
||||
{
|
||||
super(ModAccessTransformer.class);
|
||||
for (AccessTransformer at : embedded)
|
||||
{
|
||||
mergeModifiers(at.getModifiers());
|
||||
}
|
||||
}
|
||||
//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!
|
||||
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
|
||||
{
|
||||
AccessTransformer at = new AccessTransformer(jar);
|
||||
if (!at.isEmpty())
|
||||
Manifest manifest = jar.getManifest();
|
||||
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