該異常是建立代理時載入介面的類載入器與建立時傳入的不一致。
在本地eclipse做openfire二次開發,本地執行沒錯,部署到伺服器上後報異常:
java.lang.IllegalArgumentException: interface xx is not visible from class loader。
根據異常資訊,可知是動態代理時出錯的。而在之前部署過卻沒有這異常發生。
從日誌上分析,可以找到拋異常的地方是:
由於伺服器上不能斷點分析,以及無法修改jdk新增日誌,透過複製關鍵程式碼到自己程式碼開始丟擲異常處列印日誌,發現:
Class<?> interfaceClass = null; try { interfaceClass = Class.forName(interfaceName, false, loader); } catch (ClassNotFoundException e) { } if (interfaceClass != interfaces[i]) { throw new IllegalArgumentException( interfaces[i] + " is not visible from class loader"); }
interfaceClass 為null值。
然後對比之前的開發程式碼:
之前: public RPCGameAction gameAction = (RPCGameAction) Container .createRemoteService(RPCGameAction.class, "gamecenter"); 現在: public RPCGameAction getGameAction(String prefix) { return (RPCGameAction) Container .createRemoteService(RPCGameAction.class, prefix); }
而建立代理的程式碼中的獲取類載入器的程式碼為:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
前者會在初始化的時候已經建立好,而後者會根據執行時的ClassLoader而建立,而openfire載入外掛的類載入器跟執行的不一致,從而導致建立失敗。
解決的方法可以是:RPCGameAction 這個代理隨外掛啟動而建立到記憶體中;
把介面所處的jar包放到../openfire/lib 目錄下。