今天仗著不找到solution不罷休的的決心,把jEdit的原始碼拿出來一隻隻慢慢啃,最後連JDK的原始碼都找出來翻山倒海一番,才發現只需要加幾行程式碼就能解決。
我開發的軟體是這麼樣運作:
- 使用JNLP配置Java WebStart
- 搭配jEdit的jar檔啟動編輯器
- 自製兩項jedit的plug-ins
好死不死,在
經過逐步的檢查發現,原來是 jEdit 自己定義了一個新的URL格式「jeditresource:/檔案路徑」。
一般來說,Java註冊新的URL格式,會使用如下的Property「java.protocol.handler.pkgs」定義,這幾行是jEdit.java包含的程式碼。
System.getProperties().put("java.protocol.handler.pkgs",
"org.gjt.sp.jedit.proto|" +
System.getProperty("java.protocol.handler.pkgs",""));
但不知道、不知道、不知道為什麼,在Linux下的Java VM,似乎根本不理會這些定義,根據挖掘JDK原始碼URL.java的了解後,我認為跟Security機制有關,但是嘗試一些Security Policy的設定後,還是~~無效。
只好把希望放在另一種方法,也就是 URL.setURLStreamHandlerFactory 這個method,它可以讓我們自己定義Factory Implementation,將protocol對應到處理它的Handler Implementation。
以jEdit來說,需要的程式碼摘要如下:
class JEditURLStreamHandlerFactory implements URLStreamHandlerFactory {
public URLStreamHandler createURLStreamHandler(String protocol) {
if (protocol.equals("jeditresource")) {
return new org.gjt.sp.jedit.proto.jeditresource.Handler();
}
return null;
}
}
URLStreamHandlerFactory factory = new JEditURLStreamHandlerFactory();
URL.setURLStreamHandlerFactory(factory);
雖然暫時解決啟動的問題,但遇上Java惱人的Security機制,不知道何時還會在其他地方踩到地雷!
再次體驗Java的「Write Once, Debug Everywhere」不是喊假的。