vendredi 13 mai 2011

Installer Oracle Weblogic Server 11gR1 sur Ubuntu 10.04 x86

Voici quelques détails sur l'installation du serveur d'application Oracle Weblogic 11gR1 (10.3.5). J'ai choisit d'installer ce serveur d'application ainsi que la machine virtuelle Java JRockit supportée par ce serveur.

Installation



  1. Télécharger la distribution de la JRockit (jrockit-jdk1.6.0_24-R28.1.3-4.0.1-linux-ia32.bin) à cette adresse,

  2. Ajouter les droits d'exécution au fichier (chmod) avant de l'exécuter et suivre l'assistant d'installation,

  3. J'ai choisit de déplacer le dossier contenant la JRockit dans le dossier /usr/lib/jvm/, à côté des autres machines virtuelles Java,

  4. Télécharger le ficher wls1035_dev.zip (~300 Mo) à cette adresse

  5. Dé-zipper le contenu de l'archive dans le répertoire de votre choix (j'ai choisit /opt/oracle/wls-10.3.5) que nous noterons <MW_HOME>

  6. Modifier le script configure.sh situé dans le dossier MW_HOME pour le faire utiliser /bin/bash en lieu et place de /bin/sh

  7. Lire attentivement et suivre les instructions situées dans le script README.txt fourni avec le serveur,

  8. J'ai choisit de créer le domaine /var/local/wlsdomains/localdomain en utilisant l'interface graphique via le script $MW_HOME/wlserver/common/bin/config.sh


Un peu de monitoring


Voilà, Weblogic 11gR1 est maintenant prêt à servir, JRockit est fournit avec JRockit Mission Control, une console d'administration de la machine virtuelle fortement utile pour inspecter en vol le fonctionnement des applications (Mémoire, CPU, Thread).
On pourra faire tourner le serveur avec un JVM classique et utiliser Visual VM présent depuis la version 1.6.0_07 dans $JAVA_HOME/bin/jvisualvm, ou alors utiliser JConsole présent depuis la JDK 1.5 dans $JAVA_HOME/bin/jconsole
Enjoy!

mardi 10 mai 2011

REST avec Jersey!

Les architectures REST sont une nouvelle forme d'architecture exprimant un certain retour aux sources. En effet, ce type d'architecture tire sa puissance des standards éprouvés du Web, en particulier du protocole HTTP.

Rappel HTTP


HTTP est un protocole orienté ressource, c'est-à-dire qu'il est dédié à la manipulation de ressources à travers un réseau et constitue un fondement de l'Internet et du World Wide Web. Il repose sur TCP et se traduit sous 2 formes :

La requête

Connexion effectuée depuis un client vers un serveur, elle identifie une ressource via son URL et donne un ordre à effectuer au serveur. Exemple :

GET http://www.google.com/

Les différents ordres sont :

  • (C) POST : pour créer une ressource,

  • (R) GET : pour lire une ressource,

  • (U) PUT : pour modifier une ressource,

  • (D) DELETE : pour supprimer une ressource,

  • ..., et bien d'autres encore, ...


Le format que nous utilisons tous (y compris en consultant ce billet) avec notre navigateur est codifié de la manière suivante : text/html. D'autre format sont également codifiés par la RFC 2046, on y retrouve notamment application/xml pour le format XML, application/json pour un flux JSON, ... Exemple :

Accept: application/xml, application/json, text/plain


La réponse

Connexion effectuée par le serveur vers le client ayant effectuée une requête afin de retourner le resultat de celle-ci. Elle est caractérisée par son code de retour, et eventuellement un contenu dont le format est précisé. Exemple :

HTTP/1.1 200 OK
<html>
...
</html>

Les codes de retour varient selon le résultat de l'exécution de la requête :

  • 200 : retour normal car tout va bien,

  • 201 : retour indiquant que la ressource a bien été créée,

  • 404 : la ressource n'a pu être trouvée

  • ..., et bien plus encore, ...



De la même manière qu'un client indique les représentations qu'il est en mesure de comprendre, le serveur indique dans l'entête de la réponse la représentation qu'il a choisit. Exemple :

Content-Type: text/html


Un premier pas en JEE


Maintenant que nous avons révisé les bases, allons plus loin avec un exemple d'implémentation en Java. Commençons par jetter un oeil sur la classe HttpServlet: avez vous remarqué ces méthodes, elles ne vous rappellent rien ?

Il s'agit des méthodes qu'il convient d'implémenter pour écrire une servlet orienté REST. Les codes de retour sont quant à eux disponibles sous forme de constantes dans la classe HttpServletResponse, c'est bien fait non ?

On passe la 6ième avec Jersey


L'écriture d'un servlet faisant du REST est une belle aventure à vivre mais on se heurte à une difficulté majeure : celle de savoir facilement interpréter une URL. C'est-à-dire comment savoir que

http://people.host.ext/user/guillaume.wallet/messages/20110101

est une URL listant les messages datés du premier janvier de l'année deux mille onze de l'utilisateur enregistré sous le nom 'guillaume.wallet', galère non?
JAX-RS est une spéficiation Java EE, incluse depuis la verion 6, ayant pour objet la standardisation de cette démarche REST au sein d'une application Java. L'implémentation de référence est fournit par le projet Jersey. Un tutorial complet est disponible sur le site.

Pom Pom Pom pommmm


Voici le pom qui m'a servi pour cette démarche:

<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sample.jersy</groupId>
<artifactId>jersey-sample</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<inceptionYear>2011</inceptionYear>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<classpathContainers>
<classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6</classpathContainer>
</classpathContainers>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<wtpversion>2.0</wtpversion>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>${tomcat.version}</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<tomcat.version>7.0.12</tomcat.version>
</properties>
<repositories>
<repository>
<id>maven2-repository.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
<layout>default</layout>
</repository>
</repositories>
</project>

Bonjour toi!


Notre première resource:

package org.sample.jersey.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

/**
* Une ressource polie.
*/
@Path( "/hello/{world}" )
public class HelloWorldResource
{
@GET
@Produces("text/plain")
public String greet(@PathParam("world") String world)
{
return "Hello " + world;
}
}

Et un peu de magie : pour tester notre application, il faut ... une application. Nous allons créer la classe suivante qui suffira à lancer notre premier test:

package org.sample.jersey.rest;

import javax.ws.rs.ApplicationPath;

import com.sun.jersey.api.core.PackagesResourceConfig;

/**
* La racine de l'application REST.
*/
@ApplicationPath( "/resources" )
public class SampleRESTApplication
extends PackagesResourceConfig
{
/**
* On explique à JERSEY que les Resources sont dans le paquet org.sample.jersey.rest.
*/
public SampleRESTApplication()
{
super( "org.sample.jersey.rest" );
}
}

Pour tester, une fois déployée dans le serveur de votre choix (tant qu'il s'agit de Tomcat dans sa version 7), rendez à l'URL suivante :

http://localhost:8080/<nom>/resources/hello/World

où <nom> remplace le nom de votre WebApp. Maintenant, remplacer "World" par ce qui vous chante et constater la magie: si peu de ligne pour un si bel effet.

«Comment tu le veux ta ressource ?»


L'exemple ci-dessous illustre la négociation de contenu.

package org.sample.jersey.rest;

import java.util.HashMap;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import org.json.simple.JSONObject;

/**
* Gestion des gens.
*/
@Path( "/users/{username}" )
public class PeopleResource
{
@GET
@Produces( "application/json" )
public String showUserAsJSON( @PathParam( "username" ) String username )
{
User user = findUserByUsername( username );
return user.toJSON();
}

@GET
@Produces( "text/plain" )
public String showUserAsTextPlain( @PathParam("username") String username )
{
User user = findUserByUsername( username );
return user.toString();
}

public PeopleResource()
{
users.put( "guillaume.wallet", new User( "guillaume.wallet", "Guillaume", "Wallet" ) );
users.put( "linus.torvalds", new User( "linus.torvalds", "Linus", "Torvalds" ) );
}

private User findUserByUsername( String username )
{
User user = users.get( username );
return user;
}

/* Une vraie BDD. */
private HashMap users = new HashMap();

/**
* Euh, ... un utilisateur quoi!
*/
private static class User
{
private String username;

private String firstname;

private String lastname;

public User( String username, String firstname, String lastname )
{
super();
this.username = username;
this.firstname = firstname;
this.lastname = lastname;
}

@SuppressWarnings( "unchecked" )
public String toJSON()
{
JSONObject me = new JSONObject();
me.put( "username", username );
me.put( "firstname", firstname );
me.put( "lastname", lastname );
return me.toJSONString();
}

@Override
public String toString()
{
return String.format( "%1s %2s", firstname, lastname );
}
}
}

Selon que vous fassiez :

$> wget --header "Accept: application/json" http://localhost:8080/<nom>/resources/users/guillaume.wallet

ou

$> wget --header "Accept: text/plain" http://localhost:8080/<nom>/resources/users/guillaume.wallet

Le rendu de la ressource change.

Conclusion


Cet article ne constitue qu'un petit pas, c'est maintenant à vous de faire le REST.

mercredi 27 avril 2011

Un tuto pour apprendre Ruby

Ruby est un langage interprété orienté objet et un environnement d'exécution permettant l'exécution des programmes écrit dans ce langage.

Ce tutorial permet d'en savoir plus sur le langage et la façon de programmer.

samedi 23 avril 2011

Installer Ruby 1.9.2 et Rails 3 sur Ubuntu 10.04

Dans le cadre d'une démarche de découverte de l'environnement Ruby et Ruby on Rails, j'ai été confronté au problème d'installation. En effet, sur la version 10.04 de Ubuntu, difficile d'installer la dernière version de cet environnement. Voici la recette qui a marché pour moi.

Installer Ruby 1.9.2


La version de l'environnement Ruby disponible dans les dépôts n'est pas assez récente pour les étapes à venir, donc il faut désinstaller tout ce que avoir été installé auparavant pour repartir sur une base saine.

Installation de RVM


Ruby enVironnement Manager et un script permettant d'installer et gérer plusieurs version de l'environnement Ruby. Son installation se fait en lançant la commande suivante:

$> sudo bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

Installation de Ruby 1.9.3


En utilisant RVM, on peut installer Ruby via la commande suivante:

$> sudo rvm install ruby-1.9.2

Finalisation de l'installation


Il faut maintenant ajouter l'environnement RVM via le fichier .bashrc
Remplacer :

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Par :

# If not running interactively, don't do anything
if [[ -n "$PS1" ]] ; then
[[ -s "/usr/local/rvm/scripts/rvm" ]] && source "/usr/local/rvm/scripts/rvm" # This loads RVM into a shell session.
fi

Positionner la version courante de Ruby


Il faut maintenant indiquer la version courante de Ruby à employer via la commande suivante :

$> sudo rvm --default ruby-1.9.2

Installer Rails 3


Ruby est accompagner d'un utilitaire gem. Ce dernier est un gestionnaire de paquet propre à Ruby. Ainsi, un logiciel est empaqueter dans une archive (un gem) puis mise à disposition et peut être installer via l'utilitaire du même nom. Nous allons installer Rails via cette commande:

$> sudo gem install rails

J'utiliserai une base de données MySQL par la suite, j'installe donc les drivers adéquats:

$> sudo apt-get install libmysqlclient16-dev
$> sudo gem install mysql
$> sudo gem install mysql2

Tester l'installation


Rails permet de créer un projet via la commande suivante:

$> rails new /path/to/project -d mysql

Pour lancer le serveur et tester l'application:

$> rails server

Il ne reste plus qu'à naviguer vers la page http://localhost:3000/

Conclusion


L'installation, bien que plus compliquée qu'un simple «apt-get install», reste assez bien outillée. D'autres ticket viendrons tracer mes premiers pas sur ce nouveau continent.

jeudi 21 avril 2011

JConsole & Weblogic

Un article qui m'a été fort utile pour me connecter sur des instances weblogic afin d'en visualiser les entrailles à distance.
Tout est là.

vendredi 15 avril 2011

L'effaceur

Comment tuer certains processus lancés par un utilisateur ?

$> ps -aef | grep ^<USERID> | grep <PROCNAME> | awk '{ print "kill -9 " $2 }' | sh

Où <USERID> représente l'identifiant de l'utilisateur ayant lancé ses processus, et <PROCNAME> représente le nom du processus lancé par <USERID>.

Supprimez le dernier tube pour voir les commande que vous auriez lancées «manuellement» pour faire la même chose.

vendredi 1 avril 2011

«Git, dessine moi un mouton»

Il y a quelques mois je découvrai Git, un gestionnaire de sources distribué dont la réputation croît en ce moment. Ayant déjà vécu la montée en puissance de Subversion au détriment de CVS, je voulais me rendre compte des qualités/défauts du nouveau challenger.

Une nouvelle philosophie


Git fait partie de la famille des contrôleurs de sources distribués. Cela se traduit principalement par le fait que chaque membre d'une équipe collaborant à un même projet est en possession d'un dépôt contenant l'ensemble de l'historique du projet. Les publications se font ainsi en local, ne nécessitant alors aucune connectivité réseau. Seul les échanges entre dépôts se font via le réseau.
Une première question vient alors à l'esprit : Si tout le monde est un dépôt, d'où provient la version de l'application à livrer ? Plusieurs organisation sont possibles à ce sujet:

  • Une organisation par cercle de confiance, comme par exemple pour le développement du noyau Linux, où un membre de l'équipe représente le dépôt de référence que tout le monde utilise pour compiler sa version du noyau, alimenté par les dépôts de plusieurs lieutenant possédant chacun un dépôt alimenté par des dépôts considérés par ses derniers comme étant de confiance.

  • L'outil est suffisament souple pour reproduire les mécanismes des dépôts centralisés. Un dépôt sur un serveur sert de référence, utilisé par exemple par un automate de compilation permettant d'assurer une intégration continue des sources du projet, les développeurs de l'équipe déposent alors des lots de publication sur ce dépôts lors de chaque instruction git push

  • et bien d'autres ...


Une autre question suvient : Comment se joindre à un projet ? Il suffit tout simplement de cloner un dépôt avec la commande git clone /jango/fet.git et vous voilà avec un clone tout neuf, puis de commencer les développement. C'est un peu comme si chaque développeur avait forker le projet afin de produire une version. L'ensemble des développements publiés dans un dépôt représente alors un patch à appliquer aux autres dépôts pour contribuer au développement.

Une migration en douceur


Lors de la migration de CVS vers Svn, un utilitaire fournit (cvs2svn) permettait de migrer un dépôt CVS en dépôt Subversion tout en conservant l'historique. Une action one shot qui implique de synchroniser l'ensemble des membres de l'équipe utilisant le dit dépôt vers le nouvel outil.
Permier avantage de Git sur Svn : git-svn. Cet utilitaire fait la même chose que le précédent, c'est-à-dire de constituer un dépôt Git à partir d'un dépôt Subverion tout en conservant l'historique via la commande git svn clone. Mais il va plus loin en conservant une connectivité avec le dépôt Subversion lui servant d'origine. Ainsi le dépôt git et maintenu à jour en continu avec la commande git svn rebase.
Cela va encore plus loin en permettant de publier les commit effectués dans le dépôt Git vers le dépôt Subverion via la commande git svn dcommit. De cette manière, un développeur peut se mettre à utiliser Git tout en continuant de collaborer à un projet dont le référentiel de source est Subversion (ce que je fit pendant plusieurs mois).

Un bénéfice au quotidien


«Git est un nouvel outil!
- d'accord
-Il est plus fashion!
- OK, mais encors?»

«Wiiiilsooooon !!!!»


On peut aussi tout simplement utilser Git en mode seul au monde pour historiser tout ce qui se trouve sur un ordinateur. La création d'un dépôt se fait avec la commande git init, puis ont ajoute les fichiers à historiser via la commande git add monprecieux.fic puis on plublie les modification via la commande git commit. Pas besoin d'un serveur où d'un dépôt à créer et/ou administrer. C'est simple et efficace et l'on peut s'en servir pour maintenir l'historique des fichiers de configuration sur un serveur (<troll>bein oui un serveur Linux/UNIX, comment on ferait pour historiser les clics droits sous Windows®</troll>) et tout projet sandbox commencé mais jamais terminé. Je m'en sert également pour réaliser des kit de démarrage afin de savoir toutes les étapes que j'ai franchies et ainsi produire une documentation exhaustives.

«Release Early, Release Often»


Ce principe de livraison fréquente peut être appliquer au niveau du développeur qui va pouvoir publier fréquement ces modifications induisant ainsi une meilleur qualité de ces publications (fini le fichiers qui manquent, les modifications oubliées dans un coin ne sachant pas si elles concernaient la tâhes en cours, ...). Chaque modification faisant progresser le code d'un état stable à un autre (bien qu'intermédiaire) doit faire peut faire l'objet d'un commit ce qui n'est pas envisageable sur un projet centralisé.

Un build incassable


Cette capacité à pouvoir publier sans retenue permet la mise en oeuvre du build incassable. Dans la mesure où seul le dépôt local est touché par ces modifications une sécurité m'est offerte en clonant mon propre dépôt dans un endroit de mon ordinateur et en construisant mon projet à partir de ce clone afin de constater la fiabilité des mes développements avant le partage de mes travaux.

«cou roucoucou roucoucou stach stach»


Il y a des moments où le travail suit son cours, le soleil est radieux, la journée a bien commencé, quand tout à coup le ciel s'obscurci, un bug en prod doit être fixé de toute urgence sinon c'est la fin du monde. Avec SVN il me fallait alors créer une nouvelle copie de travail (ce qui peut être long sur de très gros projet) puis la supprimer une fois l'urgence traitée. Où alors de créer un patch, annuler toutes mes modifications en cours puis appliquer le patch après la tempête.
La commande git stash permet ainsi de mettre de côté (to stash = planquer) les modifications en cours pour repartir d'une version clean de la copie de travail puis de reprendre les travaux au moyen de la commande git stash pop, tout ceci avec une efficacité sans précédent pour moi.

Conclusion


En conclusion, je n'ai pas listé beaucoup de défauts (aucun pour être précis) mais je noterai tout de même l'effort à produire pour changer d'habitude et notamment le changement de philosophie induit par la distribution des dépôts.
Je m'y met de plus en plus serieusement ce qui implque d'autres publications à l'avenir sur cet outil qui fait maintenant parti de mes meilleurs amis en tant que développeur.