0

I'm trying to make a mod, so I have been looking for a way to access a protected arrayList from another class. So far I have managed to use my new basic understanding of Java reflection in order to do so. I have been able to find the field I am looking for, but I have not yet been able to find a way to modify its elements because I believe that it is the casting that leads to multiple errors. Any suggestions for a way to solve this?

My code (repository https://github.com/dilosir22/BTAprodject/tree/master/src/main/java/com/example/examplemod):

public class LivingEntityHelper {

   static Field monsterList;

    static {
        try{
            Field[] feilds = BiomeGenBase.class.getDeclaredFields();
            for(Field feild : feilds) {
                    if(feild.getName().equals("spawnableMonsterList")) {
                        monsterList = feild;
                    }

            }
            if(monsterList == null) throw new RuntimeException("Could not find spawnableMonsterList feild!");
            monsterList.setAccessible(true);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @SuppressWarnings("unchecked")
    public static void addMonster(SpawnListEntry monster, Object biome){
        try {
            ((List<SpawnListEntry>) monsterList.get(biome)).add(monster);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

biomeGenBase contains:

protected List<SpawnListEntry> spawnableMonsterList;

As well as multiple static instances of itself (what the biome parameter in addMonster() is meant to specify when used).

This in its constructor:

this.spawnableMonsterList = new ArrayList();

The errors received:

[18:57:32] [Minecraft main thread] java.lang.RuntimeException: java.lang.IllegalArgumentException: Can not set java.util.List field net.minecraft.src.BiomeGenBase.spawnableMonsterList to java.lang.Class
[18:57:32] [Minecraft main thread]  at com.example.examplemod.util.LivingEntityHelper.addMonster(LivingEntityHelper.java:35)
[18:57:32] [Minecraft main thread]  at com.example.examplemod.ExampleMod.init(ExampleMod.java:15)
[18:57:32] [Minecraft main thread]  at bta.ModLoader.loadMod(ModLoader.java:120)
[18:57:32] [Minecraft main thread]  at bta.ModLoader.init(ModLoader.java:76)
[18:57:32] [Minecraft main thread]  at net.minecraft.client.Minecraft.startGame(Minecraft.java:309)
[18:57:32] [Minecraft main thread]  at net.minecraft.client.Minecraft.run(Minecraft.java:566)
[18:57:32] [Minecraft main thread]  at java.base/java.lang.Thread.run(Thread.java:833)
[18:57:32] [Minecraft main thread] Caused by: java.lang.IllegalArgumentException: Can not set java.util.List field net.minecraft.src.BiomeGenBase.spawnableMonsterList to java.lang.Class
[18:57:32] [Minecraft main thread]  at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
[18:57:32] [Minecraft main thread]  at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
[18:57:32] [Minecraft main thread]  at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
[18:57:32] [Minecraft main thread]  at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
[18:57:32] [Minecraft main thread]  at java.base/java.lang.reflect.Field.get(Field.java:425)
[18:57:32] [Minecraft main thread]  at com.example.examplemod.util.LivingEntityHelper.addMonster(LivingEntityHelper.java:33)
[18:57:32] [Minecraft main thread]  ... 6 more
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 1
    Have you tried just casting to java.util.ArrayList using the non-generic format? Generics don't really help here. So I'd omit them. Also you could call biome.getClass().getName() to determine what class type of object biome is. – AminM Sep 11 '22 at 04:36
  • Yes I've tried using the non-generic versions of both List and ArrayList as well but it still gives the error that java.util.List field net.minecraft.src.BiomeGenBase.spawnableMonsterList can't be converted to java.lang.Class – Dilosir 22 Sep 11 '22 at 05:35
  • As @AminM suggests, check what class `biome` is. – tgdavies Sep 11 '22 at 05:38
  • Thanks, that seemed to do it, I just changed the parameter type biome from object to an instance of BiomeGenBase (the class it inherits from), thank you – Dilosir 22 Sep 11 '22 at 13:59
  • Declare the `biome` parameter as `BiomeGenBase`. You may have an other error in your code - as it looks like you pass a class to the method, not an instance. – Johannes Kuhn Sep 11 '22 at 16:21
  • 1
    Does this answer your question? [Reflection generic get field value](https://stackoverflow.com/questions/13400075/reflection-generic-get-field-value) – pppery Sep 18 '22 at 03:03

0 Answers0