Fenêtre maximisée en JAVA

Lors de l’initialisation d’une fenêtre (JFrame) en JAVA, on commence habituellement par définir son titre, sa taille et sa position sur l’écran. Cependant, dans certains cas, on peut vouloir la faire apparaître maximisée à l’écran sans que l’utilisateur n’ait à appuyer sur le bouton de maximisation.

Ceci se fait simplement en procédant comme suit :

import java.awt.HeadlessException;
import javax.swing.JFrame;

public class Frame extends JFrame {

    public Frame() throws HeadlessException {
        this.setTitle("Maximized");
        this.setSize(800,600);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);
        this.setVisible(true);
    }
}

C’est la ligne

this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);

qui permet d’obtenir l’effet voulu. On peut aussi choisir de maximiser sa fenêtre dans un sens ou dans l’autre à l’aide des variables MAXIMIZED_HORIZ et MAXIMIZED_VERT.

Comparer le type d’un objet en Java

Il peut être intéressant dans certains cas de stocker différents types d’objets dans une ArrayList. Ceci implique que tous les objets aient un niveau d’abstraction supplémentaire pour être contenus dans cette liste. Le problème va être d’identifier chaque type d’objet lorsque l’on voudra les sortir de cette liste.

Prenons un exemple concret. Nous souhaitons créer un objet « Carte » qui peut contenir un « Nom« , un « Prenom » et plusieurs « Email » tous héritant de la classe « ElementCarte« . Ne sachant pas quels éléments seront ajoutés à la carte, il est plus simple de créer une ArrayList de « ElementCarte » dans laquelle se trouveront les différents éléments.

Le problème sera lorsque nous souhaiteront exploiter les données enregistrées. Le plus intéressant serait de caster chaque donnée, mais comment savoir à quel type spécifique il correspond ? C’est là qu’intervient instanceof. Il permet de tester le type d’un objet. On pourra donc faire quelque chose comme :

for (ElementCarte ec : maListe) {
    if (ec instanceof Nom) {
        //Alors l'élément est de type Nom
    }
}

Chaque élément peut ainsi être traité en temps que son type et pas en temps que la classe dont il hérite.

Hasher une chaîne de caractères en Java

Une notion élémentaire de sécurité informatique est de ne jamais stocker un mot de passe en clair. La moindre brèche de sécurité qui donnerait accès à la base de stockage des comptes utilisateurs aurait des conséquences catastrophiques.

Pour éviter un tel problème, on prend l’habitude systématique de hasher les mots de passe. On prend aussi l’habitude de faire ce que l’on appelle « saler » les mots de passe mais je reviendrai là dessus à la fin.

En Java, le code suivant retourne le hash sous la forme d’un tableau de byte. Son avantage est de ne pas se limiter au seul hash MD5.

public byte[] hasher(String toHash, String algorythm) {
	byte[] hash = null;

    try {
    	hash = MessageDigest.getInstance(algorythm).digest(toHash.getBytes());
    } catch (NoSuchAlgorithmException ex) {
    	Logger.getLogger(Hasher.class.getName()).log(Level.SEVERE, null, ex);
    }

    return hash;
}

Le hash MD5 produit un résultat sur 128 bits. Il est le plus souvent écrit comme une suite de 32 caractères hexadécimaux. Cependant, grâce à ce code, on peut aussi hasher des chaines en SHA-1, SHA-256, …

Il existe plusieurs manières de transformer ce tableau de byte en chaîne de caractères lisible. La plus simple que j’ai trouvé est celle ci :

public String toReadable(byte[] hash) {
    StringBuilder stringBuilder = new StringBuilder();
    for (byte byt : hash) {
        String hex = Integer.toHexString(byt);
        if (hex.length() == 1) {
            stringBuilder.append(0);
            stringBuilder.append(hex.charAt(hex.length() - 1));
        } else {
            stringBuilder.append(hex.substring(hex.length() - 2));
        }
    }
    return stringBuilder.toString();
}

On obtient ainsi un hash de n’importe quelle chaîne, et ce, dans l’algorithme que l’on souhaite.

Maintenant, je vais vous expliquer ce que l’on appelle le sel (salt) et quel est son intérêt.

Un sel est une séquence de bits dont le but est de modifier une séquence originel, dans notre cas, un mot de passe. La séquence peut être aléatoire ou choisie, mise avant ou après, voire même imbriquée. Le but de ce sel est de rendre unique la séquence finale afin de compliquer la tâche d’un attaquant éventuel. Le sel contre particulièrement bien les attaques que l’on appelle attaque par dictionnaire en diminuant les chances que la chaîne se trouve dans l’un d’entre eux.

De plus, même si le hash final ainsi que le sel sont trouvés, il faudrait générer un dictionnaire par sel. Autant dire une tâche longue et fastidieuse à laquelle aucun attaquant ne se lance tellement sa rentabilité est faible.

Taille maximum d’un String

Dans la continuité des découverte faites avec Hook, une question qui s’était posée était la taille maximum que pouvait atteindre un String en Java, Par extension, j’ai cherché la réponse dans plusieurs langages.

Deux choses peuvent limiter la taille d’un String :

  • La taille de la pile attribuée (Heap Size) (Surtout lorsque l’on passe dans une machine virtuelle)
  • La taille maximum que peut prendre un tableau soit, en Java, Integer.MAX_VALUE. Ceci correspond à 2 147 483 647 caractères soit 2^31 -1 caractères ou la taille de stockage d’un int.

La gestion des String étant la même dans presque tous les langages, on peut considérer cette limite valide dans la majeur partie des cas.

Les détails viennent d’ici : http://blog.lecharpentier.org/2012/06/27/java.lang.string-limits/

byte[] to String

Beaucoup de développement ces temps ci et donc pas mal de petites découvertes.

Sur le projet Hook, nous avions à traiter les images que nous envoyions comme des tableaux de Byte afin de le encoder en Base64. Ici, pas de fonction dans le JDK natif, mais une classe Base64 des plus efficaces dans le SDK Android. Cependant, de l’autre côté, pour les stocker, il nous fallait récupérer les tableaux, et les convertir en String. Ceci est déjà mâché en Java puisqu’il existe un constructeur de String prenant en paramétré un byte[]. Il est même possible de préciser l’encodage stocké dans la chaîne de caractère.

Modifier le dossier de base de Java dans NetBeans

J’ai récemment eu à réinstaller tous mes logiciels dont NetBeans et mon JDK (Java Development Kit). Cependant, manque de chance, entre le début et la fin de mes installation, la dernière version de Java avait changée et était passée de la 1.7u10 à la 1.7u11.

J’ai naturellement désinstallé l’ancienne version pour mettre la nouvelle mais, surprise, au lancement suivant de mon NetBeans, j’ai eu une magnifique erreur stipulant :

Cannot locate java installation in specified jdkhome:
C:\Program Files\Java\jdk1.7.0_11
Do you want to try to use default version?

Pour y remédier, rien de plus simple, il suffit d’aller modifier l’adresse suivant netbeans_jdkhome= dans le fichier de configuration de l’IDE. Ce fichier est /etc/netbeans.conf (Sous Windows, dans le répertoire d’installation de NetBeans)

Week End Be My App du 5 au 7 Octobre 2012

Je parle assez peu de moi dans mon blog et en tout cas si je le fais c’est pour donner un contexte à une résolution de problème que j’ai eu. Voilà l’article qui marque un changement vu qu’aucun problème ne va être résolu dans cet article. Je ne compte pas devenir un rédacteur de skyblog pour autant mais mon point de vue a quelque peu évolué.

L’évènement qui me fait sortir de ma discrétion à propos de ma vie est un évènement qui m’a réellement marqué et que je recommande à tout développeur / designer / marketer / hacker / IT fan est Be My App. Du vendredi 19H au Dimanche 22H (bien que nous ayons dû partir, plus tôt à cause du trajet Paris – Clermont-Ferrand qui n’est pas anodin), un weekend entier de développement sur le thème du NFC.

Be My App a, d’après ce que j’ai pu voir, des partenaires et une organisation aux petits oignons. Pas moins que JCDecaux, Orange, Intel, BeGeek, FrAndroid, Programmez, FrenchWeb, le Forum des services mobiles sans contact, le blog Avec ou sans contact, Fred Zone, Le blog des nouvelles technologies comme partenaires. Pour ce qui est de l’organisation, un timing parfait, une équipe connaissant son métier et des intervenants tout aussi qualifiés. Tout était fait pour que l’on puisse avoir tout le matériel, les outils et les connaissances à disposition pour travailler. Pour ce qui était des locaux, l’évènement s’est passé à l’IESA multimédia. De la place pour tout le monde, même si les organisateurs eux même n’en attendaient pas autant. Le seul petit détail négatif que l’on peut trouver était la profondeur des tables et leur inclinaison qui bien que très certainement pratique pour des feuilles de papier, s’avéraient un peu juste pour des laptops (d’autant plus pour les 17″). On faisait fie de ce détail assez rapidement cependant.

La première soirée a commencé avec ce que l’on appelait les « pitches » qui correspondent à la présentation des différentes idées proposées par les « porteurs d’idées« . 37 présentations ont été faites à ce moment là et chaque idée était votée par un jury de 5 « mentors« . Ces votes étaient finalement à titre indicatifs et n’influaient pas sur la suite. Ce qui influait était leur délibération qui a eu lieu après et au cours de laquelle 7 projets ont été choisis pour être en compétition pour le prix final. Durant cette délibération, un jeu servant au rattrapage d’une idée était organisé et correspondait à une sorte de sélection du publique. Chaque porteur d’idée allait tenter de collecter des jetons qui avaient été remis à chaque développeur lors de leur arrivé. Les jetons récoltés étaient ainsi comptés et les résultats remis aux mentors. 1 projet supplémentaire était ainsi rattrapé. Une fois les idées sélectionnées lançées, il était possible de rejoindre l’un des groupes ou, comme mes amis et moi avons décider de le faire portés par un très bon designer intéressé par notre idée, de développer son idée en tant que team dissidente.

Les hostilités étaient alors lancées pour une durée de 48H. A nous d’organiser notre temps comme nous le souhaitons pour nous reposer (fort peu) ou nous ravitailler (fort bien et fourni par les organisateurs de surcroît, nous évitant ainsi d’avoir à quitter les lieux et de risquer de nous perdre ou de perdre du temps) pendant le temps imparti. Deux petites pauses étaient prévues le samedi pour, à la mi-journée, faire un checkpoint vidéo puis, en fin d’après-midi, pour faire une sorte d’entrainement à la présentation du lendemain.

Au cours des 48H de code, de nombreuses personnes, plus compétentes les unes que les autres dans leurs domaines, sont venues nous aider à forger notre projet, à trouver les points d’attaque marketing, à étoffer l’idée de base que nous avions afin de, petit à petit, la voir vivre. L’aspect recherche d’un business model systématique a été une grande découverte pour moi. En effet, la plupart des idées que j’ai amené à maturité n’étaient destinées qu’à mon usage personnel ou à être diffusées de manière open source et sans attente de rétribution financière. La manière de monétiser une application mobile était une recherche particulièrement intéressante. D’ailleurs, Be My App va organiser des conférences à ce sujet le Mardi 16 Octobre et je regrette déjà de ne pas pouvoir y participer (Be My App Comment monétiser votre application mobile ?)

Un autre checkpoint vidéo était organisé le dimanche à la mi journée avant l’arrêt du code à 18H. Une légère pause (la plupart du temps la finalisation des slides de présentation) jusqu’à 19H était octroyée puis les présentations finales avaient lieux. Ces présentations étaient faites devant tous les membres du jury et donc étaient intéressantes même pour les team dissidentes puisqu’elles permettaient potentiellement de se faire repérer. En effet, en plus des mentors de la première sélection, un certain nombre de membres liés aux différents sponsors venaient participer aux choix. Ayant dû partir après notre présentation, je n’ai pas tous les détails de la fin des décisions mais ce qui était annoncé était le passage de toutes les team sélectionnées puis le vote des jury pour choisir les gagnants.

En résumé, ce weekend était une expérience particulièrement géniale. L’ambiance était extrêmement chaleureuse et le contact avec les gens était très facile. Ça se sentait que tout le monde était là pour rencontrer des gens et s’éclater. Cela a été aussi l’occasion de voir naître des projets particulièrement prometteurs que l’on verra peut-être en place et prendre en notoriété au fil du temps.

En ce qui concerne ma team, nous avons eu l’occasion de commencer, et presque finir mais maintenant que les 48H sont passées nous pouvons prendre le temps de faire les choses bien, notre projet nommé Hook (NFCard lors de la présentation du Vendredi). Vous pouvez suivre l’avancement de cette application sur les pages facebook et twitter créées à cet effet.

En tout cas comme dit au début, je recommande à toute personne ayant la possibilité de se rendre à ces évènements Be My App d’y aller et j’espère réellement pouvoir y retourner dès que possible. Je félicite encore les organisateurs pour leur travail et la vivacité qu’ils ont su amener à tout le weekend.

PS : Les photos de l’event

Installer Java sous Linux et l’ajouter au Path de l’interface graphique

Je suis un utilisateur de Java depuis quelques années maintenant et malheureusement, depuis le passage à la version 7, il n’y a plus d’installateur automatique pour les versions autres que RPM (gageons que ce soit temporaire). Voici donc la procédure pour avoir un Java fonctionnel et facilement upgradable par la suite.

Tout d’abord, il faut commencer par télécharger le JDK et le JRE qui nous intéresse sur la page officielle de Java. Il faut bien sûr prendre la version tar.gz et pour ma part je prend la version 64bits. Je me retrouve donc avec les fichiers :

jre-7u7-linux-x64.tar.gz
jdk-7u7-linux-x64.tar.gz

Je créé ensuite un dossier java dans le dossier /opt/ puis y déplace le JDK et le JRE à installer à l’aide des commandes :

mkdir /opt/java
mv jre-7u7-linux-x64.tar.gz jdk-7u7-linux-x64.tar.gz /opt/java/

On décompresse ensuite les deux archives puis on les renomme respectivement en jre et en jdk :

tar -xzf jdk-7u7-linux-x64.tar.gz
tar -xzf jre-7u7-linux-x64.tar.gz
mv  jdk1.7.0_07 jdk
mv  jre1.7.0_07 jre

Il ne reste plus qu’à enlever les deux fichiers d’archives et on a les fichiers d’exécution de Java à leurs places définitives. L’avantage de cette mise en place est qu’il n’y aura qu’à remplacer les fichiers à l’intérieur des dossiers jdk et jre par les nouvelles version de Java. Ce sera ainsi le seul changement qu’il y aura à apporter par la suite pour mettre à jour sa version.

Maintenant qu’on a des emplacements de Java suffisamment génériques pour résister aux changements de versions, il faut les inclure au PATH. Il y a plusieurs solutions en fonction de ce que l’on désire mettre en place. Pour ma part, je voulais inclure Java partout (sous entendu y compris dans l’interface graphique) afin que les programmes qui en ont besoin le trouve facilement. De plus, ceci me permet de lancer facilement mes programmes sans mettre la direction absolue de mon installation.

Je vais maintenant détailler différentes possibilités d’installation :

  • La première permet d’ajouter Java au PATH console d’un seul utilisateur. Il suffit pour ce faire de rajouter les lignes :
export PATH=$PATH:/opt/java/jdk/bin:/opt/java/jre/bin
export JAVA_HOME=/opt/java/jre/bin

à la fin du fichier .bashrc de l’utilisateur.

  • La deuxième permet d’ajouter Java au PATH console de tous les utilisateurs du système. Il suffit de rajouter les même lignes qu’au dessus mais dans le fichier : /etc/bash.bashrc
  • La dernière, et celle que j’ai utilisé, permet de modifier le PATH de tout le système. Elle consiste à modifier le fichier /etc/environment. On modifie la ligne PATH et on rajoute une variable JAVA_HOME au fichier de cette manière :

PATH= »/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/java/jdk/bin:/opt/java/jre/bin »
JAVA_HOME= »/opt/java/jre/bin »

De nombreux détails sur les variables d’environnements et leurs utilisations sont présentes sur les pages officielles d’Ubuntu.

Après un simple redémarrage de l’ordinateur, les configurations seront prises en compte. Nous voici donc avec un Java facilement upgradable utilisable partout.