前提・実現したいこと
MinecraftというゲームのMODを作っているのですが、そのMODから更に外部のJarファイルを読み込むというものを作っています。
プログラムが実行されると、外部のJarを読み込み、さらにその中のプログラムをリフレクションを使用し、実行させるというものです。
arという変数が見つからないという問題が起きています。
関係は次のようになっています。
Minecraft
リフレクションを使用して外部JarのMODを実行
私の作っているMODの関数が呼ばれる
更にリフレクションを使用して外部のJarを実行(invoke)
そこでクラスは見つかるが変数が見つからないというエラーが出る
invokeしたプログラムでは変数を書き換えることはありません。
発生している問題・エラーメッセージ
arという変数が見つからないエラーが出てしまいます。
java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at versionsmod.versionsmod.init(versionsmod.java:57) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:532) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) at com.google.common.eventbus.EventBus.post(EventBus.java:275) at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:212) at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:190) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) at com.google.common.eventbus.EventBus.post(EventBus.java:275) at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:119) at cpw.mods.fml.common.Loader.initializeMods(Loader.java:737) at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:311) at net.minecraft.client.Minecraft.startGame(Minecraft.java:597) at net.minecraft.client.Minecraft.run(Minecraft.java:942) at net.minecraft.client.main.Main.main(Main.java:164) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) at GradleStart.main(Unknown Source) Caused by: java.lang.NoSuchFieldError: ar at test.test.init(test.java:21) ... 44 more
test.javaというのは外部Jarの.classのファイルのことです。
該当のソースコード
versionsmod.java
Java
1/*38行目*/@EventHandler 2public void init(FMLInitializationEvent e) { 3 File modDir = new File(mod_dir); 4 System.out.println(Block.class); 5 try { 6 for(String className : loadedClasses) { 7 if (className.toLowerCase().substring(className.toLowerCase().lastIndexOf(".")).equals(".class")) { 8 System.out.println("load "+className.replace("/", ".").replace(".class", "")); 9 Class clas = getClass().getClassLoader().loadClass(className.replace("/", ".").replace(".class", "")); 10 if(clas.getAnnotation(Mod.class) != null) { 11 Mod m = (Mod) clas.getAnnotation(Mod.class); 12 Object o = clas.newInstance(); 13 mods.put(m, o); 14 for(Method meth : clas.getDeclaredMethods()) { 15 Class[] classes = meth.getParameterTypes(); 16 if(classes.length==1&&classes[0].getName().equals(FMLInitializationEvent.class.getName())) { 17 try { 18 meth.setAccessible(true); 19 FMLInitializationEvent event = new FMLInitializationEvent(); 20 meth.invoke(o, event); 21 }catch(InvocationTargetException e11) { 22 e11.printStackTrace(); 23 } 24 } 25 } 26 } 27 } 28 } 29 } catch (Exception e1) { 30 e1.printStackTrace(); 31 } 32}
test.java(外部Jarの中に入っているtest.class)
Java
1/*19行目*/@EventHandler 2public void init(FMLInitializationEvent e) { 3 System.out.println(Item.ar); 4}
試したこと
外部Jarの中に以下のソースを書き、実行しました。
Java
1for(Field field : Item.class.getFields()) { 2 System.out.println(field.getName()); 3}
するとarというフィールドが存在するというのがわかりました。
しかしinvokeでは見つからないというのがよくわかりません。
補足情報
Minecraft Forge 1.7.10-10.13.4.1558
Eclipse 4.4
Windows 10 64bit