首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

使用 Java Web Start 部署 JRuby 應用程式

     編輯:Java 相關知識

前言

進入 Ruby 與 Java 結合的世界,通常只需一行指令:include Java。這讓你能像操作普通 Ruby 物件一樣實例化 Java 類別、呼叫方法、甚至繼承它們。但其中有微妙差異,本文將展示如何管理這些差異,以最快速度設計新應用並部署給客戶。

本文基於一個簡單應用:使用 JRuby 與 Swing 實作的 ObjectSpace 瀏覽器。Ruby 的 ObjectSpace 特性可存取系統中所有物件,例如列印所有使用中的字串:

ObjectSpace.each_object(String) do |string|
  puts string
end

在我的 irb 工作階段中執行約產生 28,000 個字串。透過 Swing 與 JRuby,我們可在圖形介面顯示不同類別、其實例與可用方法,甚至點擊右側面板呼叫無參方法:

JRuby ObjectSpace 瀏覽器截圖

JRuby ObjectSpace 瀏覽器

註:JRuby 的 ObjectSpace 支援預設停用,因其在運行時產生的效能問題。

Java 整合

將 Java 整合至腳本後,可繼承現有 Java 類別。只需指定 Java 類別完整限定名。範例應用中主視窗繼承 JFrame,並匯入 javax.swing 與 java.awt 套件,無需每次使用完整類別名:

class MainWindow < javax.swing.JFrame
  include_package 'javax.swing'
  include_package 'java.awt'
  ...

替代方案:使用 include_class 匯入指定類別,避免污染命名空間。

呼叫父類別建構子如同普通 Ruby 程式碼,在 initialize 方法第一行呼叫 super("JRuby Object Browser") 設定視窗標題。

因匯入整個 javax.swing 套件,實例化 Java 類別變得直接:

list_panel = JPanel.new
list_panel.layout = GridLayout.new(0, 3)

仔細觀察第二行,似乎直接存取 JPanel 的 layout 屬性。實則 JRuby 為 Java 物件增加便利方法,等同於:

list_panel.setLayout(GridLayout.new(0, 3))

不再使用 getters/setters,彷彿直接存取屬性。JRuby 還為 Java 物件增加更多「語法糖」:任何方法呼叫可使用 snake_case 而非 camel case。呼叫 setLayout 的第三種方式:

list_panel.set_layout(GridLayout.new(0, 3))

呼叫 setter 方法時需小心,Ruby 可能誤以為你要建立區域變數,必須以 self 為接收者明確呼叫:

self.default_close_operation = WindowConstants::EXIT_ON_CLOSE

Java 與 Ruby 另一差異在常數存取,如 EXIT_ON_CLOSE。將 Java 程式碼轉為 Ruby 時,將所有 . 存取符替換為 ::。

對於監聽器,Java 需在匿名類別中實作介面:

button.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) { ... }
});

JRuby 僅需兩行:

button.add_action_listener do |event|
  ...
end

(若不使用 event 變數甚至可忽略它)

這些是使用 JRuby 開發 Swing 的基礎。雖然 JRuby 讓 Swing GUI 開發更方便,複雜佈局仍需手寫大量程式碼。若希望更簡單建立 Swing UI,請參考「使用 JRuby GUI APIs 的三種方式」。

部署 JRuby 應用變得更簡單

Ruby 應用與程式庫通常透過 RubyGems 分發,但需安裝 Ruby 與 RubyGems,對一般用戶不切實際。傳統 MRI/C-Ruby 程式已透過 RubyScript2Exe 解決(將腳本與 Ruby 解釋器綁定成跨平台套件)。JRuby 用戶擁有更強大工具:Java Web Start。

使用 Java Web Start

Java Web Start 內建於 Java 執行環境,大多數系統均可使用。部署應用僅需一個包含所有檔案與 JNLP(Java Network Launching Protocol)描述檔的 JAR 包。以 ObjectSpace 瀏覽器為例,示範建立可透過 Web Start 部署的 Ruby 應用。

建立應用 JAR 包

JRuby 提供兩種程式庫:jruby.jar(最小)與 jruby-complete.jar(捆綁完整 Ruby 標準程式庫)。若不使用標準程式庫,可用較小的 jruby.jar 減少約 1MB 下載量。

讓腳本運行最簡單方式:將 .rb 檔案加入 jruby.jar:

jar uf jruby.jar rob.rb

透過 java 啟動應用驗證:

java -Djruby.objectspace.enabled=true -jar jruby.jar -r rob

-r 選項自動尋找所需檔案並執行腳本。此應用需要 ObjectSpace,透過傳遞 jruby.objectspace.enabled=true 屬性啟用。

提前編譯(AOT)

JRuby 1.1 激動人心的新特性:支援提前編譯。JRuby 中有 2048 個方法採用即時編譯,AOT 能減輕此限制。JRuby 編譯器 jrubyc 仍在開發中,建議使用最新 JRuby 版本。編譯 Ruby 檔案為 class 檔案:

jrubyc rob.rb

建立包含 rob.class 的 ruby 目錄。不再需將 ruby 目錄打包進 jruby.jar,只需建立單獨 JAR 包含應用程式:

jar -cfe rob.jar ruby/rob.class ruby

建立名為 rob.jar 的小型 JAR 檔案,Manifest 指定 ruby/rob.class 為主類別,簡化呼叫:

java -Djruby.objectspace.enabled=true -cp rob.jar:jruby.jar ruby.rob

Web Start 部署

編寫 JNLP 檔案前,需對 JAR 進行簽名。因 JRuby 使用反射需更多權限,詳見 JRuby Wiki。最簡單方法:使用 JDK 自帶 keytool 建立測試憑證:

keytool -genkey -keystore myKeystore -alias myself
keytool -selfcert -alias myself -keystore myKeystore

之後每次修改 JAR 必須更新簽名,否則運行時會得到 SecurityException:

jarsigner -keystore myKeystore jruby.jar myself
jarsigner -keystore myKeystore rob.jar myself

JNLP 檔案最小配置(部分欄位為規範要求:title、vendor、j2se 標籤、security 區段):

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="https://example.com/app" href="rob.jnlp">
  <information>
    <title>JRuby Object Browser</title>
    <vendor>Mirko Stocker</vendor>
  </information>
  <security>
    <all-permissions/>
  </security>
  <resources>
    <j2se version="1.5+"/>
    <jar href="jruby.jar"/>
    <jar href="rob.jar"/>
    <property name="jruby.objectspace.enabled" value="true"/>
  </resources>
  <application-desc main-class="ruby.rob"/>
</jnlp>

若忽略 AOT 或僅使用單一 JAR 方式,需修改 JNLP 包含 -r rob 參數。最後將 JAR 與 JNLP 上傳至指定位置,即可在瀏覽器或使用 javaws 工具開啟連結。

問題排解

瀏覽器需以 application/x-java-jnlp-file MIME 類型發布 JNLP 檔案。若瀏覽器僅顯示 JNLP 內容且 javaws 未自動載入,需修改 Web 伺服器配置。例如 Apache 需在 mime.types 加入:

application/x-java-jnlp-file jnlp
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved