Hi Blackdrag,

thank you for your reply. I have created a minimal IntelliJ 2017.1.2 Groovy project that exhibits the problem (without the Groovy lib it is only 16KB, so I can mail it to you or upload it somewhere).
It contains just 4 simple classes:
public abstract class MicraEntityMinimalJava {
 public boolean preventEntitySpawning;
}

@CompileStatic
class MicramodEntityMinimalCompileStaticGroovy extends MicraEntityMinimalJava {
 MicramodEntityMinimalCompileStaticGroovy() { this.preventEntitySpawning = true }
}

class MicramodEntityMinimalGroovy extends MicraEntityMinimalJava {
 MicramodEntityMinimalGroovy() { this.preventEntitySpawning = true }
}

class MicramodEntityMinimalJava extends MicraEntityMinimalJava {
 MicramodEntityMinimalJava() {
  this.preventEntitySpawning = true;
 }
}
Which, when compiled in IntelliJ using groovy-2.4.11 under Java 1.8.0_131, give the following class files (decompiled using IntelliJ):
public abstract class MicraEntityMinimalJava {
  public boolean preventEntitySpawning;
  public MicraEntityMinimalJava() {}
}

public class MicramodEntityMinimalCompileStaticGroovy extends MicraEntityMinimalJava implements GroovyObject {
  public MicramodEntityMinimalCompileStaticGroovy() {
    MetaClass var1 = this.$getStaticMetaClass();
    this.metaClass = var1;
    boolean var2 = true;
    ScriptBytecodeAdapter.setGroovyObjectProperty(Boolean.valueOf(var2), MicramodEntityMinimalCompileStaticGroovy.class, this, (String)"preventEntitySpawning");
  }
}

public class MicramodEntityMinimalGroovy extends MicraEntityMinimalJava implements GroovyObject {
  public MicramodEntityMinimalGroovy() {
    CallSite[] var1 = $getCallSiteArray();
    MetaClass var2 = this.$getStaticMetaClass();
    this.metaClass = var2;
    boolean var3 = true;
    ScriptBytecodeAdapter.setGroovyObjectProperty(Boolean.valueOf(var3), MicramodEntityMinimalGroovy.class, this, (String)"preventEntitySpawning");
  }
}

class MicramodEntityMinimalJava extends MicraEntityMinimalJava {
  MicramodEntityMinimalJava() {
    this.preventEntitySpawning = true;
  }
}

The way I see it, the MicramodEntityMinimalJava.class file has the form that works with Mineforge, since it contains a preventEntitySpawning field access which the Mineforge obfuscator finds.
The two Groovy class files access the field through setGroovyObjectProperty with the String argument "preventEntitySpawning", which the Mineforge obfuscator does not replace, since it has no explicit Groovy support.

If I understand you correctly, the class file coming from MicramodEntityMinimalCompileStaticGroovy does not have the form you would have expected, and it should look like the one coming from MicramodEntityMinimalJava ?

I hope this helps,
Ahm
Am 12.06.2017 um 10:19 schrieb Jochen Theodorou:
On 10.06.2017 21:52, Ahm Avoby wrote:
Hi, I am a Groovy developer at work, and am trying to switch my sons Minecraft 1.11.2 project (Forge based) from Java to Groovy 2.4.11. Since the generated class files need to be obfuscated to work with Minecraft, I am using @CompileStatic, as suggested by another Minecraft developer, so that the Forge obfuscator finds the field/method names in the class files. This works in some cases, but when trying to access fields of the base class (e.g. net.minecraft.entity.Entity) I am encountering groovy.lang.MissingPropertyException|s.
you need the obfuscation to be able to call into the obfuscated minecraft code I assume. It sounds very much like a bug if calling to a accessible super class field ends up in a MissingPropertyException. Is it possible for you to make a small example? Though I had assumed, that if you use forge, you do not need to do that anymore. Well, modding on minecraft is not unknown to me, but I never tried to mod myself. So of course I have no idea about the details.
I don't have much experience using @CompileStatic (nor with Minecraft modding), but looking at the generated class files, it seems as if property (same for fields) access is not compiled statically, but remains a call to ScriptBytecodeAdapter.setProperty, with the property name given as a string literal (ergo the obfuscator won't see it, and the call in Minecraft will fail). I have explained this more in-depth with code samples on minecraftforum.net, but did not get a reply ( http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/modification-development/2828852-groovy-compilestatic-solution-not-working-when).
Frankly, about every setProperty/getProperty call in @CompileStatic is not right and needs fixing.
Can anyone confirm to me that what I am seeing is the excpected @CompileStatic behavior - so using @CompileStatic on all Groovy classes is not the solution to modding Minecraft with Groovy - or if there is something I can do differently ?
That is not the expected behaviour, no. If you can provide samples, especially a small script, that shows the problem but has no other dependencies, you would help us to fix this. As for obfuscation in Groovy in general... I think it can be done, but there are some limitations, even with @CompileStatic. Our final goal for @CompileStatic is to have a runtime, that has only the minimum required dynamic elements, but right now we have a lot of methods, that you usually call, that have more a naming convention, than anything else. And such conventions do not translate to obfuscation well. For example doCall in Closure, asBoolean, and iterator are very central here, as they are called from the runtime dynamically even if @CompileStatic is used. But excluding those few would then already do the job.. well... in theory... if @CompileStatic does not fall back to a dynamic setProperty for a reason it should not do that of course.
I would also be grateful for any other suggestion at a solution - I really would like to avoid having to revert the project back to its Java version :-)
depending on the problem we could fix it and ensure there is a speedy 2.4.12. Other solution my also require knowing the nature of the problem first bye Jochen