mardi 7 août 2018

Accélérer les développements Web Java avec le plugin Maven Tomcat

Le but de cet article est de partager quelques astuces qui vont nous permettre de gagner du temps lors de la phase de développement des applications web en Java qui utilisent une base de données MySQL et un conteneur web Apache Tomcat, en utilisant comme principale outil Maven et Eclipse, ainsi que MySQL.
Plan :
  • Installer Eclipse Mars, version Java EE sous windows.
  • Création d’un projet Maven , dépendences et plugins.
  • Plugin maven tomcat
  • Intégration avec la base de données MySQL en utilisons une DataSource de Apache Tomcat.
  • Installation d’Eclipse Mars :
Il faut installer au préalable la JDK, référez-vous à mon article sur l’installation de la JDK, puis allez sur le site :
Télécharger le fichier ZIP, puis décompresser le, placer à l’endroit de cotre choix, puis cliquer sur l’icône d’Eclipse.
Parmi les avantages d’utilisation de cette version est qu’elle intègre par défaut un certain nombre de plugins que nous allons utiliser pour développer une applications web java, parmi c’est plugin :
  • Maven Integration for Eclipse, donc on n’a pas besoin d’installer Maven pour pouvoir l’utiliser, avec cette version.
Pour s’assurer que vous avez ces outils, il faut se rendre dans Eclipse, Help à About Eclipse , vérifier que vous avez wtp et m2e (comme sur le schéma suivant):
00-help
  • Création d’un projet web dynamique avec Maven :
Vous faites un clic droit dans le projet Explorerd’Eclipse, puis vous cliquez sur New, puis Project et vous sélectionnez Maven Projet comme dans la capture d’écran suivant :
01-nouveau projet maven
Puis, vous cliquez sur Next, et cochez : Create a simple projet (skip archetype selection) :
Puis, vous cliquez sur Next, après il faut renseigner le Group IDl’Artifact Idversion et le Packaging :
C’est cette partie du POM (Projet Object Model) qui est un fichier XML, va permettre d’identifier votre projet.
GroupId : va permettre de connaitre la partie (entreprise, communauté, …) qui gère le projet. Pour les conventions du nommage on utilise ce qu’on appelle un reverse du domaine.
ArtifactId : est l’identifiant unique du composant qu’on développe au sein du GroupId .
Version : par défaut Majeur.Mineur.Correctif suivi du mot clé réservée de Maven SNAPSHOT.
Pour plus d’informations sur les conventions de nommage, voir le lien : https://maven.apache.org/guides/mini/guide-naming-conventions.html
  • Exemple :

4.0.0

com.alphorm

exemple-maven

0.0.1-SNAPSHOT

war

J’attire votre attention sur le fait qu’il faut spécifier que le packaging et un war, puisque nous créons une application web dynamique.
Une fois que nous avons créé notre projet Maven on a le fichier pom.xml qui ressemble à ça :
Pour les besoins de notre projet web java, nous devons ajouter les dépendances suivant :
  • servlet-api
  • jsp-api
  • jstl
  • mysql-connector-java
Il y a plusieurs manières de le faire, mais on veut le faire directement à partir d’Elipse, pour cela il faut configure Eclipse pour qu’il charge les dépendances dont on a besoin directement du central repository, donc il faut aller dans le menu Window à Prefernces àMaven, puis il faut cocher la case : Download repository index updates on stratup :
04-config mavne
Par la suite il faut aller dans notre fichier pom.xml, puis on clique sur l’onglet Dependencies, puis Add…
Supposons que je veux ajouter JSTL pour une application qui utilise Servlet 3.0 à titre d’exemple.
05-maven dependencies
Puis, une fois qu’on ajoute notre dépendance on a la possibilité de modifier ces propriétés, typiquement je veux modifier le scope de ma dépendance à provided pour dire que cette dépendance sera fournie par notre environnement d’exécution qui tomcat dans notre cas, que nous allons devoir configurer par la suite à l’aide de Maven.
Afin d’arriver à notre but nous allons sélectionner notre dépendance, puis on clique sur propriétés qui nous ouvre la fenêtre des dépendances comme suite :
06-modifier les propriètes de maven
Jusqu’à présent nous avons ajouté les dépendances dont on a besoin pour notre application, et nous souhaitons tester les Servlets et les JSP que nous avons développé. Donc on a besoin d’un conteneur web, qui va nous permettre de tester nos développements, il y a plusieurs solutions, mais nous avons choisi d’utiliser Maven pour intégrer le conteneur web Tomcat, maven nous propose d’ajouter des plugins, le pluign que nous allons utiliser est :
  • tomcat7-mavenplugin
Pour l’ajouter, il faut sélectionner notre projet, clique droit, puis Maven –> Add Plugin
07-ajout d'un plugin maven
Nous avons ajouté notre conteneur web Tomcat à notre projet à travers les plugins Maven, maintenant nous allons pouvoir tester notre application, pour cela il faut crée un run configuration pour notre projet, il faut faire un clic droit sur notre projet, puis run As à Maven Build …, j’insiste sur les 3 points, vous aurez la fenêtre suivante :
Puis, au niveau du Goals il faut taper : tomcat7 :run
08-editer une config maven
Par la suite, il sera disponible dans le Run AS …  Avec le nom que vous avez choisi.
Si vous n’avez pas d’erreurs vous une console log pareil, avec un une adresse pour tester :
09-console maven
Je commence les tests et voici les résultats :
J’arrive à accéder à ma JSP de login :
10-tomcat7 goal run
On plus d’un goal tomcat7 :run, il existe un ensemble d’autre goal, que vous pouvez trouver sur ce lien : https://tomcat.apache.org/maven-plugin-2.2/tomcat7-maven-plugin/plugin-info.html
Je vais démontrer l’utilisation d’un autre goal qui va nous permettre de créer un war (Web Archive) :
11-tomat7 war goak
On exécute ce goal qui va créer le war de notre projet au niveau du répertoire target :
12-war file

Utilisation d’une DataSource pour la gestion des connections (Pool de connection) :


Nous souhaitons se connecter à la base de données ou mes utilisateurs sont stocker, afin que je puisse les identifier. Plusieurs choix et solutions s’offre à nous, n’hésitez pas à voir le cours Java OCP (1Z0-804) le chapitre JDBC sur la plateforme Alphorm, qui explique les différents choix possibles :
C’est d’ailleurs un cours de très bonne qualité !
Revenons à nos moutons, le choix c’est porter sur l’utilisation d’un pool de connexion qui sera fourni par notre conteneur web Tomcat, à l’aide d’une DataSource qui sera localisé à l’aide d’un service de nommage (JNDI)qui va nous permettre de trouver notre ressource.
Pour voir le différence entre un DirverManager et une DataSource rendez-vous : http://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html
Là aussi, on peut compter sur Maven pour aller très vite, cependant la configuration demande un peu de concentration.
Il nous faut :
  • Une DataSource pour les pool de connexion (sera fournie par Tomcat)
  • Pour la recherche il nous faut JNDI avec InitialContext
Nous commençons par configurer le plugin tomcat7-maven , dans notre fichier pom.xml on précisons le contextFile, qui contient le fichier context.xml :





       org.apache.tomcat.maven

       tomcat7-maven-plugin

       2.2

       

                    src/test/resources/context.xml

       

La création du fichier context.xml, il faut faire attention au ResourceLink  le name doit être celui du Context:





       





       



       

    

Il faut aussi configurer le fichier web.xml, on ajoutons :



    Connexion à la base de données MySQL

    jdbc_mabdd

    javax.sql.DataSource

    Container

  
 

Notre ressource est disponible il ne reste qu’à l’utiliser, et notre but est d’initialiser notre de pool de connexion avant le démarrage de notre application web, alors la solution c’est d’utiliser l’interface : ServletContextListener, voiçi un exemple :
@WebListener

public class InitialisationPoolDeConnexion implements ServletContextListener{



       public void contextInitialized(ServletContextEvent sce) {

             // Initaliser le contexte

                           Context contextInitial=null;

                           System.out.println("ouverture du : ServletContextListener");

                           try

                           {

                                  contextInitial=new InitialContext();

                                  if (contextInitial==null)

                                  {

                                        throw new Exception("Impossible de charger le contexte");

                                  }



                                  // Connexion JNDI

                                  Context environnement=(Context)contextInitial.lookup("java:comp/env");

                                  DataSource datasource=(DataSource)environnement.lookup("jdbc_mabdd");

                                  if (datasource==null)

                                  {

                                        throw new Exception("Erreur lors du chargement du datasource");

                                  }

                                  // Sauvegarder le datasource dans le contexte de l'application

                                  ServletContext servletContext=sce.getServletContext();

                                  servletContext.setAttribute("datasource", datasource);

                           }

                           catch (Exception e)

                           {

                                  System.out.println(e.getMessage());

                           }

                           finally

                           {

                                  try

                                  {

                                        // On ferme le contexte

                                        if (contextInitial!=null)

                                        {

                                               contextInitial.close();

                                                                                        }

                                  }

                                  catch (Exception e)

                                  {

                                        System.out.println("Erreur lors de la fermeture du contexte");

                                  }

                           }

       }



       public void contextDestroyed(ServletContextEvent sce) {

             System.out.println("Fermeture du Datasource");

       }


Ainsi, nous avons pu voir comment accéder notre cycle de développement à l’aide de Maven pour créer un projet web dynamique, comment ajouter des dépendances et comment ajouter le plugin tomcat7-maven pour lancer notre serveur configurer une connexion avec la base de données en utilisant une DataSource pour créer un pool de connexion, sans installer tomcat, ni le configurer.

Installation de node.js avec NVM

Dans cette suite de tutoriaux d’introduction à node.js, nous allons voir comment installer node.js sur Ubuntu (Unix-like system). Pour les fans de Microsoft je tiens à vous annoncer la petite surprise qui  date de la semaine dernière et qui est le support de Node.js par l’IDE Visual Studio à travers le plugin gratuit NTVS. Pour plus d’informations, rendez-vous sur le site officiel:  https://nodejstools.codeplex.com/.

Installation de node.js avec NVM

NVM (Node Version Manager) est un outil multiplateforme pour installer Node.js, et permet de compiler Node.js manuellement. A noter qu’il est aussi possible d’installer Node.js avec le package manager de Ubuntu, cependant il n’est pas très flexible et ne permet pas toujours d’installer la dernière version. Il faut cloner le dépôt NVM à partir de Github (lien : https://github.com/creationix/nvm), et pour cela il faut au préalable installer un client Git, ainsi que curl sur votre machine Ubuntu.
1) installation de Git sur Ubuntu, ouvrez le terminal et tapez:
sudo apt-get install git
2) même chose pour installer curl:
sudo apt-get install curl
3) Une fois qu’ont à les deux outils Git et curl, on est pret à installer NVM, il faut copier cette ligne à partir du lien précedent:
curl https://raw.github.com/creationix/nvm/master/install.sh | sh
Une fois l’installation de NVM correctement terminée, vous aurez ce message:
Close and reopen your terminal to start using NVM
Fermer votre navigateur et ouvrer le à nouveau, et pour s’assurer que NVM à bien été installé, tapez dans le terminal.
nvm
Si tous marche bien une liste des options de NVM, ainsi que des exemples seront affichés.
4) une fois NVM est correctement installé, tapez dans le terminal
nvm install 0.10
5) une fois Node.js installé, tapez dans le terminal:
node
Vous serez redirigé vers l’interpréteur Node.js, et voilà !
Pour quitter l’interpréteur node, faîtes (ctrl +c 2 fois )
6) Une dernière chose avant de quitter votre terminal et finir cette première partie, il faudra définir la dernière version de node.js comme version par défaut, sinon à chaque fois que vous ouvrirez votre terminal vous n’aurez pas node.js !
nvm alias default 0.10
Enfin, pour etre sûr que cela fonctionne, fermez votre terminal, puis ouvrez-le à nouveau et taper:
node --version
Cela doit vous afficher la version utilisée.

Conclusion

Dans ce petit tutoriel, nous avons vu l’installation de Node.js avec l’outil NVM dans Ubuntu, ainsi que ses avantages par rapport au package manager.
Dans le tutoriel suivant nous allons créer notre premier serveur web HTTP avec Node.js

Introduction à Node.js


Node.js est une nouvelle technologie très utilisée à la Silicon Valley, notamment par Microsoft, VMware, eBay, Yahoo, LinkedIn, etc …  pour n’en citer que quelques uns.
Dans cette série d’articles, on va voir comment node.js offre de nouvelles opportunités aux développeurs.
Peut-être que vous avez entendu parler de Node.js, et vous savez qu’il est utilisé pour des applications « temps réel » ou qui demande de la «haute performance », et vous savez certainement que Node.js est du JavaScript côte-serveur, mais vous n’êtes pas sûrs quand et/ou pourquoi l’utiliser, rassurez-vous dans ce tutoriel, je vais tenter de vous expliquer quand l’utiliser et pourquoi.

Quand choisir Node.js ?

A l’époque du Web 2.0, le web est devenu plus interactif. Les utilisateurs autour du monde ont besoin d’interagir entre eux et ceci en temps réel. Le tchat, les jeux en ligne, réseaux sociaux, ainsi que les outils collaboratifs  sont des applications qui demandent une communication en temps-réel entre les utilisateurs. Cette communication en « temps-réel » doit se produire à grande échelle, en supportant des millions de requêtes.

Intro à Node.JS

Node.js est un environnement créé par Rayn Dahl en 2009 qui s’appuie sur le JavaScript exécuté côté serveur. Comme le montre le schéma ci-dessous il est principalement basé sur libuv, le moteur V8 JavaScript de Google utilisé dans le navigateur Google chrome, et le langage JavaScript.
node-1
A noter que Node.js n’est pas un Framework web, pour avoir une idée sur ces différents Framework de Node.js, je vous conseille de voir ce lien : http://webapplog.com/node-js-frameworks/ parmi d’autres.
Dans ce tutoriel, j’explique brièvement la différence entre fonction bloquante et non bloquante à travers un exemple, et pour clôturer, j’expliquerai l’utilité de la boucle d’évènement dans Node.js.
Pour commencer Node.js il faut comprendre la différence entre Node.js est les environnements des langages de script exécutés côté serveur tel que PHP.

La programmation asynchrone (ou non-bloquante)

J’illustre ici le principe de la programmation bloquante et la programmation non-bloquante, avec ce pseudo-code.
Par exemple un code bloquant sera de la forme suivante :
Lire le fichier à partir du système de fichier, stocker le contenu dans "contenu"
Afficher contenu
Faire autre chose
Avec cette version on ne peut pas afficher le contenu tant que l’on a pas lu tout le contenu à partir du fichier (on ne peut pas faire autres chose tant que la lecture et l’affichage ne sont pas faits), car on a trois instructions bloquantes en série.
Une version non-bloquante du code sera de la forme suivante :
Lire le fichier à partir du système de fichier
       Et quand tu as fini, affiche contenu
Faire autre chose
Avec cette version on peut lire le contenu à partir du fichier et quand la lecture est finie on pourra l’afficher. Entre temps, on passe à l’instruction suivante sans attendre le retour de la fonction qui la précède, ce qui permet en quelque sorte un « pseudo-parallélisme » même en sachant que Node.js n’est pas multithread. Cette technique est ce qu’on appelle «callback ».
Si on veut traduire ce code bloquant, ça sera :
var contenu = fs.readFileSync('/etc/hosts');
console.log(contenu) ;
console.log('Faire autre chose');
La version non-bloquante sera :
fs.readFileSync('/etc/hosts', function(err, contenu ){
    console.log(contenu);
});
console.log('Faire autre chose');
A noter que la plupart des fonctions contenues dans Node.js sont des fonctions asynchrones (c’est-à-dire des fonctions qui ne reste pas bloquées en attendant qu’une autre fonction soit terminée). C’est pour cela que le langage JavaScript est un de ces principaux composants comme le montre le schéma précèdent, car il permet l’utilisation des fonctions callbacks.
Comme mentionné au début de cet article, node.js est un environnement, ce qui signifie que certains fonctionnalités ne sont pas accessibles avec l’installation par défaut. Il est cependant très facile de charger des librairies externes créées par la communauté pour la majorité des besoins « classiques ». La création d’un serveur web peut par exemple être facilement réalisé avec la librairie « Express ».

Boucle d’évènements (Event Loop)

Je me permets de traduire ce que Rayn Dahl a dit à propos du choix du langage JavaScript:
« Le langage JavaScript a certaines caractéristiques qui le différencie des autres langages dynamiques. Il n’a pas de concept de threads, son modèle de gestion de la concurrence est complètement basée autour des évènements. »
JavaScript nous permet de faire la programmation événementielle en utilisant la boucle d’évènements et d’écrire un code asynchrone (non-bloquant).
Alors qu’est-ce que la boucle d’évènements ?
La boucle d’évènement est une file FIFO (First-In-First-Out). Lorsqu’une fonction asynchrone est exécutée, les fonctions callbacks sont ajoutées dans la file, et le moteur JavaScript ne démarre pas le traitement de la boucle d’événements jusqu’à ce que le code qui est après la fonction asynchrone soit exécuté. Puisque la boucle d’évènement est une file (FIFO) les fonctions callbacks s’exécutent dans l’ordre où elles étaient ajoutées à la file d’attente.

Conclusion

Node.js est un environnement qui permet d’exécuter JavaScript côte serveur, offrant de hautes performances pour des applications temps-réel grâce à son modèle mono-thread.
Dans le prochain tutoriel nous allons installer Node.js via le gestionnaire de version de Node (NVM) dans un environnement Ubuntu.

Node.js : Construire un serveur web personnalisé léger en utilisant node.js


Alors que faire si vous avez besoin de quelque chose de précis ? Internet Information Server (IIS) et Apache sont gourmands, et même les serveurs de nouvelle génération comme nginx nécessitent des ressources importantes. C’est là qu’intervient node.js Au lieu de prendre un serveur Web existant, on vous permettant de tailler votre application autour de ses fonctionnalités et API, node.js adopte une approche très différente. Vous n’avez pas de serveur, vous avez juste un kit de pièces que vous pouvez assembler dans votre propre application web sur mesure qui gère les entrées et sorties que vous avez conçu – il s’agit d’un routeur qui prend les entrées et sorties donnée, pour vos applications web.
Un autre avantage, c’est la possibilité d’écrire des extensions pour votre serveur Web avec le langage du Web: JavaScript.

Création d’un serveur web avec Node.js

Contrairement aux serveurs web classiques, vous aurez besoin d’écrire du JavaScript pour pouvoir traiter les requêtes client, et ainsi construire de votre propre serveur Node.js. Commencez par créer un fichier appelé « server.js ».
var http = require("http");
 console.log("démarrage du serveur web");
 var host="127.0.0.1";
 var port="9999";
Nos premières lignes de code ont déclaré 4 variables clés – le protocole de notre serveur ,un message , l’hôte et le port sur ​​lequel notre serveur écoute. Nous pouvons maintenant commencer à ajouter du code pour gérer les requêtes, et les réponses. Nous pouvons le faire en une seule ligne, avec une fonction imbriquée dans un objet createServer.
http.createServer(function (request, response) {
   response.writeHead(200, {'Content-Type': 'text/plain'});
   response.end('Hello from Node.js\n');
 }).listen(port,host, function() {
   console.log("ecoute sur : + host +": "+ port");
 });

Exécuter le serveur

Le code que nous avons ajouté affiche une simple réponse http, ce qui signifie que vous avez besoin de plus que ça, afin que votre serveur puisse répondre à toutes les requêtes http, c’est ce qu’on va voir dans le prochain tutoriel. Enfin avant de se quitter lancer votre serveur avec la commande :
node server.js
Puis ouvrez votre navigateur et entrez l’url : 127.0.0.1:9999, pour voir le résultat.

lundi 6 août 2018

Git Tips : Cherry-pick

La commande « Cherry-pick » permet de sélectionner un commit dans une branche et l’appliquer sur une autre branche. Ce patch sera considéré comme un nouveau commit dans la nouvelle branche. 
 
Pour abandonner un cherry-pick en cas d’erreur, il faut faire :   
  • Git cherry-pick --abort 
Pour faire un roll back d’un cherry pick, il y a deux méthodes : 
  • Si la branche est privée : git rebase. 
  • Si la branche est publique : git revert. 

Cas d’usages de cherry-pick : 
Lorsqu’on découvre un « defect » en production, et qu’on a corrigé le « defect » pour la branche de production, nous devons apporter les modifications à la branche de développement entre autres. 

  • La première approche auquel il faut penser c’est de faire un simple merge si cela fonctionne correctement. Si le merge est possible ç’est de loin la meilleure solution.  Sinon, si d’autres changements ont été apportés à la branche production et qui ne doivent pas figurer dans la branche de développement, le merge ne produira pas le résultat souhaité, puisqu’il va inclure tous les autres changements apportés à la branche de production. 
  • Dans ce cas la « cherry-pick » est la réponse à votre besoin.  « Cherry-pick » va rapporter uniquement les changements inclus dans le commit sélectionner sans les changements apportés par les autres commits. 
Voici un scénario très courant qui illustre cela : 
Un « defect » a été trouvé en production. Le fix apporté est dans le commit Hmais le commit G ne doit pas être appliqué à la branche de développement. 

 
Le cherry-pick du commit H dans la branche Development, commande git à executer : 

  • Git checkout Development 
  • Git cherry-pick H 
Ce qui résulte en ça :