Cas d’utilisation

Il est fréquent que nous réalisions des bouts de codes qui peuvent devenir des bibliothèques (ou librairies pour les faux amis).

Souvent un des freins à la libre distribution de ces sources très utiles n’est pas la mise à disposition des sources (Github a bien aidé dans ce sens ces dernières années), mais la distribution sur un des dépôts Maven accessible au tout venant.

En fait, il est bon de savoir que Sonatype permet la mise à disposition de n’importe quelle bibliothèque ( open source ) dans les dépôts centraux de Maven. Pour ce faire il suffit de suivre quelques étapes.

Signature des artefacts

Si vous vous êtes déjà penchés sur la façon de fonctionner des dépôts Maven, vous aurez remarqué que les binaires disponibles sont en réalité signés par leurs développeurs. Le but est simple, permettre d’éviter que des petits malins introduisent des backdoors dans des librairies réputées (par exemple imaginez un hacker qui s’attaque à apache-httpclient…).

Ainsi il va être nécessaire de signer tous les binaires que vous allez produire, ceci passe par l’utilisation de GnuPG et de la mise à disposition de votre clef publique.

Installation de GnuPG

L’installation passe par votre gestionnaire de package classique (apt-get install gpg, brew install gpg, install-gpg-on-my-os.exe…). De là, vous pourrez vérifier dans un shell que vous avez une version d’accessible en tapant par exemple la commande suivante:

$ gpg --version
gpg (GnuPG) 1.4.16
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: ~/.gnupg
Supported algorithms:
Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

Génération de la clef

GnuPG est un mécanisme de chiffrement impliquant une clef publique (distribuée librement) associée à une clef privée (à garder précieusement). Avant de pouvoir prétendre distribuer des binaires chiffrés, il convient donc de générer le couple clef privée/publique et de distribuer la clef publique sur les serveurs appropriés. Ainsi, après avoir fourni nom, email et commentaire pour votre clef, vous serez prêt à la distribuer au plus grand nombre :

$ gpg --gen-key

Dans les écrans qui apparaissent, vous pouvez conserver les valeurs par défaut pour la plupart des éléments (type, taille et durée de validité). Enfin, vous allez devoir spécifier la passphrase de votre clef. N’hésitez pas à utiliser une phrase : elle sera plus difficilement “cassable” et vous vous en rappelerez certainement mieux qu’un mot de passe complexe.

Vérification de la clef

Pour vérifier que votre clef est correctement installée, vous pouvez récupérer la liste des clefs connues par votre système. Ainsi pour connaître les clefs publiques vous pouvez taper :

$ gpg --list-keys
/Users/cgatay/.gnupg/pubring.gpg
--------------------------------
pub   2048R/CE236D5E 2013-04-28
uid                  Cedric Gatay <[email protected]>
sub   2048R/08130909 2013-04-28

Et pour les clefs privées :

$ gpg --list-secret-keys
/Users/cgatay/.gnupg/secring.gpg
--------------------------------
sec   2048R/CE236D5E 2013-04-28
uid                  Cedric Gatay <[email protected]>
ssb   2048R/08130909 2013-04-28

Si la génération s’est déroulée comme prévu, la seule différence résidera dans l’emplacement du fichier correspondant au stockage de la clef publique et privée.

Distribution de la clef publique

Pour que tout le monde soit à même de vérifier votre “identité”, il faut distribuer votre clef publique sur les dépôts reconnus. L’un d’eux est hkp://pool.sks-keyservers.net qui fera la distribution auprès des différents serveurs OpenPGP. Pour se faire, il suffit de lancer la synchronisation vers ce serveur, en remplaçant ${KEY_ID} par l’id de votre clef publique tel que récupéré lors de la commande précédente (dans mon cas il s’agit de CE236D5E):

    $ gpg --keyserver hkp://pool.sks-keyservers.net --send-keys ${KEY_ID}

Pour vérifier que l’envoi s’est fait comme attendu, vous pouvez demander à récupérer la clef par la commande suivante :

    $ gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys ${KEY_ID}

Création d’un compte sur Sonatype

La distribution de binaires passe par la création d’un compte sur le JIRA de Sonatype. La procédure est assez simple, elle ne vaut pas la peine d’être détaillée plus avant. Ensuite, pour faire vous autoriser à distribuer vos applicatifs, il est nécessaire de créer un ticket pour demander les droits correspondants. Ce ticket doit être du type Support - Open Source Project Repository Hosting - New Project dans le JIRA OSSRH. Il vous faudra ensuite remplir les champs suivants :

  • summary : Descriptif de votre projet
  • groupId : le groupId de votre projet (généralement votre nom de domaine, org.9h41 dans notre cas)
  • Project URL : URL vers le site du projet
  • SCM URL : URL vers les sources du projet
  • Nexus Username : votre nom d’utilisateur actuel (et les éventuels noms d’utilisateurs à autoriser)
  • Already sync to central : si il y a déjà des projets sur Maven central avec le même groupId
  • Description : n’importe quelle information supplémentaire que vous jugez utile de préciser

Par exemple, le ticket correspondant à la mise à disposition de l’intégration entre Apache Wicket et ParsleyJS est OSSRH-6026

Préparation du projet pour la distribution

Pour que vous puissiez distribuer votre projet, il est nécessaire d’ajuster légèrement le descripteur de votre projet (le fameux pom.xml dans notre cas traitant de Maven).

Informations indispensables

Il est nécessaire que le pom.xml contienne les informations suivantes :

  • modelVersion
  • groupId
  • artifactId
  • version
  • packaging
  • name
  • description
  • url
  • licenses
  • scm.url
  • scm.connection
  • developers

Modification de votre projet

De plus il est indispensable d’hériter du projet parent de Sonatype, celui-ci décrit en fait les plugins ainsi que les dépôts qui vont être utilisés pour la livraison.

Vous devez donc ajouter dans votre descripteur le lien avec le parent Sonatype :

<project>
  <parent>
    <groupId>org.sonatype.oss</groupId>
    <artifactId>oss-parent</artifactId>
    <version>7</version>
  </parent>
  <!-- le reste de votre descripteur -->
</project>

Pour le remplissage des informations de votre dépôt de sources, plusieurs façon de les remplir s’offrent à vous en fonction du type de dépôt que vous utilisez, dans la majorité des cas pour les projets récents, le système de gestion de version utilisé est Git, la partie correspondant dans le pom.xmlsera donc de la forme suivante (en ajustant ${USER} et ${PROJECT} bien entendu) :

<scm>
  <connection>scm:git:[email protected]:${USER}/${PROJECT}.git</connection>
  <developerConnection>scm:git:[email protected]:${USER}/${PROJECT}.git</developerConnection>
  <url>[email protected]:${USER}/${PROJECT}.git</url>
</scm>

Préparation de votre poste pour la distribution

Pour déployer sur les dépôts gérés par Sonatype, vous allez devoir vous identifier pour gérer l’upload, bien entendu, il n’est pas concevable de stocker vos informations d’identification au sein du descripteur de votre projet :

  • vous ne voulez pas publier vos identifiants au grand public
  • vous ne voulez pas passer sur chacun des projets si vous les changez

La technique est donc d’utiliser le fichier de configuration global de Maven en définissant des paramètres. Ainsi, en éditant le fichier ~/.m2/settings.xml vous allez ajouter vos identifiants (encore une fois, en ajustant ${USER} et ${PASSWORD}):

  <servers>
    <server>
      <id>sonatype-nexus-snapshots</id>
      <username>${USER}</username>
      <password>${PASSWORD}</password>
    </server>
    <server>
      <id>sonatype-nexus-staging</id>
      <username>${USER}</username>
      <password>${PASSWORD}</password>
    </server>
  </servers>

Distribution d’une version SNAPSHOT

Si vous désirez distribuer vos bibliothèques sur des dépôts centraux, vous devez connaître les notions de SNAPSHOT et release propres à Maven. Pour faire un bref rappel, les versions SNAPSHOT sont des versions en développement alors que les versions release sont les versions finales. Ainsi, dépendre d’une version SNAPSHOT déclenchera des vérifications régulières par l’outil de construction pour récupérer toujours la dernière version alors qu’une version release ne sera rapatriée qu’une et une seule fois (en assurant la stabilité de la construction).

Sonatype fourni un dépôt pour de telles versions de développement ainsi qu’un dépôt pour les versions stables. Dans un premier temps et pour tester que votre système est correctement configuré, vous allez déployer une version SNAPSHOT de votre librairie :

$ mvn clean deploy

Si tout se passe comme prévu, votre livrable sera visible et disponible sur le dépôt SNAPSHOT de Sonatype : https://oss.sonatype.org/content/repositories/snapshots En cas d’erreur 401 Unauthorized, vérifiez que vos identifiants JIRA sont corrects (en vous connectant sur https://issues.sonatype.org).

Préparation et distribution d’une release

Le plugin Maven release est préconfiguré grace à l’intégration du descripteur parent de Sonatype, il suffit donc de l’utiliser pour construire votre projet, il va s’occuper de construire les livrables nécessaires, de les signer et de les déployer en tant que staging.

$ mvn release:clean
$ mvn release:prepare
$ mvn release:perform

Lors de la procédure, le plugin release va s’occuper de changer le numéro de version SNAPSHOT vers un numéro release, de préparer la version SNAPSHOTsuivante, de tagguer le tout sur le système de gestion de sources. Un de ses atouts est de préparer la construction à partir d’une version propre provenant du système de gestion de sources, de cette façon vous pourrez vous assurer de la reproductibilité des constructions.

Vous aurez donc besoin de saisir la passphrase de votre clef GnuPG lors du processus, pour effectuer la signature des livrables.

Vous pouvez également distribuer votre livrable avec la commande deploy comme dans le cas d’une livraison SNAPSHOT.

Publication de vos livrables

Pour finir la publication de votre livrable, il faut passer par l’interface de Sonatype https://oss.sonatype.org Dans la partie Staging Repositories, vous verrez une ligne correspondant à votre déploiement, sur cette ligne, il faudra close pour dire que la distribution est terminée, puis, une fois qu’il sera clos, il faudra en faire la promote pour qu’il soit distribué vers les dépôts Maven centraux.

Si vous ne pouvez pas clôre ou promouvoir votre livrable, Nexus vous fournira un message d’explication (tel que “impossible de trouver le jar de sources”)

Attention: pour votre première livraison vers les dépôts centraux, il sera nécessaire de mettre à jour le ticket JIRA que vous avez ouvert pour demander la synchronisation vers Maven Central.

Ajout d’un collaborateur

Il est rare que seul une personne ait le droit d’effectuer les distributions, ainsi, dès que vous désirez ajouter quelqu’un vous devrez mettre à jour le ticket JIRA pour demander l’ajout (collaborateur qui devra suivre également la première partie du guide pour créer un compte et distribuer sa signature numérique).

Livraison d’un nouveau projet

Tant que votre projet respecte le groupId dont vous avez revendiqué la paternité, vous pourrez livrer et distribuer à votre convenance sans avoir besoin de créer de nouvelles demandes sur le JIRA de Sonatype.

Install from VirtualBox ?

If you are like me, you have got plenty of hard drives hanging around and never got an optical drive or an usb stick. One thing that could reveal itself to be hard is installing a new Operating System on any machine without any of the two I mentionned earlier.

In this short tips and tricks post, I will show you how you can use VirtualBox raw disks feature (I guess here for compatibility with VMWare) to install a new Operating System from your old one (yes, without the 10 minutes part were you can do nothing else with your computer).

Prerequisites

What you will need in order for this to work :

  • a Linux setup with root access (sudoing will be fine)
  • a second hard drive where you want to put your brand new Operating System
  • ISO file of the OS you want to install

Install

First of all, install VirtualBox on your system (yum, apt-get, whatever your package system is). Then you will need to find out what is the identifier of the drive you want to use as a new (sudo fdisk -l can tell you everything you need to know about your disks).

In my example lets say I want to install on a 300GB hard drive, I got this fdisk output

cgatay@cgatay2:~$ sudo fdisk -l
[sudo] password for cgatay:

Disk /dev/sda: 251.1 GB, 251059544064 bytes
255 heads, 63 sectors/track, 30522 cylinders, total 490350672 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000efa30

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048   489302015   244649984   83  Linux
/dev/sda2       489304062   490348543      522241    5  Extended
/dev/sda5       489304064   490348543      522240   82  Linux swap / Solaris

Disk /dev/sdb: 400.1 GB, 400088457216 bytes
255 heads, 63 sectors/track, 48641 cylinders, total 781422768 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0003f041

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *          63   390627047   195313492+   7  HPFS/NTFS/exFAT
/dev/sdb2       390627048   781422767   195397860    c  W95 FAT32 (LBA)

Disk /dev/sdc: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00048185

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1   *        2048      499711      248832   83  Linux
/dev/sdc2          499712  1952790527   976145408   83  Linux
/dev/sdc3      1952792574  1953523711      365569    5  Extended
/dev/sdc5      1952792576  1953523711      365568   82  Linux swap / Solaris

Disk /dev/sdd: 300.1 GB, 300090728448 bytes
255 heads, 63 sectors/track, 36483 cylinders, total 586114704 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000cb074

   Device Boot      Start         End      Blocks   Id  System
/dev/sdd1   *        2048   574060543   287029248   83  Linux
/dev/sdd2       574062590   586113023     6025217    5  Extended
/dev/sdd5       574062592   586113023     6025216   82  Linux swap / Solaris

The interesting line is the one stating Disk /dev/sdd: 300.1 GB. From now on I will use /dev/sdd as the target of my install.

For the rest of the commands to work you need to run everything as root (by sudoing), I think there is more “cleaner” way of doing this by correctly setting suid flags but I did not took the time to look after this.

You need to create the hard disk file that will point to your physical install, then launch VirtualBox as root (there is a lot of chances that your regular user can’t do everything he wants on a device):

sudo VBoxManage internalcommands createrawvmdk -filename disk.vmdk -rawdisk /dev/sdd; #replace /dev/sdd with your device
sudo VirtualBox;

From there, this is a simple VirtualBox machine setup, you just need to select the created disk.vmdk file for the hard disk of your Virtual Machine, mount the ISO and proceed with the install. At the end of the install, you can shut down the VirtualMachine, reboot your computer and use the boot selection menu of your bios (or change the boot order) to boot directly on your newly installed system.

If you are on a Linux system, you can issue a update-grub that will detect all your operating systems and will create the boot menu (you can still boot your old one this way).

Disclaimer

This method has been tested multiple times for installing Windows as well as Linuxes without any hurt. However, it might kill kitten or trigger a nuclear war if used incorrectly, in such cases, I decline responsibility.

Thoughts

As a side note, I think a Linux host is not required, you can achieve the same with a Windows operating system, the command line surely just need some improvements to point to the physical disk.

Another Java Rest framework

If you’re a somewhat experienced Java developer I guess you’ve encountered a lot of framework when it comes to write web services.

Restx.io is a new kid on the block leveraging high velocity with a focus on testability through a set of unique and great features :

  • each rest endpoint generates its documentation from its tests (real killer feature here : we hate writing docs but we live writing tests!)
  • a built in monitoring engine
  • everything that can be done at compile time is done at that time (annotations / dependency injection)
  • it is written in good old plain Java (IDE support : I’m looking at you Play Framework!)
  • auto compile (we don’t like waiting!)

I’ve tested it on a few small projects, I can’t wait to try it on a real project !

Packt Publishing is actually discounting the full range of their eBooks and videos by 50 percent until October 17th using this discount code : COL50.

It can be a good opportunity to check “Instant Apache Wicket 6” which I reviewed a few weeks ago for the newcomers to Apache Wicket. Another good deal could be checking out the best-seller title “Mastering Web Application Development with AngularJS”!

Head over to Packt Publishing site and pick the books of your choice using the promo code COL50.

When you're developping Web applications, you often ask yourself what does your beautiful design will look like if your users enter a very long text. Or you may want to prototype a new screen based on an existing one, I came around a quick hack using HTML5 goodness: content editable !

On the page you want to edit, open your JavaScript console (Cmd+Alt+I on Chrome Mac), and enter the following

  document.body.contentEditable = true;
  

Now you can freely edit the text on your page, once you're done, you can switch off the content editable mode setting the property to false !