groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ahm Avoby <>
Subject Re: Minecraft modding with Groovy: @CompileStatic not statically compiling fields ?
Date Mon, 12 Jun 2017 22:17:11 GMT
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 MicramodEntityMinimalCompileStaticGroovyextends MicraEntityMinimalJava
  MicramodEntityMinimalCompileStaticGroovy() {this.preventEntitySpawning =true }

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

class MicramodEntityMinimalJavaextends 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 MicramodEntityMinimalCompileStaticGroovyextends MicraEntityMinimalJavaimplements
GroovyObject {
   public MicramodEntityMinimalCompileStaticGroovy() {
     MetaClass var1 =this.$getStaticMetaClass();
     this.metaClass = var1;
     boolean var2 =true;
     ScriptBytecodeAdapter.setGroovyObjectProperty(Boolean.valueOf(var2), MicramodEntityMinimalCompileStaticGroovy.class,this,

public class MicramodEntityMinimalGroovyextends MicraEntityMinimalJavaimplements GroovyObject
   public MicramodEntityMinimalGroovy() {
     CallSite[] var1 = $getCallSiteArray();
     MetaClass var2 =this.$getStaticMetaClass();
     this.metaClass = var2;
     boolean var3 =true;
     ScriptBytecodeAdapter.setGroovyObjectProperty(Boolean.valueOf(var3), MicramodEntityMinimalGroovy.class,this,

class MicramodEntityMinimalJavaextends 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, but did not 
>> get a reply ( 

> 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 

View raw message