2013-01-02 26 views
0

我一直在研究Bukkit插件項目一段時間,終於決定正式發佈。因此,在我瘋狂的爭奪文件記錄有關我的項目的一切,我決定清理一些API的人誰願意使用它們。現在,我遇到了一個單一的問題。我在我的Java項目中遇到了一些反思

基本上,在這個API中,你必須實現一個接口,然後用一個管理每個實現的類來註冊你的實現,並且檢查/註冊另一個插件裏面的PluginMetrics變量。

這裏是我的界面,用「名」和「跟蹤器」領域是關注的領域:

public interface IAction { 

    /** 
    * Name of the action. 
    */ 
    String name = null; 
    /** 
    * Stores args passed to the action by the player. 
    */ 
    String[] args = null; 
    /** 
    * Holds the Metrics tracker object. 
    */ 
    Tracker tracker = null; 

    ... 
} 

而且,這裏是我的所有問題產生的方法(和init()方法):

public static void registerAction(final Class a) { 
    try { 
     store.put((String) a.getField("name").get(a), a); 
     log.exDebug(String.format("Action %s (%s) was registered.", (String) a.getField("name").get(a), a.getCanonicalName())); 
     try { 
      Tracker metric = (Tracker) a.getField("tracker").get(a); 
      try { 
       OpenAuth.getMetrics().addCustomData(metric); 
       log.exDebug(String.format("Registered Metrics data tracker [%s] from %s.", metric.getColumnName(), a.getCanonicalName())); 
      } catch (java.lang.Exception e) { 
       log.info("Exception occurred while registering Action data tracker."); 
      } 
     } catch (java.lang.Exception e) { 
      log.info("Exception occurred while registering Action data tracker."); 
      // e.printStackTrace(); 
     } 
    } catch (java.lang.Exception e) { 
     log.info("Exception occurred while registering an Action."); 
     e.printStackTrace(); 
    } 
} 

public static void init() { 
    for (Actions a : Actions.values()) { 
     try { 
      registerAction(a.getAction()); 
     } catch (java.lang.Exception e) { 
      log.info("Exception occurred while initialising Actions enumerator."); 
      e.printStackTrace(); 
     } 
    } 
    for (Object ob : classLoader.load().getClasses()) { 
     Class c = null; 
     try { 
      c = (Class) ob; 
     } catch (java.lang.Exception e) { 
      log.info("Exception occurred while casting up external Action."); 
      e.printStackTrace(); 
     } 
     try { 
      registerAction(c); 
     } catch (java.lang.Exception e) { 
      log.info("Exception occurred while registering external Action."); 
      e.printStackTrace(); 
     } 
    } 
} 

和示例實現:

public class FreezeStick implements IAction { 

    public static final String name = "freeze"; 
    public static final Tracker tracker = new Tracker("FreezeStick"); 

    private String[] args = null; 
    private Session attached; 
    private SessionController sc; 
    private final LogHandler log = new LogHandler(); 
    private final String permissible = "openauth.action.freeze"; 
    private OAServer server; 
    private boolean used = false; 

    protected OAPlayer sender; 
    protected OAPlayer target; 

    public FreezeStick(OAServer server, Session attached) { 
     this.server = server; 
     this.sc = server.getController().getSessionController(); 
     this.attached = attached; 
     this.setSender(this.attached.getPlayer()); 
    } 

-- etc.. -- 

每次Tracker metric = (Tracker) a.getDeclaredField("tracker").get(a);發生,這是 報告爲null。我嘗試過使用a.getField()而不是a.getDeclaredField(),但同樣的問題。名稱和跟蹤變量在實現中聲明時會收到private, static, and final,並且自從我第一次寫這個變量以來,對名稱變量使用a.getField()已經正常工作。

如果有人能在正確的方向指向我,我將不勝感激:)

而且,這裏是發生異常,如果它有什麼更好的找出我的問題可以幫助:

2013-01-02 10:48:10 [INFO] [OpenAuth-debug] Action ban (me.maiome.openauth.actions.BanStick) was registered. 
2013-01-02 10:48:10 [INFO] [OpenAuth] Exception occurred while adding Action data tracker. 
2013-01-02 10:48:10 [SEVERE] java.lang.NullPointerException 
2013-01-02 10:48:10 [SEVERE] at me.maiome.openauth.actions.Actions.registerAction(Actions.java:65) 
2013-01-02 10:48:10 [SEVERE] at me.maiome.openauth.actions.Actions.init(Actions.java:104) 
2013-01-02 10:48:10 [SEVERE] at me.maiome.openauth.bukkit.OpenAuth.onEnable(OpenAuth.java:230) 
2013-01-02 10:48:10 [SEVERE] at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:217) 
2013-01-02 10:48:10 [SEVERE] at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:457) 
2013-01-02 10:48:10 [SEVERE] at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:381) 
2013-01-02 10:48:10 [SEVERE] at org.bukkit.craftbukkit.v1_4_6.CraftServer.loadPlugin(CraftServer.java:278) 
2013-01-02 10:48:10 [SEVERE] at org.bukkit.craftbukkit.v1_4_6.CraftServer.enablePlugins(CraftServer.java:260) 
2013-01-02 10:48:10 [SEVERE] at org.bukkit.craftbukkit.v1_4_6.CraftServer.<init>(CraftServer.java:214) 
2013-01-02 10:48:10 [SEVERE] at net.minecraft.server.v1_4_6.PlayerList.<init>(PlayerList.java:52) 
2013-01-02 10:48:10 [SEVERE] at net.minecraft.server.v1_4_6.DedicatedPlayerList.<init>(SourceFile:11) 
2013-01-02 10:48:10 [SEVERE] at net.minecraft.server.v1_4_6.DedicatedServer.init(DedicatedServer.java:104) 
2013-01-02 10:48:10 [SEVERE] at net.minecraft.server.v1_4_6.MinecraftServer.run(MinecraftServer.java:399) 
2013-01-02 10:48:10 [SEVERE] at net.minecraft.server.v1_4_6.ThreadServerApplication.run(SourceFile:849) 

回答

0

我找到了我的答案。原來,我試圖在Metrics實例準備好使用之前在Metrics實例上運行#addCustomData()。只需要在我的控制器中將Actions.init()移動幾行就可以了:)

1

接口不能聲明字段,是實際的代碼嗎?

您面臨的問題是getDeclaredField方法將得到一個具有該名稱的字段,但不會搜索超類。爲了回答這個問題的反思部分,我建議你創建一個幫助器方法,這個方法將持續地在Class對象(以及該對象的超類等)上調用.getSuperclass(),直到你到達聲明該字段的類。 (編輯,匹配給定的例子:爲了讓靜態字段,你應該使用field.get(null);

一個更合適的解決方案,但是,這是使界面聲明一些getter方法 - Tracker getTracker();String getName();

+0

好的,事情是,registerAction()方法能夠獲得完全正確的名稱!但每次該方法試圖讓該方法嘗試獲取跟蹤器時,它都會給出一個空值。它是否有助於澄清我是否提供了我的整個動作API? – pirogoeth

+0

Score_Under的建議很好。 – Bill

+0

如果'''getDeclaredField'''不是返回'''null'',但''get'''的那個,那麼這個字段的值可能實際上是空的。 –

0

如果您正在使用以bean結構化的類對象,那麼您應該在Spring中查看apache-commons或BeanWrapper(名稱上不能100%確定)的BeanUtils。在幕後,他們爲你處理低級反思和內省,所以你只需編寫一個簡單的方法調用來檢索一個值。

尋找registerAction,你只是嘗試投射傳入的類對象,這可能會導致一些頭痛。

我想你也許可以使用泛型來強制參數作爲一個跟蹤類對象

public static void registerAction(final Class<Tracker> a) { 

你也可以添加一些檢查,看是否有類包含的方法或字段,然後再重寫嘗試使用它們。

相關問題