該異常是創建代理時加載接口的類加載器與創建時傳入的不一致。
在本地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 目錄下。