openfire 部署後報錯: java.lang.IllegalArgumentException: interface xx is not visible from class loader
阿新 • • 發佈:2017-12-01
exceptio color 本地 java creat 根據 ret 打印 exception
該異常是創建代理時加載接口的類加載器與創建時傳入的不一致。
在本地eclipse做openfire二次開發,本地運行沒錯,部署到服務器上後報異常:
java.lang.IllegalArgumentException: interface xx is not visible from class loader。
根據異常信息,可知是動態代理時出錯的。而在之前部署過卻沒有這異常發生。
從日誌上分析,可以找到拋異常的地方是:
Class<?> java.lang.reflect.Proxy.getProxyClass0(ClassLoader loader, Class<?>... interfaces); 由於服務器上不能斷點分析,以及無法修改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 目錄下。
openfire 部署後報錯: java.lang.IllegalArgumentException: interface xx is not visible from class loader