McModLauncher / modlauncher

Java 21 mod launcher
Other
171 stars 47 forks source link

Error when computing hierarchy for class with interface that should be stripped #57

Closed ichttt closed 4 years ago

ichttt commented 4 years ago

This issue is somewhat complex to understand, so I'll try to explain it by example: The enviroment is a dedicated server. A transformer transforms the class CrossbowItem. This means modlauncher will re-compute the frames for this class. One of the frames requires the common superclass of FireworkRocketEntity and another class, so getSupers (https://github.com/cpw/modlauncher/blob/2f3da1afba50a180f02c9e700e582cdcb59ce42b/src/main/java/cpw/mods/modlauncher/TransformerClassWriter.java#L110) is called, which then calls computeHierarchy when FireworkRocketEntity has not been classloaded yet (https://github.com/cpw/modlauncher/blob/2f3da1afba50a180f02c9e700e582cdcb59ce42b/src/main/java/cpw/mods/modlauncher/TransformerClassWriter.java#L76) computeHierarchy reads the class metadata, and eventually reaches the visit (https://github.com/cpw/modlauncher/blob/2f3da1afba50a180f02c9e700e582cdcb59ce42b/src/main/java/cpw/mods/modlauncher/TransformerClassWriter.java#L134) Then it calls computeHierarchy for all interfaces that FireworkRocketEntity implements (https://github.com/cpw/modlauncher/blob/2f3da1afba50a180f02c9e700e582cdcb59ce42b/src/main/java/cpw/mods/modlauncher/TransformerClassWriter.java#L144). Modlauncher sees the interface IRendersAsItem, which is not present on the dedicated server, and crashes trying to lookup it (https://github.com/cpw/modlauncher/blob/2f3da1afba50a180f02c9e700e582cdcb59ce42b/src/main/java/cpw/mods/modlauncher/TransformerClassWriter.java#L94). Normally, the interface would not even be in the bytecode, but as there is a forge patch for FireworkRocketEntity, the binarypatcher also adds the interface (which is normally stripped by the obfuscator). This is not a problem in normal classloading however, as the RuntimeDistCleaner would remove the interface from the class before the ClassWriter or any other code would see it. But when loading a class for hiearchy lookup, no class transformers are run on the class, and so the interface will not be removed.

Possible solutions: 1: Define a new method on Launch Plugins that is being called when a Launch Plugin should perform class metadata transformation (such as changing super, adding/removing interfaces etc) 2: Just ignore when classes cannot be found (this would be more of a hack fix IMO)

Example log of the error: https://gist.github.com/Shadows-of-Fire/64fb62022cdd6c17b675a71663a0ba4f