2010-07-05 8 views
3

J'ai une question apparemment (stupide) simple:L'application Sinatra dans un seul fichier JAR?

Avec JRuby est-il possible de déployer une seule application Sinatra de fichier?

Je veux dire: J'ai mon application Sinatra avec toutes les gemmes nécessaires a explosé dans un répertoire ./vendor/lib et je voudrais déployer l'application tout en un seul fichier jar pour exécuter sur une machine de déploiement:

$ java jar my_app.jar 

où la seule chose que j'ai est Java.

Est-ce possible? Et, si oui, il y a un moyen simple d'accomplir cela?

TIA

Répondre

2

C'est assez facile en fait. Supposons que vous pouvez exécuter votre application avec tout gelé sous un répertoire avec une commande:

ruby myapp.rb 

Maintenant, vous devez placer ce script dans le répertoire lib dans votre application et écrire une enveloppe java qui va charger le script. Exemple de code qui fait cela:

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); 
    } 
} 

En cas au-dessus du script que je lance est dans lib/livesync_wrapper.rb

Maintenant, tout ce dont vous avez besoin est un fichier build.xml approprié (placé dans le répertoire racine) mon 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> 

Les choses que vous pourriez avoir à changer ici sont:

  • nom Main-Class - cela a à nom une grande partie de votre emballage java (chargement de script Ruby)
  • Ajouter/supprimer certains zipfilesets

Vous devez également inclure des fichiers JRuby-complet-1.1.2.jar et jarjar-1.0rc7.jar dans le répertoire du fournisseur. Vous devriez les google sans aucun problème. Après cela, vous allez dans le répertoire racine et exécutez ant. Après cela, vous pouvez exécuter votre script avec

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

Espérons que cela aide!

+0

Cela ressemble vraiment super, mais pouvez-vous envelopper aussi Ruby Gems comme une bibliothèque et non exécutable. Je veux dire que j'ai bibliothèque Ruby avec toutes sortes de fonctions/méthodes que je veux courir à partir de mon code serveur java Comment exactement dois-je appeler des fonctions Ruby à partir de Java, y compris des arguments et des objets –

+0

Désolé, il fait deux ans vu que je ne l'ai pas quoi que ce soit avec java + jRuby donc ma connaissance est un peu rouillée. Quoi qu'il en soit, vous pouvez trouver beaucoup d'exemples de ce fait dans cette source de pierres précieuses: https://github.com/kowalski/redcloth/blob/master/ext/redcloth_scan/redcloth_inline.java.rl Ne pas avoir peur loin que c'est un gabarit ... –

4

Vous pouvez essayer d'utiliser Warbler pour cela. A partir de la version 1.1, Warbler supporte la création d'un fichier de guerre "exécutable". Voir the documentation pour plus de détails.

Fondamentalement, installez warbler et essayez de l'exécuter sur votre application Sinatra. Si vous avez un config.ru, tout devrait marcher.

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

TNX, j'ai déjà essayé ça ... Le seul problème apparait avec une gemme "installée" avec Bundler (ex: nokogiri). –

0

À partir d'un fichier jruby-complete jar; Décompressez le pot. Vous pouvez ensuite installer vos gemmes dans le pot explosé. Dans le répertoire META-INF se trouve jruby.home où se trouve l'installation jruby "habituelle". Vous pouvez utiliser la gemme dans ce répertoire.

Ensuite, dans le répertoire jruby.home, créez un répertoire, nous allons l'appeler l'application et placez votre application en elle.

Ensuite, vous devrez créer un script à exécuter dans le répertoire bin qui démarre votre application.

TEST et assurez-vous que tout fonctionne.

zip Puis tout sauvegarder, la création d'un fichier tel que app.jar.

Enfin, pour exécuter:

java -jar app.jar -S YOUR_SCRIPT 

-ou- Muck sur le manifeste et créer une classe java qui est fonctionnellement similaire au script.

Questions connexes