Jump to content

[1.7.10] [SOLVED] ClassDefNotFound after ClassTransformer is called?


superckl

Recommended Posts

Hey everyone,

 

I'm having a bit of a problem patching classes with ASM. I'm attempting to patch two functions, one in BiomeGenBase and one in ChunkProviderGenerate. The patching works fine for BiomeGenBase, however, the class cannot be found by the JVM once I've patched it. Here is my class transformer:

 

 

public class ClassTransformer implements IClassTransformer{

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
	FMLRelaunchLog.warning("%s", name);
	if(find(name, class_biomeGenBase) != -1){
		ClassNode cNode = new ClassNode();
		ClassReader reader = new ClassReader(bytes);
		reader.accept(cNode, 0);
		MethodNode mNode = null;
		//FMLRelaunchLog.warning("%s", Arrays.toString(cNode.methods.toArray()));
		for(MethodNode node:cNode.methods){
			FMLRelaunchLog.warning("%s:%s", node.name, node.desc);
			if(find(node.name, method_genBiomeTerrain) != -1 && find(node.desc, desc_genBiomeTerrain) != -1){
				mNode = node;
				break;
			}
		}
		if(mNode == null){
			LogHelper.error("Failed to replace water!");
			return bytes;
		}
		boolean fixed = false;
		for(AbstractInsnNode node:mNode.instructions.toArray()){
			if(node instanceof FieldInsnNode){
				FieldInsnNode vNode = (FieldInsnNode) node;
				LogHelper.info(vNode.name);
				if(find(vNode.name, field_blockWater) != -1){
					node = vNode.getNext();
					if(node instanceof VarInsnNode && ((VarInsnNode)node).var == 10){
						vNode.owner = "me/superckl/betteroceans/common/reference/ModBlocks";
						vNode.name = "saltWater";
						vNode.desc = "Lme/superckl/betteroceans/common/fluid/block/BlockFluidSaltWater;";
						LogHelper.info("Patched "+name+"."+mNode.name);
						fixed = true;
						break;
					}
				}
			}
		}
		LogHelper.info("Writing class with fixed: "+fixed);
		ClassWriter cWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
		cNode.accept(cWriter);
		return cWriter.toByteArray();
	}else if(find(name, class_chunkProviderGenerate) != -1){
		ClassNode cNode = new ClassNode();
		ClassReader reader = new ClassReader(bytes);
		reader.accept(cNode, 0);
		MethodNode mNode = null;
		//FMLRelaunchLog.warning("%s", Arrays.toString(cNode.methods.toArray()));
		for(MethodNode node:cNode.methods){
			FMLRelaunchLog.warning("%s:%s", node.name, node.desc);
			if(find(node.name, method_func_147424_a) != -1 && find(node.desc, desc_func_147424_a) != -1){
				mNode = node;
				break;
			}
		}
		if(mNode == null){
			LogHelper.error("Failed to replace water!");
			return bytes;
		}
		for(AbstractInsnNode node:mNode.instructions.toArray()){
			if(node instanceof FieldInsnNode){
				FieldInsnNode vNode = (FieldInsnNode) node;
				if(find(vNode.name, field_blockWater) != -1){
					vNode.owner = "me/superckl/betteroceans/common/reference/ModBlocks";
					vNode.name = "saltWater";
					vNode.desc = "Lme/superckl/betteroceans/common/fluid/block/BlockFluidSaltWater;";
					LogHelper.info("Patched "+name+"."+mNode.name);
				}
			}
		}
		ClassWriter cWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
		cNode.accept(cWriter);
		return cWriter.toByteArray();
	}
	return bytes;
}

public static <T> int find(final T toFind, final T[] in){
	for(int i = 0; i < in.length; i++)
		if(in[i] == toFind || in[i].equals(toFind))
			return i;
	return -1;
}


	public static final String[] field_ocean = {"ocean", "field_76771_b"};
	public static final String[] field_deepOcean = {"deepOcean", "field_150575_M"};
	public static final String[] field_blockWater = {"water", "field_150355_j", "j"};

	public static final String[] method_genBiomeTerrain = {"genBiomeTerrain", "func_150560_b", "b"};
	public static final String[] method_func_147424_a = {"func_147424_a", "a"};

	public static final String[] desc_genBiomeTerrain = {"(Lnet/minecraft/world/World;Ljava/util/Random;[Lnet/minecraft/block/Block;[bIID)V", "(Lahb;Ljava/util/Random;[Laji;[bIID)V"};
	public static final String[] desc_func_147424_a = {"(II[Lnet/minecraft/block/Block;)V", "(II[Laji;)V"};

	public static final String[] class_biomeGenBase = {"net.minecraft.world.biome.BiomeGenBase", "ahu"};
	public static final String[] class_chunkProviderGenerate = {"net.minecraft.world.gen.ChunkProviderGenerate", "aqz"};

}

 

 

And the error I get:

 

 

java.lang.NoClassDefFoundError: me/superckl/betteroceans/common/gen/BiomeGenBetterOcean

at me.superckl.betteroceans.common.utility.BiomeHelper.replaceOceanBiomes(BiomeHelper.java:22) ~[biomeHelper.class:?]

at me.superckl.betteroceans.BetterOceans.init(BetterOceans.java:59) ~[betterOceans.class:?]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_05]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_05]

at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_05]

at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:513) ~[forge-1.7.10-10.13.0.1183.jar:?]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_05]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_05]

at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_05]

at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-16.0.jar:?]

at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-16.0.jar:?]

at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-16.0.jar:?]

at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-16.0.jar:?]

at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-16.0.jar:?]

at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:208) ~[forge-1.7.10-10.13.0.1183.jar:?]

at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:187) ~[forge-1.7.10-10.13.0.1183.jar:?]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_05]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_05]

at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_05]

at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-16.0.jar:?]

at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-16.0.jar:?]

at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-16.0.jar:?]

at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-16.0.jar:?]

at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-16.0.jar:?]

at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:118) [LoadController.class:?]

at cpw.mods.fml.common.Loader.initializeMods(Loader.java:691) [Loader.class:?]

at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:288) [FMLClientHandler.class:?]

at net.minecraft.client.Minecraft.func_71384_a(Minecraft.java:541) [bao.class:?]

at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:867) [bao.class:?]

at net.minecraft.client.main.Main.main(SourceFile:148) [Main.class:?]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05]

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_05]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_05]

at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_05]

at net.minecraft.launchwrapper.Launch.launch(Launch.java:134) [launchwrapper-1.9.jar:?]

at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.9.jar:?]

Caused by: java.lang.ClassNotFoundException: me.superckl.betteroceans.common.gen.BiomeGenBetterOcean

at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:188) ~[launchwrapper-1.9.jar:?]

at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_05]

at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_05]

... 39 more

Caused by: java.lang.NoClassDefFoundError: net/minecraft/world/biome/BiomeGenBase

at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_05]

at java.lang.ClassLoader.defineClass(Unknown Source) ~[?:1.8.0_05]

at java.security.SecureClassLoader.defineClass(Unknown Source) ~[?:1.8.0_05]

at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:180) ~[launchwrapper-1.9.jar:?]

at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_05]

at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_05]

... 39 more

Caused by: java.lang.ClassNotFoundException: net.minecraft.world.biome.BiomeGenBase

at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:99) ~[launchwrapper-1.9.jar:?]

at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_05]

at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_05]

at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_05]

at java.lang.ClassLoader.defineClass(Unknown Source) ~[?:1.8.0_05]

at java.security.SecureClassLoader.defineClass(Unknown Source) ~[?:1.8.0_05]

at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:180) ~[launchwrapper-1.9.jar:?]

at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_05]

at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_05]

... 39 more

 

 

The error is thrown on this line of code:

 

final BiomeGenBetterOcean boO = new BiomeGenBetterOcean(BiomeGenBase.ocean.biomeID);

If I remove the class transformer, everything works fine. I'm not entirely sure what is going on here... Maybe I'm doing something completely wrong her - It's my first time working with ASM.

 

Thanks for any help you can offer.

 

EDIT: I forgot to mention that it works fine in my eclipse development environment. The patch works and does what it's supposed to. It seems like the obfuscation is messing it up in some way.

 

EDIT 2: Fixed! I just applied a sorting index of > 1000 to get above the FML deobfuscater and it all worked!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.