2010-07-05 89 views
3

我有一個顯然(愚蠢)的簡單問題:將Sinatra應用程序封裝到單個JAR文件中?

使用JRuby可以部署單個文件Sinatra應用程序嗎?

我的意思是:我已經在我的末日應用程序與所有需要的寶石爆炸到一些./vendor/lib目錄,我想整個應用程序部署爲一個jar文件部署的機器上運行:

$ java jar my_app.jar 

我唯一擁有的就是Java。

這可能嗎?而且,如果是這樣,有一個簡單的方法來實現這一點?

TIA

回答

2

這實際上很容易。假設你可以用一切某些目錄下凍結的命令運行應用程序:

ruby myapp.rb 

現在你需要這個腳本放到lib目錄應用程序下,寫一個Java包裝,這將加載腳本。示例代碼做到這一點:

package livesync; 

import org.jruby.Ruby; 
import org.jruby.RubyRuntimeAdapter; 
import org.jruby.javasupport.JavaEmbedUtils; 
import java.util.ArrayList; 

public class LiveSyncRunner { 
    public static void main(String[] args) { 
     String[] jrubyArgs = new String[3 + args.length]; 
     jrubyArgs[0] = "-e"; 
     jrubyArgs[1] = "require 'livesync/livesync_wrapper'"; 
     jrubyArgs[2] = "livesync"; 
     for (int i = 0; i < args.length; ++i) { 
      jrubyArgs[i + 3] = args[i]; 
     } 
     org.jruby.Main.main(jrubyArgs); 
    } 
} 

萬一我運行上面的腳本中的lib/livesync_wrapper.rb

現在,所有你需要的是一個正確的build.xml文件(在根目錄下) 我的build.xml:

<?xml version="1.0" encoding="UTF-8"?> 

<project basedir="." default="dist" name="Juggernaut"> 
    <description>Combine Ruby and Java source with the jruby-complete jar</description> 
    <target name="dist" description="Create the deliverable jar"> 
    <taskdef name="jarjar" 
      classname="com.tonicsystems.jarjar.JarJarTask" 
      classpath="vendor/jarjar-1.0rc7.jar"/> 
    <mkdir dir="pkg"/> 
    <jarjar destfile="pkg/livesync.jar"> 
     <manifest> 
     <attribute name="Main-Class" value="livesync.LiveSyncRunner"/> 
     </manifest> 
     <fileset dir="classes"/> 
     <zipfileset dir="vendor/gems" prefix="vendor/gems"/> 
     <zipfileset src="vendor/jruby-complete-1.1.2.jar" /> 
    </jarjar> 
    </target> 
</project> 

事情你可能要改變這裏是:

  • 名Main-Class的 - 這有你的Java包裝的 多少名 (加載Ruby腳本)
  • 添加/刪除一些zipfilesets

您還需要包括文件JRuby的完整-1.1.2.jar和供應商目錄中的jarjar-1.0rc7.jar。你應該沒有任何問題地將它們放出來。

做完這些之後,您只需進入根目錄並運行ant。在此之後,你可以運行你的腳本

java -jar pkg/livesync.jar args1 agrs2 ... 

希望這有助於!

+0

這看起來非常棒,但是你可以將Ruby Gems作爲庫包裝起來,而不是可執行文件。 我的意思是我有ruby庫,所有類型的函數/方法我想從我的java服務器代碼運行 我到底該如何從Java內部調用Ruby函數,包括參數和對象 – 2012-08-29 10:51:11

+0

對不起,已經兩年了,我沒有任何與Java + JRuby的東西,所以我的知識有點生疏。無論如何,你可以在這個寶石來源找到很多這樣的例子: https://github.com/kowalski/redcloth/blob/master/ext/redcloth_scan/redcloth_inline.java.rl 不要害怕遠去,這是一個模板... – 2012-09-05 10:30:51

4

你可以嘗試使用鳴鳥爲此。從版本1.1開始,Warbler支持製作戰爭文件「可執行文件」。詳情請參閱the documentation

基本上,安裝鶯並嘗試在您的Sinatra應用程序上運行它。如果你有一個config.ru,一切都應該非常有效。

$ jruby -S gem install warbler 
$ jruby -S warble executable war 
$ java -jar my_app.war 
+0

TNX,我已經試過了......唯一的問題出現在一些與Bundler「安裝」的寶石(例如:nokogiri)。 – 2010-07-08 12:28:41

0

從jruby-complete jar文件開始;解開罐子。然後,您可以將寶石安裝到爆炸罐中。

META-INF目錄中的jruby.home是「常用」jruby安裝所在的位置。您可以使用該目錄中的gem。

接下來,在jruby.home目錄中,創建一個目錄,讓我們稱它爲app,並將它放入其中。

接下來,您需要創建一個腳本,以便在啓動應用程序的bin目錄中運行。

測試並確保一切正常。

然後將所有東西都備份,創建一個文件,如app.jar。

最後,要投放:

java -jar app.jar -S YOUR_SCRIPT 

- 或 - 渣土關於與清單,並創建一個Java類,它的功能類似的腳本。

相關問題