Google Chrome OS

Google lance une véritable bombe thermonucléaire sur le monopole bien gardé de Microsoft. Les rumeurs couraient bon train depuis quelques mois, et même quelques années. Personnellement je n’y croyais pas car il me semble que Google s’éloigne de son coeur de métier, mais il faut avouer que je ne suis pas insensible à l’idée de voir un challenger de poids proposer une alternative sérieuse à Windows.

J’aime beaucoup le navigateur Chrome et j’ai hâte qu’il soit disponible en version stable pour Linux. Ce qu’ils ont fait avec Chrome montre que les ingénieurs de Google ont des idées neuves et le talent pour les mettre en oeuvre. Pour Chrome OS, le défi est d’une toute autre ampleur et l’ambition clairement affichée. Créer un OS fiable, rapide et conviviable. Je suis certain que les ingénieurs de Google sauront répondre à chacun de ces critères.

C’est une bonne chose que Google ait décidé de développer un OS spécifique pour le marché des PC car celui-ci a des exigences différentes en matière d’ergonomie que les téléphones portables. Cela permettra d’ailleurs aux équipes d’Android de concentrer leurs développements sur le marché très prometteur des terminaux mobiles, et aux équipes de Chrome OS de travailler sur l’ergonomie propre aux PC.

Google a une vision de l’informatique diamétralement opposée à celle de Microsoft. Il sera donc intéressant de voir la concrétisation de cette vision car elle apportera un regard nouveau sur notre relation à la machine. Microsoft base son modèle économique sur la notion de biens et de possession alors que Google met en avant les possibilités en matière de services et de mutualisation qu’offrent les réseaux. Il y a autant de différence entre le modèle économique de Microsoft et celui de Google qu’entre la notion d’économique primaire et tertiaire.

Je suis ravi que Google assume sans complexe son rôle de challenger de Microsoft car cela va mettre un terme à l’économie de rente qu’est devenue le marché des systèmes d’exploitation pour favoriser au contraire l’innovation.

Swinger 0.4.1 is released

Comme le titre l’annonce, j’ai livré une version intermédiaire qui ajoute le support des layouts managers. Il est donc possible de choisir son layout, ce qui n’était pas le cas auparavant.

Cette version corrige également un bug concernant le chargement des scripts groovy à partir d’une librairie externe.

Le choix de mon parser CSS (2)

Voila quelques semaines, j’avais décidé d’implémenter les CSS dans le framework Swinger. Je savais que je me lançais dans une tâche ardue. Je m’étais fixé comme objectif de livrer une version ce mois de juin.

Avec l’arrivée du mois de juillet, je dois dire que le choix du parser Batik est un échec, je ne serai pas en mesure de tenir les délais. La raison est que je me suis rendu compte à l’intégration que mon modèle ne collait pas avec celui de Batik. Je m’attendais à un parser plus facilement exploitable, en fait il a été développé dans une philosophie assez rigide et difficile à cerner car mal documentée.

Mais la vraie raison de cet échec est que je ne me suis pas donné suffisamment de temps pour étudier cette api. La conséquence est que je me retrouve confronté à une impasse. Je n’ai que deux options qui s’offrent à moi. Soit détricotter mon code pour me conformer aux attendus de Batik, soit abandonner cette api et développer mon propre parser.

C’est la deuxième option que je choisi. Pour plusieurs raisons. D’abord cela m’ennui de renoncer à plusieurs semaines de travail. Le code que j’ai produit est loin d’être parfait et devrait pêcher par manque de performance dans le cas de CSS très complexes. Mais il est bien à adapté à l’architecture de Swinger qui repose sur des Accessors qui attendent des chaînes de caractères pour l’initialisation des attributs.

L’autre raison qui me trotte dans la tête depuis deux ou trois semaines est que je souhaite que l’api Swinger puisse être intégrée comme bundle Osgi. Or dans ce cas, les librairies externes sont un handicap si elles ne sont pas elles-même livrées en tant que bundles.

Pour ces raisons, je n’ai pas de regret à me séparer de Batik. La conséquence est que cela va retarder sensiblement la livraison d’une version supportant les CSS. Du coup, je vais livrer dans les semaines qui viennent une version intermédiaire qui permettra de choisir son layout. C’était en effet le point de départ de ma réflexion sur la configuration des attributs apparents.

Je ne suis pas en mesure de fixer de date quand au support des CSS. Ce qui est certain est que ce support sera partiel et portera sur quelques attributs seulement. Les aspects les plus délicats, comme le positionnement relatif des composants, sera reporté à une version ultérieure. En tout état de cause, le support de CSS ne sera jamais complet car la philosophie de l’api swing ne permet pas par exemple de gérer le texte de la même manière qu’en html.

Sans fournir de date buttoir en raison des beaux jours dont je profite autant que possible, j’espère néanmoins finir mon parser avant la fin du mois de juillet.

Je vous tiendrai au courant de l’arrivée de la prochaine release dans les semaines à venir qui supportera la personnalisation des layouts.

Refactoring de Swinger

Je n’ai pas encore pu commencer les tests d’intégrations car j’ai rencontré quelques soucis d’architecture. Je me suis rendu compte que l’ajout d’un attribut au modèle m’obligeait à reporter cette modification à chaque classe de composant, ce qui est évidemment aberrant. J’ai donc réécrit une partie de mon api en utilisant un Decorator ce qui rend l’architecture beaucoup plus saine. Cela va m’obliger à mener des tests de non-régression car ce refactoring n’est pas sans risque vu qu’il touche au coeur de l’api. J’espère néanmoins tenir les délais que je me suis fixé et livrer la version 0.5 avant la fin de ce mois de juin.

Cette livraison portera sur une implémentation basique de CSS avec le support de quelques attributs seulement. Je n’ai pas encore pris de décision définitive pour la configuration du layout. Ce qui est certain est qu’il sera finalement possible de le configurer dans le fichier xml, mais je ne suis pas sûr de vouloir ajouter une propriété non standard à CSS.

J’avais un temps envisagé d’ajouter une balise <layout>, mais à bien y réfléchir cela me poserai un problème. J’ai en effet l’intention d’implémenter XPath pour permettre d’explorer le modèle. Or permettre de récupérer des valeurs de type différent apporterai un niveau de complexité supplémentaire. Je réserve donc cette possibilité à une future release.

Après l’implémentation des CSS, la prochaine étape est la possibilité de définir le modèle des composants complexes comme JTree ou JTable. Là encore, je n’utiliserai pas de balise comme cela se fait avec les tableaux HTML. La définition du modèle se fera dans un premier temps avec un format de fichier texte du type CSV, puis avec un format XML dans une release ultérieure.

Implémentation du pattern IoC

J’ai eu le temps dans le train de réfléchir à quelques problèmes qui s’annoncent dans l’évolution à venir de Swinger. Jusqu’à présent, j’ai laissé de côté les composants complexes de Swing tels que les JTree ou encore les JTable. La raison est que cela nécessite de pouvoir spécifier des valeurs à insérer dans le model comme dans le cas des tables en HTML. J’avais commencé à introduire une balise <item> qui était utilisée pour les JList, mais je suis finalement revenu en arrière car l’approche n’était pas la bonne. Les items ne font pas partie de la couche Vue mais de la couche Model. Il n’était donc pas judicieux de traiter communément ces deux types d’élément.

La solution que j’adopterai du point de vue du langage sera l’introduction des namespaces. Ils permettront d’identifier les différentes couches de l’api Swing. Du point de vue de l’implémentation, je suis toujours confronté à la nécessité de différencier les traitements associés à ces couches. Pour cela, j’adopterai une implémentation simplifiée du pattern Inversion of Control.

Prenons comme hypothèse de départ que vous êtes en présence d’une architecture dans laquelle l’implémentation d’une responsabilité varie selon le type de composant passé en paramètre.

Plutôt que d’implémenter la responsabilité dans une seule méthode avec des vérifications de casting, je dispatch la responsabilité dans des méthodes différentes selon le type d’objet à traiter, et je délègue l’appel de la méthode idoine au niveau des composants subalternes.

Typiquement, l’implémentation sera celle-ci :

public class Child1 implements IoC {
    @Override
    public void delegate(Parent parent) {
        parent.method1();
    }
}

public class Child2 implements IoC {
    @Override
    public void delegate(Parent parent) {
        parent.method2();
    }
}

Cette approche me permettra de conserver le caractère modulaire de Swinger. Tout type de composant pourra être ajouté à un parent, ça sera le composant fils qui déterminera de quel manière il sera ajouté à son parent. Actuellement, seule la méthode Container.add() est utilisée. Avec cette nouvelle architecture, il sera même possible d’ajouter un layout à un conteneur grâce à une balise. Je rappelle que c’est ce problème qui m’avait amené à l’origine à implémenter CSS. Je n’ai pas pour autant l’intention d’abandonner CSS car je pense que cela apportera une plus grande simplicité dans la création d’IHM.

Implémentation d’un modèle CSS

J’ai presque terminé de développer mon modèle CSS. Il me manque néanmoins deux parties importantes, la distinction entre les différents type de valeurs : valeurs spécifiées, calculées et réelles, ainsi que le traitement des différents type de sélecteurs.

En revanche, l’héritage et la cascade sont entièrement implémentées, il ne me reste plus qu’à terminer quelques tests unitaires. C’est la classe CSS2EngineImpl qui a la responsabilité de la cascade et de l’héritage. Elle collabore avec les classes StyleRule.SelectorMessenger et Value pour le calcul de la spécificité des sélecteurs et de la prévalence des valeurs dans l’ordre de la cascade.

La réalisation des tests d’intégration prendra plus de temps car il me faut encore raccorder le parser CSS avec le modèle CSS. Je pense que je me contenterai d’une implémentation élémentaire du DOM en ne définissant que les méthodes qui sont effectivement appellées.

Enfin, la partie qui s’annonce la plus longue est la plus rébarbative est le support des divers propriétés CSS. Je me contenterai dans un premier temps des propriétés basiques comme la couleur, les dimensions et la position des composants. J’ajouterai une propriété non standard : layout, puisque c’est pour cette raison que j’ai implémenté le support de CSS.

Lorsque j’aurai terminé ces différents points, je publierai la version 0.5, si tout se déroule bien dans le courant du mois de juin.

Internet est-il cassé ?

C’est devenu la grande question du jour. La constatation de base est qu’Internet n’a pas été prévu pour supporter toutes les applications qu’il accueille actuellement. Les problèmes soulevés sont en grande partie liée à la sécurité des divers protocoles applicatifs, qu’il s’agisse de dns, https, etc…mais aussi des protocoles bas niveau sur lesquelles sont basés toute l’architecture des réseaux modernes comme tcp/ip.

Nous pouvons distinger deux catégories de protocoles. Ceux qui n’ont pas pris en compte les questions de sécurité, on pense en particulier à dns et http entre autre. Parmis les protocoles qui remontent au-delà des orgines du Web, tcp/ip non plus n’a pas été conçu dans le but de garantir l’identité de ses usagers mais de garantir la robustesse des canaux de communication. Puis il y a ceux qui sont venus se juxtaposer aux protocoles existants dans le but de pallier à leurs défaillances en terme de sécurité, je pense en particulier à https, mais aussi à des protocoles plus sensibles comme ssh, utilisé dans le monde professionnel.

Le problème est que ces protocoles additionnels sont tous des protocoles applicatifs qui se placent au-dessus des protocoles réseau comme tcp/ip. Ils ne résovent que partiellement les failles inhérantes à l’architecture du réseau. D’autant plus partiellement que la sécurité des protocoles modernes utilisent des systèmes de cryptage assymétrique dont le fondement repose sur la faiblesse supposée des moyens de calcul de l’attaquant. Ce fondement n’est justifié que si le protocole de cryptage est parfaitement robuste, ce qui n’est jamais le cas dans la réalité. Autre problème, l’authentification par mot de passe présente une limite humaine quant à la longueur et la complexité des mots de passe, tandis que les moyens de calcul des attaquants augmentent régulièrement selon la loi de Moore.

Alors, Internet est-il cassé ?

Tout d’abord, nous devons bien distinguer les usages d’Internet, parmis lesquels le Web ou la messagerie, d’Internet lui-même. Le changement d’architecture d’Internet ne devrait théoriquement pas impacter les usages qui en sont fait.

Maintenant que cette distinction est posée, il faut bien admettre que les problèmes de sécurité sont de plus en plus préoccupant ou du moins brident les usages d’internet. Malheureusement, aucun système ne peut garantir une fiabilité à 100%. Cette loi est bien connue des informaticiens, elle a été énoncée et prouvée par Alan Turing dans les années 30. Plus précisément, cette loi énonce qu’il est impossible de prévoir si et quand un algorithme complexe s’arrêtera. En clair, il est impossible de savoir si un problème posé sera un jour résolu.

Il est intéressant de noter l’approche révolutionnaire, pour ne pas dire nihiliste des américains qui tend à ignorer l’énoncé de Turing, et l’approche progressiste des européens qui considère que conserver l’architecture existante présente l’avantage de déjà en connaître les principales failles (sans savoir néanmoins si nous pourrons les colmater).

Pourquoi choisir Linux

Pour beaucoup de monde, Linux n’évoque pas grand chose, tout comme la notion de système d’exploitation. Répondre à cette question ne m’a pas paru évidente au premier abord, tant ce choix s’impose aujourd’hui naturellement dans mon esprit. De la même manière que les utilisateurs des Windows sont attachés à un système qu’ils maîtrisent suffisament bien pour leur usage quotidien, seule un innovation majeure me ferait revenir vers Windows.

Quand je repense aux choix et aux décisions qui m’ont fait franchir le pas, c’est indiscutablement parce que je m’intéresse à l’informatique. Je le répète souvent à mes amis, Linux est un système d’exploitation qui ne convient qu’aux personnes qui sont prêt à consacrer du temps à bidouiller leur machine. Un système comme Ubuntu, celui que j’utilise sur mon ordinateur personnel, est réputé pour sa simplicité d’installation et d’utilisation. Il n’en reste pas moins que dès que l’on sort des sentiers battus, il faut s’en remettre à la fameuse et redoutée ligne de commande.

J’ai maintenant 3 ans d’ancienneté en tant qu’utilisateur Linux, et avec le recul, je dirais que ce qui me fait conserver Linux plutôt que de revenir vers Windows est d’abord la mauvaise réputation de Vista, mais aussi le sentiment d’appartenir à une communauté animée par une volonté d’ouverture de la majorité de ses membres. Je dois néanmoins avouer que je ne participe pas activement à cette communauté et que ce sentiment d’appartenance est donc quelque peu usurpé.

La question se posera de nouveau à moi puisque je compte acquérir prochainement un ordinateur portable qui sera très certainement doté de Vista par défaut. Le choix sera de garder Windows ou bien d’installer Linux sur mon nouveau portable. Je pense que je choisirai d’installer Linux et de le conserver si je ne rencontre pas trop de difficulté avec le wifi.

Choix du modèle CSS

Cet article fait suite aux articles précédent :

J’ai finalement décidé de ne pas utiliser le moteur de CSS de batik. Plusieurs raisons m’ont amené à cette décision. Tout d’abord, batik n’implémente pas l’héritage, mais seulement la cascade, il revient donc au client de le faire. Mais ce qui m’a le plus dérangé, c’est le caractère obscure de l’api. Cette librairie est très difficile à comprendre, mal documentée pour la partie CSS et je dirais même mal conçue.

Un exemple concret est que le constructeur de CSSEngine prend 13 valeurs en argument. Oui vous avez bien lu, treize !!! Inévitablement, il est difficile de comprendre le rôle de chacun de ces arguments.

Il existe par ailleurs ce qui me semble être des incohérences. Par exemple, lorsqu’on appelle la méthode getCascadedStyleMap(CSSStylableElement,String), celle-ci cherche à récupérer les valeurs actuelles des attributs que l’on veut justement initialiser. Sans doute y a-t-il une logique dans ce mécanisme, mais elle m’échappe. Le seul cas de figure où il serait nécessaire d’y accéder serait le support des sélecteurs d’attributs, mais ce n’est pas le cas ici. Autre étrangeté, cette méthode, qui est censée être appelée après avoir parsé la feuille de style, accède à nouveau au parser CSS. Cela signifie que le modèle de la CSS est incomplet ou incohérent.

En outre, certains indices me laissent penser que les performances du moteur de style doivent être désastreuses.

Pour toutes ces raisons, je préfère implémenter moi-même le moteur de CSS. Je me baserai sur la spécification DOM-Level-2-Style pour la définition du modèle CSS. Néanmoins, je ne respecterai pas l’implémentation de cette spécification (org.w3c.dom.css) au pied de la lettre, car là encore, j’ai relevé des incohérences. La spécification précise clairement que le modèle ne doit pas donner accès aux valeurs dites “spécifiée” ou “réelle”, mais seulement aux valeurs “calculée”. Ce qui signifie que les instances de CSSPrimitiveValue sont des valeurs calculées puisqu’elles sont obtenues à partir du modèle. Or cette même spécification précise que les valeurs calculées doivent être accessibles en mode “read-only” tandis que l’interface CSSPrimitiveValue expose des setters.

Le moteur de style sera applicable à tout modèle XML. J’ai donc dors et déjà commencé à implémenter un modèle XML standard. Mais je me suis lancé dans une approche expérimentale. En effet, l’api swing implémente déjà un modèle qui repose sur le pattern Composite. Implémenter un modèle parallèle obligerait donc à synchroniser ces deux modèles avec toutes les difficultés que cela entraîne. Sans compter les problèmes de fuite de mémoire.

Pour résoudre ces inconvénients, j’ai défini un pattern que j’appellerai Messenger.

Messenger est un croisement des patterns Adapter et Singleton. Il consiste à présenter au client l’interface qu’il attend, comme dans le cas d’Adapter, mais cette interface est implémentée par un Singleton, ce qui évite les fuites de mémoire et évacue les problèmes de synchronisation. L’inconvénient majeur de ce pattern est qu’il doit être utilisé avec beaucoup de précaution. En particulier, les instances de Messenger ne doivent être référencées que par des variables dont la portée est strictement limitée à la méthode qui les manipule. Si on a besoin de conserver une référence, celle-ci doit pointer sur la valeur véhiculée par le Messenger, et non sur le Messenger lui-même. En outre, Messenger n’est pas adapté à un context multi-thread.

Pour l’instant, je souhaite enrichir fonctionnellement le framework Swinger, mais je consacrerai une release à l’optimisation des performances. Le pattern Messenger offre un potentiel de gain assez important en particulier au niveau des parsers CSS et XML.

Il me reste dorénavant à implémenter le modèle de CSS ainsi que l’algorithme de la cascade et de l’héritage. Pour cela, il me faudra étudier en détail la spécification CSS2. Je vous ferai part de mes réflexions sur ce sujet dans un prochain billet.

Le choix de mon parser CSS

J’ai décidé d’implémenter les CSS dans mon projet swinger. Le W3C propose une interface (SAC) écrite en Java qui est implémentée par deux API, Flute et Batik.

Flute est une implémentation basique de SAC, il s’agit d’un simple parser, tandis que Batik est un projet beaucoup plus vaste qui est en fait un toolkit pour le support du format SVG.

Il n’existe que très peu de documentation sur ces deux parsers, j’ai donc commencé par étudier le code source de ces deux API. Le parser de Flute repose sur un ParserTokenManager qui a la responsabilité d’extraire les éléments gramaticaux du fichier CSS. Dans l’api Batik, ce role est dévolu à la classe Scanner. Dans les deux cas, le parser est associé à un DocumentHandler qui reçoit les évènements qui surviennent lors du parcours du fichier CSS.

J’ai effectué des tests de performance pour comparer les deux parsers, et il ressort que le parser de Batik est 40 à 50% plus rapide que celui de Flute. Cette différence ne me surprend pas vraiment car le parser de Flute a été généré avec JavaCC. Il s’agit d’un outil extrêmement puissant mais qui a l’inconvénient de produire un code absolument dégueulasse.

J’ai également comparé les évènements produits par les deux parsers. Et là je suis tombé sur un os. Toute la puissance du langage CSS repose sur les sélecteurs. Tant que l’on utilise des sélecteurs élémentaires telles que des id, des classes ou des élements xml, il n’y a aucun problème. Mais dès que l’on introduit un peu de complexité en jouant sur les opérateurs, on constate des différences d’interprétation. Je ne maîtrise pas suffisament les CSS pour savoir lequel des parsers est en faute.

Il s’agit d’un problème assez sérieux, mais pas rédhibitoire. La nécessité de standardiser les usages du web vient du fait qu’il existe une grande diversité de navigateurs. Firefox, Opera, Safari, Chrome, Internet Explorer, pour ne citer que les plus connus. Dans mon cas, la nécessité de respecter les standards n’est dicté que par le soucis de bien faire. Néanmoins, compte tenu de cette différence d’interprétation, il est évident qu’il sera nécessaire de modifier le code source et qu’il ne sera pas possible de considérer le parser comme une simple boîte noire.

Cette dernière considération me fait choisir le parser Batik, car l’utilisation de JavaCC dans le cas de Flute me parait rendre l’analyse et la correction de bugs trop complexe, sans compter qu’il n’est pas totalement exclu que JavaCC soit lui-même à l’origine de cette différence d’interprétation.

Maintenant que le choix de mon parser est fait, je dois maintenant décider jusqu’à quel point je souhaite utiliser la librairie Batik. En effet, Batik propose un modèle de CSS complet accompagné d’un moteur qui implémente l’héritage et la cascade. Mais cela reste à vérifier. Je vous ferai partager mes réflexions à ce sujet lors d’un projet billet.

Page suivante »