xmarsh 0.1.3 release

0

新增 ssl 服務支援。

細節參閱

xmarsh@openfoundry

extremepattern.com/XMARSH

Mylar Connector with SSL Client Certificate

0

源起

mylay 的連接器目前沒有提供 SSL Client Certificate 設定, 需要在 eclipse 上面作些設定,同時改一下 mylar 的程式。

參考

  1. Add support for HTTP Digest authentication to Trac connector
  2. Guide to Remote repository access through authenticated HTTPS
  3. 為高級 JSSE 開發人員定制 SSL

eclipse.ini

目前要改 mylar ui 會需要動比較多,所以這裡用 system property 直接穿 進去用。

改這個 ini 檔的時候,注意不要多出空白等資料,不然會讀不進去,可以 開起來後,用 Help-About-Configuration Details 看看。

-vmargs
-Xms512m
-Xmx512m
-XX:PermSize=128m
-XX:MaxPermSize=128m
-Dfile.encoding=UTF-8
-Dmylar.trustStore=trust.jks
-Dmylar.keyStore=haha.pfx
-Dmylar.trustStorePassword="trustpass" 
-Dmylar.keyStorePassword="hahapass" 

org.eclipse.mylar.tasks.core.web.WebClientUtil.SslClientAuthProtocolSocketFactory

只是改一下 SslProtocolSocketFactory.java

private String trustStore = 
  System.getProperty("mylar.trustStore");
private String trustStorePassword = 
  System.getProperty("mylar.trustStorePassword");
private String keyStore = 
  System.getProperty("mylar.keyStore");
private String keyStorePassword = 
  System.getProperty("mylar.keyStorePassword");

protected KeyManager[] getKeyManagers() {...}
protected TrustManager[] getTrustManagers(){...} 
private SSLContext getSslContext() {
    if (sslContext == null) {
    try {
        TrustManager[] tms = getTrustManagers();
        KeyManager[] kms = getKeyManagers();
        sslContext = SSLContext.getInstance("SSL");
        sslContext.init(kms, tms, null);
        } catch (Exception e) {
            MylarStatusHandler.log(e, "could not get SSL context");
        }
    }
    return sslContext;
}

org.eclipse.mylar.tasks.core.web.WebClientUtil

再改個 setupHttpClient() 中使用的的部份就可以。

Protocol acceptAllSsl = new Protocol("https", 
  new SslClientAuthProtocolSocketFactory(proxySettings),
  WebClientUtil.getPort(repositoryUrl));

觀察

  1. mylar 過不久應該會有 ui 介面可用,現在這樣可以先撐著用。

Log4j and OSGi

0

源起

日誌的使用算是部署時候的必須考量,而且往往牽涉到所有參與的 bundle, 這裡以 Apache Commons Loggings 與 Apache Log4j 來練習,基本考量是 希望設定檔不要放在 classpath 去,因為這樣不能改。

參考

  1. config.ini and org.eclipse.osgi
  2. Universal Logger Plug-ins for RCP Applications
  3. Eclipse – a tale of two VMs

Apache Commons Logging 設定

OSGi 環境下面有 LogService 可以輸出日誌,不過現有的支援軟體都不是為 OSGi 設計, 為了支援現有的軟體需求,還是採用 Apache Commons Logging 的方式。

可以在 equinox_install/configuration/config.ini 中設定 system properties 如下 ,讓 commons logging 導向使用 log4j。

org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger

不過上述設定會需要 Log4JLogger 動態載入,所以 org.apache.commons.logging 這個 bundle 中間要有下面宣告,這樣做法可以讓需要時再使用,不需要 log4j 的使用環境, 可以不用管它。

Import-Package: org.apache.log4j;resolution:=optional

不過目前包好的 bundle 似乎都沒有加入選擇性載入 log4j 的設定,所以需要自己建一個。

Apache Log4j 設定

log4j.configuration 這個值雖說可以在 equinox_install/configuration/config.ini 設定 如下。

log4j.configuration=file:/C:/equinox_install/configuration/log4j.properties

不過這樣需要絕對路徑,如果要相對載入,可以藉由第一個 bundle 的 start() 中載入 LogFactory 之前設定如下,將預設的位置放到 equinox_install/configuration/log4j.properties。

System.setProperty("log4j.configuration", 
  System.getProperty("osgi.configuration.area") + 
  "log4j.properties");
Log logger = LogFactory.getLog(getClass());

不過 log4j.appender.logfile.File 可以支援相對路徑,例如設定 log4j.appender.logfile.File = logs/haha.log 會寫入到 equinox_install/logs/haha.log 。

基本動作

每個有日誌需求的客端 bundle 必須在其 MANIFEST.MF 上有下列標示 :

  1. Import-Package: org.apache.commons.logging
  2. Requires-Bundle: org.apache.log4j
  3. Eclipse-RegisterBuddy: org.apache.log4j

觀察

  1. 每個需要日誌的 bundle 都要加上三個標示,要找看看有沒有比較簡化做法 ?

config.ini and org.eclipse.osgi

0

源起

在 eclipse PDE 測試 bundle 很方便,實際部署一堆 bundle 時候,執行的情況要如何調整。

參考

  1. Equinox QuickStart
  2. Lazy Start Bundles
  3. Equinox Launcher

部署

一開始是採用 org.eclipse.update.configurator 部署的的自動安裝方式,這個 bundle 啟動後會自動安裝 plugins 目錄下的 bundle,但是並不會啟動這些 bundle,這種部署佈局方式如下。

somedir/
  org.eclipse.osgi_3.3.0.v20061101.jar
  org.eclipse.update.configurator_3.2.0.v20092006-1400.jar
  org.eclipse.equinox.common_3.3.0.v20061023.jar
  plugins/  
    B1.jar
    B2.jar
  configuration/
    config.ini

config.ini 的內容如下,不管後來安裝 B3,B4,B5,X2 等新功能,都不需要 改 config.ini 的內容。

osgi.bundles=org.eclipse.equinox.common@2:start, 
  org.eclipse.update.configurator@3:start
eclipse.ignoreApp=true

下面是 eclipse 3.2 sdk 的 config.ini,即使用到數十個 bundle, 也是只要寫三個 bundle 啟動即可。

osgi.bundles=org.eclipse.equinox.common@2:start, 
  org.eclipse.update.configurator@3:start,
  org.eclipse.core.runtime@start

加 -console 輸出下面內容。

osgi> ss

Framework is launched.

id      State       Bundle
0       ACTIVE      system.bundle_3.3.0.v20061101
1       ACTIVE      org.eclipse.equinox.common_3.3.0.v20061023
2       ACTIVE      org.eclipse.update.configurator_3.2.0.v20092006-1400
3       RESOLVED    B1_1.0.0
4       RESOLVED    B2_1.1.0

可以發現 B1/B2 不會自行啟動。

config.ini 注意事項

  1. 啟動的檔名很重要,xx@2:start 必須有個 xx-1.2.3.jar 出現,注意如果是 xx_1.2.3.jar 的寫法並不支援。
  2. 非 eclipse 要加個 eclipse.ignoreApp=true 來啟動。

LazyStart

因為 org.eclipse.update.configurator 只安裝,並不會自動啟動, 可以使用 Eclipse-LazyStart Header 的做法,這樣會讓每個 bundle 被 存取時自動啟動。

Equinox Framework version 3.2
Eclipse-LazyStart: true; exceptions="org.eclipse.foo1" 

或是 Equinox Framework version 3.3
Bundle-ActivationPolicy: lazy

但是前提是這些 bundle 有設計這些 header,像是之前做好的一些 bundle 並 不一定有支援這類啟動,這時候需要類似 eclipse sdk 用的 org.eclipse.core.runtime 方式,加一個 runtime 的 bundle 來手動啟動沒有加上 LazyStart 的 bundle。

haha.core.runtime

改由一個新的 haha.core.runtime 統管執行時期的一些調整, 讓讀取的 bundle 可以自動啟動執行。

public class Activator implements BundleActivator {
  public void start(BundleContext context) throws Exception {
    Bundle[] bundles = context.getBundles();
    for(Bundle bundle : bundles){
      if(bundle.getState() == Bundle.RESOLVED){                
        bundle.start();
      }
    }
}

不過上面是一網打盡的做法,會讓加上 Lazy Start 的也執行啟動, 等於枉費 Lazy Start 的設計用意。

config.ini 內容 :

osgi.bundles=org.eclipse.equinox.common@2:start, 
  org.eclipse.update.configurator@3:start, 
  haha.core.runtime@start
eclipse.ignoreApp=true

用 Equinox Launcher

下載 launchers-win32.win32.x86.3.3M3.zip 來測試,解開後有下面內容。

root/
  eclipse.exe
  epl-v10.html
  notice.html
  startup.jar
  configuration/
    config.ini

輸出時只要將需要的 jar 放到 plugins 目錄中就可以跑了, 不過這類輸出需要特定平台。

觀察

  1. 使用 org.eclipse.update.configurator 可以支援讓之前沒寫進 config.ini, 後來加入的 bundle 可以得到啟動。
  2. Eclipse-LazyStart 可能以後會因為變成標準而改用 Bundle-ActivationPolicy。

osgi.configuration.area and FileSystemResource

0

源起

程式都需要一些設定檔或是資料庫檔,然而這些檔案的安裝位置並不一定是絕對的, 所以執行時需要取得當時環境的資訊來調整,往往是根據安裝時放置的相對位置來決定, 像要練習如何取得 OSGi 執行時期的檔案位置,以及處理 Spring-OSGi 不支援 Resource 注入的替代方案。

參考

  1. Eclipse Runtime Options
  2. Can’t Find Resources outside of the bundle

Eclipse runtime options

使用 Equinox osgi 執行時會提供一些環境參數 ,程式中可以用 System.getProperty() 取得執行時期一些 檔案路徑來使用,下面為一個 bundle 在 Eclipse PDE 平台 的測試的範例。

  1. osgi.configuration.area= file:/C:/EclipseInstall/eclipse-3.2/configuration/
  2. osgi.install.area= file:/C:/EclipseInstall/eclipse-3.2/
  3. osgi.instance.area= file:/C:/myproject/Haha2007/
  4. osgi.instance.area.default= file:/C:/Documents and Settings/Foo/workspace/

File Resource

之前使用 Spring Resource 注入的 bean,放到 OSGi 環境會出現檔案問題,根據參考連結的解法,需要自行產出 FileSystemResource 來使用。

<bean 
class="org.sf.beans.factory.config.PropertyPlaceholderConfigurer" />
<bean id="haha" class="xx.yy.zz">
<property name="fooFile">
   <bean class="org.sf.core.io.FileSystemResource">
      <constructor-arg>${osgi.configuration.area}</constructor-arg>
   </bean>
</property>
</bean> 

不過 FileSystemResource 不吃 file: 開頭的字串,乾脆轉成下面做法。

<bean 
  class="org.sf.beans.factory.config.PropertyPlaceholderConfigurer" />
<bean id="haha" class="xx.yy.zz" 
  p:osgiConfArea="${osgi.configuration.area}"/>

觀察

  1. osgi.configuration.area 不清楚是否 OSGi 規格有提到,如果沒有,其他執行平台不一定會支援。

Older posts: 1 2 3 ... 8