Accueil

Articles techniques

A propos de AzureGuru.org

Publier sur AzureGuru.org
 
   Accueil

06
Lancer une application JAVA dans Windows Azure
Comme beaucoup d’entre vous le savent déjà, il est tout à fait possible de faire tourner sous Windows Azure des programmes écrits dans d’autres langages que ceux basés sur .Net, comme JAVA, PHP ou Python par exemple.

Aujourd’hui, je propose que l’on voie rapidement comment faire tourner une application JAVA (JAR) dans Windows Azure.

Pour ce tutoriel j’ai choisi de faire tourner un serveur HTTP écrit en JAVA, appelé Apache Jackrabbit, disponible en version Standalone sur le site http://jackrabbit.apache.org/downloads.html . Le serveur en question se trouvera sur un Storage Account (ainsi que JRE), et sera dynamiquement copié en local ou tourne le Worker Role puis lancé pour écouter sur le port 4242. Je communiquerais ensuite avec lui via telnet pour vérifier son bon fonctionnement. NB. : J’aurais aussi pu inclure le serveur dans les sources de mon Worker Role en tant que ressource incorporée, mais je trouve que c’est moins propre ;-) .

Pour pouvoir faire tourner un programme JAVA, il nous faut aussi le Java Runtime Environment (JRE). Etant donné qu’il n’existe pas de version Standalone de JRE, le mieux est de l’installer, copier le répertoire d’installation, puis de le désinstaller. Téléchargez la dernière version qui se trouve ici http://java.com/fr/download/manual.jsp#win , de préférence la version 64 bits, au moment ou j’écris ce tutoriel, il s’agit du fichier jre-6u22-windows-x64.exe .

Dans un premier temps nous allons créer un projet Cloud incluant un Worker Role.



Commençons par créer la classe qui va nous permettre de copier en local le contenu de mon Storage Account (dans notre cas le fichier .jar) :

public static class StorageHelper
{
    private static string GetLocalPath(string uri, string path)
    {
        foreach (var segment in new Uri(uri).Segments.Skip(2))
            path = Path.Combine(path, segment);
        return path;
    }
    public static void CopyContainer(string destFolder, CloudBlobContainer blobContainer)
    {
        var cloudBlobs = blobContainer.ListBlobs(new BlobRequestOptions
                                          {
                                              UseFlatBlobListing = true,
                                              BlobListingDetails = BlobListingDetails.Metadata
                                          }).OfType<CloudBlob>();
        foreach (var blob in cloudBlobs)
        {
            var localpath = GetLocalPath(blob.Uri.ToString(), destFolder);
            Directory.CreateDirectory(Path.GetDirectoryName(localpath));
            blob.DownloadToFile(localpath);
        }
    }
}



Puis définissons nos clés et répertoires de stockage dans les fichiers de configuration. Le répertoire JRE (le contenu du répertoire qui se trouve généralement dans C:\Program Files (x86)\Java\jre6\) se trouvera dans le container « java » et le serveur jackrabbit-standalone-2.1.2.jar dans le container « jackrabbit ».

ServiceConfiguration.csdef :

<ConfigurationSettings>
    <Setting name="DataConnectionString"
            
value="DefaultEndpointsProtocol=http;AccountName=javainazuresa;AccountKey=clé" />
    <Setting name="DiagnosticsConnectionString"
             value="DefaultEndpointsProtocol=https;AccountName=javainazuresa;AccountKey=clé"/>
    <Setting name="JackRabbitFilesContainerName" value="jackrabbit" />
    <Setting name="JavaFilesContainerName" value="java" />
</ConfigurationSettings>


ServiceDefinition.csdef :

<LocalResources>
  <LocalStorage name="JackRabbitFiles" cleanOnRoleRecycle="true" sizeInMB="50" />
  <LocalStorage name="JavaFiles" cleanOnRoleRecycle="true" sizeInMB="150" />
</LocalResources>
<ConfigurationSettings>
  <Setting name="DataConnectionString" />
  <Setting name="DiagnosticsConnectionString" />
  <Setting name="JackRabbitFilesContainerName" />
  <Setting name="JavaFilesContainerName" />
</ConfigurationSettings>


Maintenant créons les deux fonctions qui nous permettront dans un premier temps de rapatrier en local depuis le Storage Account notre JRE et notre serveur. Ces fonctions seront appelées dans le OnStart().

private static void InstallJava()
{
    var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
    var blobfoldersClient = storageAccount.CreateCloudBlobClient();
    var javaRoot = RoleEnvironment.GetLocalResource("JavaFiles").RootPath;
    StorageHelper.CopyContainer(javaRoot,
                                blobfoldersClient.GetContainerReference(
               RoleEnvironment.GetConfigurationSettingValue("JavaFilesContainerName")));
}

private static void InstallJackRabbit()

{
   
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
   
var blobfoldersClient = storageAccount.CreateCloudBlobClient();
   
var jackRabbitRoot = RoleEnvironment.GetLocalResource("JackRabbitFiles").RootPath;
   
StorageHelper.CopyContainer(jackRabbitRoot,
                                blobfoldersClient.GetContainerReference(
               RoleEnvironment.GetConfigurationSettingValue("JackRabbitFilesContainerName")));
}


Pour finir, lançons notre serveur. Pour ce faire, nous allons déjà créer un EndPoint pour ouvrir le port 4242 sur l’extérieur dans ServiceDefinition.csdef .

<Endpoints>
  <InputEndpoint name="JackRabbitIn" protocol="tcp" port="4242" />
</Endpoints>


La suite est simple, il suffit de lancer l’exécutable java.exe avec en argument notre serveur Jackrabbit et son port d’écoute, comme ceci :

private static void StartJackRabbit()
{
    // Chemin vers java.exe (dans le répertoire bin)
    var javaPath = Path.Combine(RoleEnvironment.GetLocalResource("JavaFiles").RootPath,
                                "bin",
                                @"java.exe");
    // Chemin vers le serveur jackrabbit
    var jackRabbitPath = Path.Combine(
                                 RoleEnvironment.GetLocalResource("JackRabbitFiles").RootPath,
                                 @"jackrabbit-standalone-2.1.2.jar"
);
    // EndPoint du serveur
    var ipEndpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["JackRabbitIn"]
                                                        .IPEndpoint;
    var javaserve = new Process
    {
        // Création du processus java
        // Arguments : -jar / chemin vers le serveur / -port [port]

        StartInfo = new ProcessStartInfo(javaPath,
                                         "-jar "
+ jackRabbitPath +
                                         " -port "+ipEndpoint.Port)
        {
            WorkingDirectory = RoleEnvironment.GetLocalResource("JavaFiles").RootPath,
            UseShellExecute = false,
            RedirectStandardInput = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        }
    };
    // Récupération des sorties standards
    javaserve.ErrorDataReceived += (sender, e) => Trace.WriteLine("Error: " + e.Data);
    javaserve.OutputDataReceived += (sender, e) => Trace.WriteLine("Output: " + e.Data);
    // Lançement du processus
    javaserve.Start();
    javaserve.BeginOutputReadLine();
    javaserve.BeginErrorReadLine();
}


Avant de déployer il ne faut pas oublier de créer dans notre Storage Account  les containers java et jackrabbit et d’y copier jackrabbit-standalone-2.1.2.jar et le contenu de notre répertoire JRE:



Une fois le Worker Role déployé et lancé, vérifions que le serveur Jackrabbit est en marche en se connectant dessus via telnet :

Connexion sur le serveur, port 4242 :



Requête HTTP :



Réponse :



Comme nous avons pu le voir, quelques lignes de code C# permettent de lancer assez simplement un applicatif entièrement écrit en JAVA.

N’hésitez pas à réagir à propos de ce tutoriel, si vous avez des questions ou une technique plus simple que la mienne, je suis ouvert ;) .

Mon prochain article traitera la possibilité de faire tourner un site web écrit en PHP dans Azure, et communiquant avec une base de données MySQL, hébergée elle aussi dans Azure.

Commentaires

vendredi 4 février 2011 15:10
sympa ce post! Quasi exactement ce qu'il me faut ;)!!
petit problème cependant... Comment fait-on pour uploader un répertoire sur Azure? Pour le moment j'utilise "Azure Storage Explorer" edite par neudesic...
# Olivier AIT
vendredi 4 février 2011 16:02
Bonjour et merci pour ton post.
Perso moi j'utilise CloudBerry Explorer, je n'ai jamais testé Azure Storage Explorer. Les deux se valent sûrement.

Poster un commentaire

Only registered users may post comments.