Si vous travaillez sur la rĂ©alisation de sites web, vous avez surement dĂ©jĂ dĂ» mettre en place une couche SSL, pour chiffrer certaines donnĂ©es sensibles, comme le mot de passe des internautes. Au delĂ du fait que la gĂ©nĂ©ration et l’utilisation des certificats non signĂ©s (pour le dev et les tests) reste relativement douloureuse et peu intuitive, il est possible de rencontrer une multitude d’autres problèmes. L’idĂ©e de ce post vient de ma volontĂ© de partager une situation oĂą un problème liĂ© au SSL est apparu. J’y explique le problème, sa cause, ainsi que les diffĂ©rentes Ă©tapes de sa rĂ©solution. J’espère qu’il vous sera utile, et qu’il vous permettra d’Ă©viter certains pièges vicieux dont j’ai Ă©tĂ© la victime.
Le contexte technique du projet est relativement banal : un portail (Liferay) avec plusieurs portlet externes (webapps), un sytème de SSO – Single Sign On – (CAS), et un frontal faisant office de firewall et load-balancer (par exemple un apache tomcat).
Pour des raisons fonctionnelles, nous avons du intĂ©grer le SSO (CAS) dans une iFrame se trouvant sur le portail. Ainsi, l’internaute reste en permanence sur le portail, est n’est pas redirigĂ© vers une page tierce du SSO. Bien entendu, il reste possible de brancher d’autres applications sur ce SSO, et ce composant reste donc tout Ă fait justifiĂ©.
Bien que tout fonctionnait correctement, nous avons dĂ©cidĂ© de mettre en place une couche SSL sur le portail, pour toutes les pages d’authentification, et les pages contenant des donnĂ©es utilisateur (crĂ©ation de compte, mise Ă jour du profil, etc). Après quelques tests, nous avons remarquĂ© que l’on perdait parfois la session utilisateur en passant de HTTP Ă HTTPS. Concrètement, après s’ĂŞtre connectĂ© via une page en HTTPS, on pouvait naviguer tranquillement sur le site, sur toutes les adresses en HTTP. Par contre, dès que l’on passait en HTTPS, l’utilisateur Ă©tait dĂ©connectĂ©. En repassant sur des pages en HTTP, on retrouvait notre compte, sans aucune redirection vers le CAS. Nous avions donc ici 2 informations interessantes :
De plus, ce problème se produisait seulement sur notre plateforme de staging (avec firewall et load-balancer), et non sur nos environnements d’intĂ©gration (pas de load-balancer). Le problème semblait donc liĂ© au load-balancing. Après dĂ©sactivation de l’une des 2 machines du cluster… le problème persitait ! Nous Ă©tions donc dans un cas oĂą un problème alĂ©atoire se produit seulement sur une plateforme load-balancĂ©e, mĂŞme avec dĂ©sactivation du balancing. IncomprĂ©hensible…
RĂ©solution du problèmeAprès plusieurs manipulations infructueuses, nous sommes arrivĂ©s Ă la conclusion que le jsessionId envoyĂ© en HTTP et HTTPS n’Ă©tait pas le mĂŞme. Cela semble logique, mais nous avions dĂ©jĂ essayĂ©, sans succès, plusieures configurations diffĂ©rentes du portail, pour par exemple forcer l’utilisation de la mĂŞme session en HTTP et HTTPS, ou bien rĂ©pliquer les paramètres d’une session Ă l’autre. Lorsque que l’on regardait les cookies du navigateur, nous avions 2 jsessionId :
Nom Domaine Path Sécurisé JSESSIONID my.com / Non JSESSIONID sub.my.com / OuiBizzare.
Le site est accessibles par l’url sub.my.com, mais le portail réécrit les cookies pour les mettre sur my.com, afin que tous les sous-domaines utilisent la mĂŞme session. Si le second cookie venait du portail, il devrait aussi ĂŞtre changĂ© de domaine. Ce n’est Ă©videment pas le cas. Au niveau du serveur, les autres webapps que nous avons sont :
En fait, le problème vient d’un paramètre du connecteur tomcat. En effet, il existe un attribut “emptySessionPath”, mis Ă “true” par Liferay. Cela permet de forcer le “path” des cookies Ă “/”. C’est très utile pour les portlet, car elles partagent le mĂŞme jsessionId, mais… ce n’est pas ce que l’on veut pour le CAS. Comme le portail fonctionne majoritairement en HTTP, la session HTTPS est créée par le CAS, et non par le portail. A cause de la configuration du portail, le cookie du cas est configurĂ© avec un “path” Ă “/” et non Ă “/cas-server”. Du coup, lorsque le portail passe en en HTTPS, il utilisae la session de la webapp CAS, et non celle du portail. L’utilisateur perd donc sa session. Quand on revient en HTTP, il la retrouve, car on utilise de nouveau le bon jsessionId. Nous avons donc mis le CAS sur un autre serveur tomcat, pour qu’il ait ses propres cookies, non modifiĂ©s. On dirait que ça fonctionne.
CQFD ? Par vraiment, malheureusement. Alors que nous pensions avoir rĂ©solu le problème, il est rĂ©apparu après quelques tests ! Pourtant, l’explication prĂ©cĂ©dant se tient parfaitement. Il se trouve que nous avions oubliĂ© un paramètre important : le load-blancing. Nous l’avions mis de cotĂ© car le problème se produisait mĂŞme avec une seule machine active. En fait, le calcul d’affinitĂ© sur le load-balancer se fait par le jsessionId. Ainsi, si vous fournissez toujours le mĂŞme jsessionId, vous tomberez toujours sur la mĂŞme machine ? Toujours ? Eh non, justement ! Suivant que la requĂŞte soit sĂ©curisĂ©e ou non, un mĂŞme identifiant ne renverra pas sur la machine. C’est Ă©videment un problème de configuration du load-balancer. Après quelques tests, tout fonctionne de nouveau.
ConclusionBien que les explications du problème soient relativement simples, il n’a vraiment pas Ă©tĂ© facile Ă identifier, car il s’agissait en fait de deux problèmes imbriquĂ©s :
La correction de l’un ne faisait pas disparaitre le problème (ce qui poussait Ă penser que cette correction Ă©tait fausse), mais Ă©tait obligatoire. Dans un cas de test normal, on essaie de modifier le moins possible la configuration orginale, pour ne pas inclure d’autres facteurs Ă risque et de faux comportements dans la rĂ©solution du problème. Pour rĂ©soudre celui-lĂ , il ne fallait donc pas procĂ©der comme cela, contre toute attente.
Voilà donc quelques conseils pour débugger ce type de cas :
Si vous avez des problèmes similaires, n’hĂ©sitez pas Ă les partager ici !
Le JDK de Sun/Oracle propose plusieurs outils et APIs pour monitorer une jvm locale et ceci, depuis le JDK 6, sans avoir besoin de configurer cette jvm de manière particulière (enfin, ca c’est dans les cas simples
nous verrons qu’il faut parfois ajouter une petite option)
Le JDK propose deux utilitaires avec une interface graphique : JConsole et JVisualVM. Le premier permettant principalement d’accĂ©der facilement aux MBeans JMX exposĂ©s par la JVM. Le deuxième Ă©tant beaucoup plus complet, en particulier si vous utilisez les plugins en tĂ©lĂ©chargement optionnel.
Il propose aussi des outils en ligne de commande :
Tous ces outils sont présents dans le répertoire bin du JDK.
Ces outils sont soumis Ă Â quelques restrictions :
Sous windows, je rencontre actuellement des problèmes lorsque je me connecte Ă un serveur Ă distance (via Remote Desktop) : gĂ©nĂ©ralement, il faut toujours au moins que je me connecte en mode admin (mstsc.exe /admin (ou /console dans les anciennes versions) ) pour que les outils de monitoring puisse fonctionner. Mais cela ne suffit pas toujours …
Accès programmatiquesCes outils sont très intĂ©ressants, mais il est parfois nĂ©cessaire d’accĂ©der Ă des mĂ©triques particulières d’une jvm ou de l’application que la jvm hĂ©berge. Ou ils peuvent tout simplement ne pas fonctionner dans certains cas particuliers.
Dans la suite de ce post, je vais me focaliser sur les diffĂ©rentes façons d’accĂ©der au serveur jmx des jvms en local sans avoir Ă configurer l’accès distant : qui peut se rĂ©vĂ©ler complexe si l’on veut que cet accès reste sĂ©curisĂ© ( tout est dĂ©drit ici : http://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html )
L’API AttachL’utilisation de l’API Attach pour se connecter Ă un serveur jmx en local est dĂ©crit sur la mĂŞme page web que l’accès distant :
http://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html#gdhkz
Cette api permet essentiellement :
Cette dernière fonctionnalitĂ© permet en particulier de charger l’agent JMX si il n’est pas dĂ©jĂ lancĂ©. On peut lancer l’agent jmx au dĂ©marrage de la jvm via l’option -Dcom.sun.management.jmxremote. A partir du JDK 6, c’est grâce Ă l’API Attach, que cette option n’est souvent plus nĂ©cessaire : l’agent peut ĂŞtre chargĂ© Ă la demande comme montrĂ© dans l’exemple ci-dessous.
(ce programme nécessite que le jar tools.jar présent dans le répertoire lib du JDK soit dans le classpath)
package jmx;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.List;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
public class JmxAttachAPI {
public static void main(String[] args) throws Exception {
new JmxAttachAPI().dotIt();
}
static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress";
private void dotIt() throws Exception {
System.out.println("Available local vms : ");
List vmdList = VirtualMachine.list();
for(VirtualMachineDescriptor vmd : vmdList) {
System.out.printf("%s : %s%n", vmd.id() , vmd.displayName());
}
// Choose one vm :
System.out.println();
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String pid = "";
while(pid.length() == 0) {
System.out.println("vm id ? ");
pid = stdin.readLine();
}
System.out.println();
System.out.printf("Connecting to jvm : %s%n",pid);
VirtualMachine vm = VirtualMachine.attach(pid);
String connectorAddress = null;
try {
// get the connector address
connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
// no connector address, so we start the JMX agent
if (connectorAddress == null) {
System.out.println("Agent not Started, loading it ...");
String agent = vm.getSystemProperties().getProperty("java.home") +
File.separator + "lib" + File.separator + "management-agent.jar";
vm.loadAgent(agent);
// agent is started, get the connector address
connectorAddress =
vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
} else {
System.out.println("JMX Agent already started !");
}
} finally {
vm.detach();
}
System.out.println();
System.out.printf("Connecting to jmx server with connectorAddress : %s%n",connectorAddress);
// establish connection to connector server
JMXServiceURL url = new JMXServiceURL(connectorAddress);
JMXConnector connector = JMXConnectorFactory.connect(url);
MBeanServerConnection con = connector.getMBeanServerConnection();
RuntimeMXBean runtime = ManagementFactory.newPlatformMXBeanProxy(
con, ManagementFactory.RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
System.out.printf("Extracted classpath : %s%n",runtime.getClassPath());
}
}
Et voici un exemple de son exécution :
Available local vms : 8372 : org.apache.catalina.startup.Bootstrap start 2108 : jmx.JmxAttachAPI vm id ? 8372 Connecting to jvm : 8372 Agent not Started, loading it ... Connecting to jmx server with connectorAddress : service:jmx:rmi://127.0.0.1/stub/rO0ABXNyAC5qYXZheC5tYW5hZ2VtZW50LnJlbW90ZS5ybWkuUk1JU2VydmVySW1wbF9TdHViAAAAAAAAAAICAAB4cgAaamF2YS5ybWkuc2VydmVyLlJlbW90ZVN0dWLp/tzJi+FlGgIAAHhyABxqYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN002G0kQxhMx4DAAB4cHc6AAtVbmljYXN0UmVmMgAADzE2OS4yNTQuMTQxLjIwNAAA1Qkf/eH4sQVkBOeL7SsAAAE1TnnPy4ABAHg= Extracted classpath : C:\products\apache-tomcat-6.0.32\bin\bootstrap.jar
Après avoir listĂ© les jvms disponibles, ce programme s’attache Ă la jvm sĂ©lectionnĂ© et regarde si l’agent jmx est dĂ©jĂ chargĂ© (en cherchant la propriĂ©tĂ© com.sun.management.jmxremote.localConnectorAddress)
Si il ne la trouve pas, il demande Ă la jvm de charger cet agent (l’agent est dans le jar management-agent.jar prĂ©sent dans le rĂ©pertoire jre/lib/ de la jvm cible)
Notez que la JConsole fait exactement la mĂŞme chose : elle l’indique d’ailleurs dans la fenĂŞtre de connexion en affichant “Note : The management agent will be enabled on this process” sous la liste des process disponibles lorsque le process sĂ©lectionnĂ© n’a pas encore l’agent JMX chargĂ©
Une fois l’adresse jmx locale rĂ©cupĂ©rĂ©e, l’API Attach a terminĂ© son travail. L’api JMX prend ensuite le relai.
Ici on se contente d’extraire le classpath de la JVM cible. Mais l’ensemble des MBeans JMX de la JVM sont maintenant accessibles : que ce soit les MBeans de la JVM ou les MBeans que l’application aurait exposĂ© dans le serveur JMX de la JVM
L’API MonitoredHostDans certains cas, l’API Attach ne fonctionne pas … (lorsque la JVM est exĂ©cutĂ©e par un service windows en particulier ; du moins dans l’environnement oĂą je travaille actuellement)
JConsole utilise une 2ème API pour lister les jvms et extraire des infos : sun.jvmstat.monitor.MonitoredHost. Il utilise aussi une autre api bas niveau sun.management.ConnectorAddressLink : pour rĂ©cupĂ©rer l’adresse JMX local
La limitation principale de cette api est qu’elle n’est pas capable d’activer l’agent JMX s’il ne l’est pas dĂ©jĂ . Il faut donc l’avoir activer explicitement via l’option -Dcom.sun.management.jmxremote (mĂŞme avec un jdk 6 ou plus)
Sous rĂ©serve que l’agent jmx soit activĂ©, on peut donc accĂ©der au serveur JMX de cette façon :
(ce programme, très fortement inspiré du code source de la JConsole, nécessite aussi que le jar tools.jar soit dans le classpath)
package jmx;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;
import sun.management.ConnectorAddressLink;
public class JmxMonitoredHost {
public static void main(String[] args) throws Exception {
new JmxMonitoredHost().doIt();
}
private void doIt() throws Exception {
MonitoredHost localMonitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));
Set activeVms = localMonitoredHost.activeVms();
Map pidToAddress = new HashMap();
System.out.println("Available local vms : ");
for(Integer vmId : activeVms) {
String pid = vmId.toString();
try {
MonitoredVm localMonitoredVm = localMonitoredHost.getMonitoredVm(new VmIdentifier(pid));
String commandLine = MonitoredVmUtil.commandLine(localMonitoredVm);
boolean attachable = MonitoredVmUtil.isAttachable(localMonitoredVm);
String connectorAddress = ConnectorAddressLink.importFrom(vmId.intValue());
System.out.printf("%5s %30s %4s%n",pid,commandLine,attachable);
pidToAddress.put(pid,connectorAddress);
localMonitoredVm.detach();
} catch (Exception e) {
e.printStackTrace();
}
}
// Choose one vm :
System.out.println();
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String pid = "";
while(pid.length() == 0) {
System.out.println("vm id ? ");
pid = stdin.readLine();
}
// get the connector address
String connectorAddress = pidToAddress.get(pid);
System.out.println();
System.out.printf("Connecting to jmx server with connectorAddress : %s%n",connectorAddress);
// establish connection to connector server
JMXServiceURL url = new JMXServiceURL(connectorAddress);
JMXConnector connector = JMXConnectorFactory.connect(url);
MBeanServerConnection con = connector.getMBeanServerConnection();
RuntimeMXBean runtime = ManagementFactory.newPlatformMXBeanProxy(
con, ManagementFactory.RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
System.out.printf("Extracted classpath : %s%n",runtime.getClassPath());
}
}
L’API LocalVirtualMachine de la JConsole
La JConsole a implémenté sa propre api de découverte au dessus des apis décrites ci-dessus : sun.tools.jconsole.LocalVirtualMachine ( On pourra trouvé son code source ici par exemple : http://javasourcecode.org/html/open-source/jdk/jdk-6u23/sun/tools/jconsole/LocalVirtualMachine.java.html)
PlutĂ´t que d’utiliser ces deux Apis directement, il est donc plus simple d’utiliser LocalVirtualMachine
Cela nous donne ceci :
( ce programme nécessite tools.jar ET jconsole.jar dans la classpath pour fonctionner ) :
package jmx;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.Map;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import sun.tools.jconsole.LocalVirtualMachine;
public class JmxJConsole {
public static void main(String[] args) throws Exception {
new JmxJConsole().doIt();
}
private void doIt() throws Exception {
Map allVirtualMachines = LocalVirtualMachine.getAllVirtualMachines();
System.out.println("Available local vms : ");
for(Integer vmId : allVirtualMachines.keySet()) {
LocalVirtualMachine vm = allVirtualMachines.get(vmId);
System.out.printf("%10s %50s %s%n",vmId,vm.displayName(),vm.isAttachable());
}
// Choose one vm :
System.out.println();
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String pid = "";
while(pid.length() == 0) {
System.out.println("vm id ? ");
pid = stdin.readLine();
}
// get the connector address
LocalVirtualMachine vm = allVirtualMachines.get(new Integer(pid));
// load jmx agent if necessary/possible :
vm.startManagementAgent();
String connectorAddress = vm.connectorAddress();
System.out.println();
System.out.printf("Connecting to jmx server with connectorAddress : %s%n",connectorAddress);
// establish connection to connector server
JMXServiceURL url = new JMXServiceURL(connectorAddress);
JMXConnector connector = JMXConnectorFactory.connect(url);
MBeanServerConnection con = connector.getMBeanServerConnection();
RuntimeMXBean runtime = ManagementFactory.newPlatformMXBeanProxy(
con, ManagementFactory.RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
System.out.printf("Extracted classpath : %s%n",runtime.getClassPath());
}
}
Conclusion
Avec ce dernier code, vous devriez être paré pour vous connecter en local aussi bien que JConsole et extraire vos propres métriques ou lancer des opérations de diagnostique (au hasard : lancer un heap dump) via les Apis JMX de la jvm
Toutefois mĂŞme la JConsole n’arrive pas tout le temps Ă se connecter ou Ă voir une jvm local.
En cas de soucis, voici au moins trois prĂ©-requis qui m’ont Ă©tĂ© nĂ©cessaire rĂ©cemment :
Here is a best of posts of this week on project management and agile
You're a Project Manager - Not Superman
Coaching Agile Teams http://j.mp/wYWIy5
How to Run a Job Interview As a Project Manager http://j.mp/yR0guC
The No-Drama PM http://j.mp/xjLpQs
You're a Project Manager - Not Superman http://j.mp/zaelUz
Make Good PM Practices Work for You http://j.mp/wKKwbR
Some good tips about change management and success on your projects
Coaching Agile Teams http://j.mp/wYWIy5
Use Bad Situations To Make Good Project Management Changes http://j.mp/zGTcf0
Stakeholders and the Cost of Change http://j.mp/y9i7db
Bidding to Win the Project http://j.mp/yane9Y
How to identify, prevent, and recover from project failure http://j.mp/waCBH3
Turn Down Projects but Retain the Customers – Part 2 http://j.mp/zWOu0W
Dealing with Agile can be easy
Coaching Agile Teams http://j.mp/wYWIy5
Agile Scrum vs. Change Management http://j.mp/zOC69u
Specializing Generalist http://j.mp/Aej4Df
Agile + Earned Value http://j.mp/wjPWuW
Critical Chain, Agile, and Program Management http://j.mp/y8auxt
Budgeting a Scrum Project in a Fluid Environment http://j.mp/A4osS8
Reasons for Having a Sprint Zero in Scrum http://j.mp/xbY2CZ
“Where Should I Start Looking….” http://j.mp/A2sme1
@_sara_em : http://twitter.com/#!/_sara_em
Ask your questions about project, agile and quality management on Ask.Quasutra : http://ask.quasutra.com/
J'avais en "terminale C" un prof d'histoire extraordinaire.
J'ai oublié son nom. Il était royaliste. C'était dans les années 70. Il nous parlait - déjà ! -du groupe Bilderberg. Davos à côté c'est la main droite du prestidigitateur qui vous amuse pendant que la main gauche fait le tour.
Autant que je me souvienne, le XXème siècle était au programme.
Ce prof nous avait expliqué la situation qui devait conduire à la 2ème guerre mondiale en quelques secondes. Il maniait l'art du signe.
Tout va très bien... jusqu'à la 2ème guerre mondiale.
Le problème du déniLe déni...
L'un des dénis porte sur l'intention originelle. L'agilité... avant l'agilité.
Au départ (avant 2001), c'est une user story, une développeur story.
Un autre déni : la situation réelle des personnes dans les équipes, agiles ou pas. Une question simple : avons-nous le temps de bien faire ce que nous avons à faire ? Vous voyez c'est très simple comme question.
Agile, un golem ?
(Illustration : Philippe Semeria)
Parfois, je me demande si nous n'avons pas créé un monstre.
Entre cette intention originelle, trois + un rôles agiles, et la réalité actuelle, n'y a-t-il pas un hiatus ?
La tentation est grande d'abandonner le mot "agile". Le sens (ou la direction, la voie si vous préférez) étant désormais cette lucre-agilité ou agile canada dry que certains dénoncent.
...
Et bien... Non !
Si l'agilité est aujourd'hui une vielle idée (11 ans déjà !) elle reste une belle idée qui mériterait évidemment un peu de cosmétique : flux tiré (sous jacent à XPv2 en 2004), devops...
La voie commence là où nous sommes. Elle fonctionne à tous les niveaux. La méthode est l'action. Le temps, maintenant. Dan Millman
Les bonnes nouvelles Auto organisation à l'échelleL'agilité s'installe et les organisations se prennent l'agilité dans le PIF (Paysage Informatique Français).
De nombreux groupes s'organisent à l'échelle locale.
Non seulement les groupes locaux sont actifs, mais des collaborations voient le jour entre plusieurs villes.
DéveloppeursDe plus en plus, via les confs agiles, les "code retreats" et autres dojos, je rencontre des Développeurs qui parlent et vivent le développement comme un véritable métier, simplement. Une certaine fierté teintée d'humilité est en train de naitre. Nous voila 12 ans après aux sources de l'agilité.
Comment participer, être réaliste : quelle capacité réelle de changement dans les organisations, quelle prise de conscience des parties prenantes (Développeurs, Utilisateurs pour l'essentiel) et de leur pouvoir ?
Et être utopique : envisager ce qui n'a pas encore été fait.
Vendredi dernier je donnais une formation « dĂ©couverte de l’agilitĂ© » avec des prĂ©sentations thĂ©oriques sur les origines de l’AgilitĂ© et Scrum, le tout Ă©tayĂ© par 2 jeux percutants, « Artistes et SpĂ©cifieurs » et « Joli Tableau » (tiens il faudra que je vous parle de Joli Tableau prochainement car j’ai plein de photos de ce jeu que je pratique souvent – et un grand merci Ă Xavier Quesada qui l’a inventĂ©
).
Bref, comme lors de toutes les formations, les participants prennent des notes sur leur cahier … et quelle a Ă©tĂ© ma surprise de dĂ©couvrir ce qu’avait fait Sophie sur son cahier (Cf. photo ci-dessous). C’est encore mieux qu’un MindMap car beaucoup plus percutant !
Bien sur, il faut avoir les compĂ©tences graphiques nĂ©cessaires … ce qui est la spĂ©cialitĂ© de Sophie qui est graphiste dans une sociĂ©tĂ© sur Annecy … enfin quoiqu’il en soit j’adore … et cela m’a mĂŞme donnĂ© des idĂ©es pour Agile Grenoble 2012 … chut, secret … Ă suivre …

Photo Sophie Mollard (tous droits réservés)
Agenda :
Rappel de l’offre mobilité OCTO :
OCTO travaille sur la mobilité depuis 3 ans avec une équipe capable d’adresser les projets de l’idée au store (ergonomes, designers, développeurs, experts, architectes) qui permet d’accompagner au mieux ses clients.
OCTO met le focus sur deux types d’activités :
En complément, OCTO propose à ses clients une solution pour distribuer leurs applications en interne, sous forme d’un store privé sur le Cloud : Appaloosa (lien).
Les tablettes : quels usages pour quels enjeux ?
Il s’est vendu cette année plus de tablettes (1,45 millions) que de PC de bureau (1,24 millions) pour les particuliers. 2012 laisse présager 3 millions de tablettes vendues, donc de se rapprocher des ventes de portables (4 millions en 2011)
Pourquoi cet engouement et notamment par les usagers en entreprise ?
Les tablettes présentent de nombreux avantages :
En moyenne les utilisateurs utilisent une tablette plus de 90 minutes quotidiennement : dans le salon le soir, le matin au petit-déjeuner, lors de temps d’attente ou avant de dormir. Ce sont des moments privilégiés pour capter l’attention de l’utilisateur.
L’utilisateur type de la tablette est un homme, d’environ 35 ans, aisé et plutôt geek.
Un support qui capte l’attention, un utilisateur aisĂ©, c’est une excellente opportunitĂ© pour capter le consommateur et pour diffuser ses services en B2C. Ainsi, en quelques mois la SNCF a Ă©coulĂ© plus de 100 000 billets par le biais de son application iPad, en valeur c’est 15% de ses ventes sur applications mobiles.
Le marché des particuliers est donc lancé mais on assiste également à une véritable percée sur le marché professionnel :
En effet le PC fait « écran » entre l’utilisateur et les autres, alors que l’on ne peut pas cacher derrière une tablette. Elle redĂ©finit les contours des usages en entreprise : elle devient un outil propice au partage, Ă la collaboration lĂ oĂą le PC se cantonne dĂ©sormais Ă un outil personnel d’analyse, de rĂ©flexion et de production.
Quelques exemples d’utilisation en contexte professionnel :
Pour tous ces usages la connexion au SI est primordiale.
Les tablettes : quels impacts sur le SI ?
La volonté du top management de moderniser les processus métiers existants et d’intégrer de nouveaux outils  aura un véritable impact sur la conception de nos SI. Regardons ce que changent les tablettes en comparaison des smartphones et des projets sur un PC traditionnel.
Les tablettes sont-elles équivalentes aux smartphones ?
La révolution se trouve en fait  dans le type de projets réalisés. Le périmètre métier n’est plus aussi restreint qu’avec les smartphones (les équipes sont plus larges, les durées de projet plus longues).
Un accent particulier doit être mis sur la qualité, le design et la conception. Une plus grande liberté est rendue possible grâce aux écrans plus grands des tablettes ; écrans conçus comme un mashup.
Il existe des  enjeux propres aux tablettes :
En conclusion : on assiste à une montée en puissance de nouveaux canaux  (webapps HTML5, tablettes, smartphones, demain télés connectées, réfrigérateurs….) et il est impératif de garder la maîtrise du SI par rapport à tous ces nouveaux besoins.
 Table ronde : retours d’expérience de Arval, Corsairfly, Axa et BNP Paribas Fortis
Arval : Sébastien Somchit, Head of Interactive Marketing
Le projet a été lancé mi 2011 et est parti d’une question posée : comment améliorer les relations commerciales ? L’iPad s’est présenté comme un élément efficace face aux clients (accès de qualité à une librairie master de docs références, de façon sécurisée et dans un univers brandé Arval).
Fortis : Yvan Pirenne, Manager Internet & Mobile Banking
L’application easy banking a pour but la gestion quotidienne sur mobile des opérations bancaires..
Axa : Guillaume Lemêle, Directeur Conseil & Services Distribution Internet & Marketing
L’application a pour but d’aider les commerciaux à la vente d’assurance (ou de banque) sur le terrain : documents facilement à portée de main, mise en gestion automatique.
Corsairfly : Antoine De Kerviler, DSI
L’application doit répondre à un enjeu de reporting pour le personnel navigant. Il fallait 15 à 20 jours pour reporter un problème sur un vol. Le but est maintenant de remonter les informations en 24h et de les traiter grâce à une description catégorisée.
Fortis : Très bon marketing Apple (affinité au produit) et les critères de sécurité !
Arval et Corsairfly : des tests ont été menés et l’iPad a répondu aux attentes.
Axa : le parc applicatif est énorme et la communauté de développeurs est très importante.
Axa : à terme un remplacement est envisagé (gain de temps et de praticité en épargnant sur les papiers, les temps de remplissage, de saisie post remplissage…)
Fortis : un remplacement de processus très lourds est envisagé (photocopies, tris, rangements…)
Axa : Un plan B papier est toujours envisageable si le commercial se heurte à la réticence d’un client. Mais dans l’ensemble ils sont majoritairement ok pour jouer le jeu et franchir le pas du numérique.
Fortis : ils semblent satisfaits et les gains escomptés sont à mesurer dans deux types d’action : le conseil et les transactions.
Axa : Les données collectées ne sont pas gardées sur l’iPad mais sur le Cloud et un outil de MDM est présent pour protéger ces données.
Corsairfly : Une liberté assez grande est laissée aux employés pour jouer, tester et s’approprier l’iPad mais un focus est fait sur l’importance de respecter la loi et de faire attention aux vols (aéroport, personnel navigant).
Arval : l’iPad reste un élément statutaire à ce jour. Tout le monde n’en a pas dans l’entreprise mais ça ne durera surement pas à long terme.
Axa : l’iPad est un élément motivant pour les commerciaux : perçu comme un signe de reconnaissance. Mais c’est un outil dont la valeur est intégrée à l’entreprise et qui n’est en aucun cas personnel.
Arval : c’est un projet pilote donc pour le moment les commerciaux sont formés Il faudra ensuite s’adapter (question autour du bring your own device, systématisation… ?)
Corsairfly : il sera démontré individuellement que l’iPad est générateur de valeur
Fortis : il y aura des changements au niveau réseau. Les employés sont les meilleurs ambassadeurs de ce produit (mais il est essentiel de le maîtriser avant d’en être capable donc un effort sur la formation doit être fait)
Axa : il y a 4500 commerciaux et tout va tourner autour de l’iPad. Les applications doivent donc être faciles d’utilisation ; permettant ainsi d’éviter des formations longues, nombreuses et coûteuses.
AXA : plusieurs millions d’euros.
Fortis : Le gros du budget est parti dans couche de services, interaction avec le SI.
Corsairfly : 60K tout compris pour l’application mĂ©tier + 350 € par an de TCO pour l’iPad
Arval : C’est un outil qui n’est pas conçu Ă l’origine pour du B2B. Peu de productivitĂ© et de compatibilitĂ© avec Office. On doit adapter les documents Ă la tablette.
Corsairfly : Les processus d’Apple sont compliquĂ©s : difficile d’avoir un contrat, difficultĂ© liĂ©e au dĂ©ploiement, aux numĂ©ros de carte de crĂ©dit, etc.
Fortis : l’inaccessibilité et la rigidité d’Apple. Nous avons eu de nombreux problèmes pour obtenir une licence, une application en accord avec nos brief et sans beaucoup de possibilités pour interagir.
Fortis : toujours garder l’œil sur le produit final.
Arval : avoir une vision claire de l’objectif à atteindre et intégrer toutes les fonctions clés au projet (IT notamment pour les questions sécurité, synchronisation, data… et le marketing).
Corsairfly : Tester en conditions réelles ! Ce qui permettra un REX des personnes concernées.
Axa : c’est une opportunité pour les DSI de porter l’innovation. Il ne faut pas avoir peur de se tromper, le projet sera enrichi avec les retours d’usage.
Suggestion d'articles :
Les DAO (Data Access Object) ou repository des applications contiennent souvent de l’information importante sur la façon dont les donnĂ©es d’une base doivent ĂŞtre consultĂ©es. Cette information prend la forme d’une logique mĂ©tier qui est encodĂ©e dans un ou plusieurs langages, souvent un langage dĂ©claratif (SQL, HSQL, JPQL, etc.) et un langage impĂ©ratif (Java, Groovy, Scala, etc.).
Tester cette logique d’accès polyglotte peut s’avĂ©rer complexe et lent car ce type de test se prète mal aux techniques classiques de mock et nĂ©cessite plutĂ´t l’Ă©criture de tests d’intĂ©gration qui chargent une partie du contexte rĂ©el d’exĂ©cution. Par consĂ©quent, les tests de cette couche sont parfois dĂ©laissĂ©s, voire abandonnĂ©s.
Cet article se propose de vous montrer comment rĂ©aliser de tels tests, avec un niveau d’isolation suffisant pour la parallĂ©lisation dans un processus multithread, tout en essayant de trouver le meilleur compromis avec le temps d’exĂ©cution de chaque test. Ces tests sont prĂ©sentĂ©s dans une configuration très classique utilisant Spring et JPA/Hibernate.
L’implĂ©mentation utilise une base HSQLDB et quelques bibliothèques pour faciliter l’Ă©criture du code, en essayant de rester aussi lĂ©ger que possible. Les tests sont isolĂ©s pour que vous puissiez activer l’exĂ©cution parallèle du plugin Surefire de Maven au niveau des classes de test. Vous pourrez facilement dĂ©river l’implĂ©mentation nĂ©cessaire Ă isoler vos tests au niveau des mĂ©thodes si vous le souhaitez.
Pour rappel, PostGIS est une extension ajoutant des fonctionnalités géospatiales au systeme de gestion de base de données PostgreSQL, en se basant sur la spécification OpenGIS. Si votre application manipule des repères ou zones géographiques, des objets géométriques ou des distances, c'est donc un outil à ne pas négliger.
Malgré ses 10 ans d'existence (dont 6 en version stable), PostGIS reste très peu utilisé dans les projets Web, souvent à cause de son intégration compliquée au sein des différents frameworks. Nous allons voir ici que ce n'est pourtant pas toujours le cas, en décrivant son installation et son utilisation au sein d'un projet Play ! Framework
Installation & ConfigurationLes consignes ci-dessous se basent sur la distribution Ubuntu 10.04 et sur la version 8.4 de PostgreSQL, mais l'installation varie assez peu pour les autres distributions et/ou versions, des paquets étant disponibles soit nativement, soit sur internet (voir http://trac.osgeo.org/postgis/wiki/... pour plus d'informations).
L'installation se fait grâce à deux paquets :
sudo apt-get install postgis
sudo apt-get install postgresql-8.4-postgis
Une fois ces deux paquets téléchargés, l'installation de PostGIS sur votre machine est terminée. Néanmoins, vous ne pouvez pas encore utiliser ses fonctionnalités avec votre base de données : pour cela, quelques manipulations supplémentaires sont encore nécessaires :
1.Connexion en tant qu'administrateur de serveur PostgreSQL
sudo su postgres
2. Activation du langage PL/SQL sur votre base de données :
createlang plpgsql my_geo_database
3. Ajout des fonctions PostGIS dans la base de données :
psql -d my_geo_database -f /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql
psql -d my_geo_database -f /usr/share/postgresql/8.4/contrib/postgis-1.5/spatial_ref_sys.sql
4. Changer le propriétaire des tables créées (et ainsi les rendre accessibles depuis vos applications)
psql my_geo_database -c "ALTER TABLE geometry_columns OWNER TO my_user"
psql my_geo_database -c "ALTER TABLE spatial_ref_sys OWNER TO my_user"
Ça y est, votre base de donnée est prête ! Voyons maintenant comment l'utiliser dans un projet Play !
Utilisation dans Play ! FrameworkImaginons une application Web répertoriant les célèbres cabines téléphoniques anglaises(lien), et fournissant un certain nombre de services au visiteur, notamment basés sur la géolocalisation.
Une fois le projet Play initialisé, la première étape est de télécharger les quelques librairies (JAR) nécessaires à l'utilisation de PostGIS :
Une fois les JAR ajoutés au répertoire lib/, réfléchissons à la conception du modèle de l'application. Commençons simplement en créant une classe PhoneBox, avec comme attributs un label, une latitude et une longitude :
public class PhoneBox extends Model {Une cabine téléphonique est un élément assez petit (sur une carte du moins) pour être considéré comme un point (par opposition aux polygones). Ca tombe bien, PostGIS utilise justement cette notion de Point :
import org.postgis.Point;Nous avons donc remplacé le couple latitude / longitude par un seul attribut de la classe Point et modifié le constructeur afin d'instancier cet attribut à partir de ces mêmes latitudes et longitudes.
Comme beaucoup d'autres frameworks Java, Play ! se base sur Hibernate pour gérer la persistence des objets en base de données. Malheureusement, Hibernate ne reconnait pas nativement les types utilisés par PostGIS : C'est là que va intervenir la bibliothèque Hibernate Spatial, installée précédemment.
import org.postgis.Point;En plus des annotations usuelles, l'attribut columnDefinition de l'annotation @Column détermine le type du champ en base de données, et l'annotation @Type détermine quand à elle la classe à laquelle Hibernate doit se référer pour gérer la persistance de l'attribut, ainsi que les requêtes HQL le concernant.
Après avoir relancé l'application, on peut voir que la table phonebox a bien été créée dans notre base de données, avec les champs correspondants.

Ajoutons rapidement quelques cabines téléphoniques pour voir leur représentation dans la base de données :

Les objets sont donc correctement enregistrés avec leurs données. On peut remarquer que le champ location est représenté par une chaîne de caractère peu lisible, c'est le cas avec PostGIS pour tous les champs de type geometry.
Une fois nos cabines téléphoniques disponibles, voyons ce que PostGIS nous offre comme possibilités d'utilisations. Une fonctionnalité pourrait par exemple consister à récupérer les n cabines téléphoniques les plus proches d'une position donnée. Pour cela, nous allons utiliser une requête SQL utilisant les fonctions PL/SQL ajoutées plus tôt :
public static List closest(double latitude, double longitude, int nb)En ordonnant les résultats de la requête en fonction de cette distance, on obtient bien les cabines attendues. En les affichant sur une carte Google Maps (les latitudes et longitudes sont directement récupérées depuis l'objet Point) :

Mais PostGIS ne se limite pas seulement au calcul de distances ! Le nombre de fonctions à disposition est assez impressionnant, et couvre énormément de cas d'usages. Pour s'en rendre compte, il suffit de regarder quelques projets où PostGIS a été mis à l'ouvrage :
Mais attention, malgré toutes ses qualités, PostGIS n'est pas bon à utiliser dans tous vos projets géospatiaux : dans la plupart des cas (et souvent pour les plus basiques), passer par une API tierce (Google, Bing, OSM...) apportera une simplicité et un découplage bienvenus.
Futures perspectivesActuellement, la version stable de PostGIS est la 1.5. La version 2 est sur les rails, et apportera son lot de nouveautés, notamment au niveau de la topologie et du support de la 3D, ainsi qu'un nettoyage de rigueur des fonctions dépréciées.
Pour plus d'informations sur cette seconde version, je vous renvoie vers les présentations suivantes ayant eu lieu lors lors de la dernière session PostgreSQL en Juin dernier :
Depuis trois ans maintenant, NoSQL remet en question le monde centralisĂ© des RDBMS. Les espaces de stockage distribuĂ©s ne sont pour autant pas nouveaux et les banques, les plateformes de jeux utilisent des « grilles de donnĂ©es » pour adresser leurs enjeux de dĂ©bit et de latence.
Quels sont les points communs? les principales diffĂ©rences entre les univers NoSQL et « data grids »?
Suggestion d'articles :
Tous les navigateurs acceptent HTML5 et CSS3 mais tous ne comprennent pas leurs nouvelles fonctionnalitĂ©s. L’usage de nouveaux attributs HTML5 ou de nouvelles propriĂ©tĂ©s CSS3 ne bloquera pas votre navigateur, ce dernier les ignora tout simplement. Un avantage indĂ©niable qui nous permet d’utiliser dès aujourd’hui HTML5 et CSS3 mĂŞme si certains de nos utilisateurs ne disposent pas encore de navigateurs les supportant. Comme je le prĂ©cisais dans l’article Osez renoncer aux vieux navigateurs, il ne faut pas avoir peur d’utiliser des fonctionnalitĂ©s HTML5 et CSS3 car des comportements dĂ©gradĂ©s natifs existent. Quels sont les comportements dĂ©gradĂ©s natifs acceptables ? Comment profiter d’une fonctionnalitĂ© HTML5 ou CSS3 si son comportement dĂ©gradĂ© n’est pas acceptable ? Comment pallier l’absence de support des nouvelles API JavaScript si le navigateur ne les possède pas ?
Les comportements dégradés natifsDes comportements dégradés existent nativement pour la majorité des nouveautés HTML5 et CSS3 lorsque celles-ci ne sont pas supportées par le navigateur. Prenons deux exemples pour illustrer comment les vieux navigateurs se comportent.
HTML5Certaines fonctionnalitĂ©s HTML5 sont des Ă©volutions de fonctionnalitĂ©s existantes, c’est notamment le cas pour les formulaires. Prenons l’exemple des nouveaux types de champs de saisie qui permettent de spĂ©cifier un champ de saisie en tant que champ de saisie e-mail, tĂ©lĂ©phone, date, etc. Cette spĂ©cification permet d’avoir un clavier spĂ©cifique sur les mobiles et une validation adĂ©quate cotĂ© navigateur. Ci-dessous un exemple d’un champ de saisie de type email sur Firefox pour Android 4.

Code original :
1
<input type="email">
Code compris par un navigateur ne supportant pas les formulaires HTML5 :
1
<input type="text">
Si le navigateur ne comprends pas le type (email dans notre cas), le type par dĂ©faut utilisĂ© sera text. Votre formulaire sera donc totalement fonctionnel sur un ancien navigateur, votre utilisateur ne bĂ©nĂ©ficiera pas d’un clavier spĂ©cifique ni de la validation cotĂ© client mais il pourra soumettre le formulaire. Tout le monde peut utiliser votre formulaire et vos utilisateurs qui utilisent un navigateur rĂ©cent bĂ©nĂ©ficieront de fonctionnalitĂ©s intĂ©ressantes sans la moindre charge de dĂ©veloppement.
CSS3On bénéficie également de ces comportements natifs sur les CSS3.
Si vous voyez les coins arrondis, vous êtes un utilisateur génial qui utilise un navigateur récent. Sinon mettez à jour votre navigateur.
Style original :
1 2 3 4 5 6
.boite-arrondie {
border-radius: 5px;
padding: 5px;
background: #ddd;
border: 2px solid #777;
}
Style utilisé par un navigateur ne supportant pas la propriété CSS3 border-radius :
1 2 3 4 5
.boite-arrondie {
padding: 5px;
background: #ddd;
border: 2px solid #777;
}
Si une propriĂ©tĂ© n’est pas comprise, elle est tout simplement ignorĂ©e par le navigateur et les coins sont rectangulaires. Sans les CSS3, il nous faudrait 1 Ă 6 images afin de reproduire ce rendu, ce qui en terme de performance n’est pas anodin ni en terme de complexitĂ© de code ajoutĂ©. Est-ce inacceptable de se priver des coins arrondis sur les anciens navigateurs ? Est-ce pertinent de passer du temps et augmenter la complexitĂ© du code ? Il est important de se poser ces questions pour les nouvelles fonctionnalitĂ©s CSS3 qui vous intĂ©ressent.
Ce comportement est notamment très utilisĂ© par les navigateurs qui prĂ©fixent les propriĂ©tĂ©s lorsque l’implĂ©mentation n’est pas finale. L’utilisation des prĂ©fixes sur certaines propriĂ©tĂ©s n’est pas utile lorsque les navigateurs supportent la propriĂ©tĂ© sans prĂ©fixe depuis plusieurs versions. Des sites comme Can I Use et CSS3 Generator vous permettront de voir si les prĂ©fixes sont indispensables. Ils sont inutiles pour border-radius mais impĂ©ratifs pour les gradients :
1 2 3 4 5 6 7
.fond-degrade {
background: -moz-linear-gradient(top, #1e5799 0%, #7db9e8 100%);
background: -webkit-linear-gradient(top, #1e5799 0%,#7db9e8 100%);
background: -o-linear-gradient(top, #1e5799 0%,#7db9e8 100%);
background: -ms-linear-gradient(top, #1e5799 0%,#7db9e8 100%);
background: linear-gradient(top, #1e5799 0%,#7db9e8 100%);
}
Et si ce comportement dĂ©gradĂ© n’est pas acceptable ?
Il peut arriver que le comportement dĂ©gradĂ© ne soit pas acceptable et qu’il faille envisager une autre solution. Une approche pourrait ĂŞtre de s’interdire d’utiliser une nouvelle fonctionnalitĂ© car 30% des navigateurs de vos utilisateurs ne la supportent pas. Une mauvaise approche car on nivelle par le bas et on se prive de fonctionnalitĂ©s intĂ©ressantes pour l’utilisateur et le dĂ©veloppeur. L’utilisateur profite d’une meilleure expĂ©rience utilisateur. Le dĂ©veloppeur simplifie et rĂ©duit son code car une partie est implĂ©mentĂ©e par le navigateur.
L’approche Graceful degradationL’approche Graceful degradation consiste Ă profiter des nouvelles fonctionnalitĂ©s et proposer une solution de contournement lorsqu’elles ne sont pas disponibles. Pour cela, la librairie JavaScript Modernizr expose de nombreuses mĂ©thodes permettant de dĂ©tecter le support d’une fonctionnalité HTML5 ou CSS3. On peut ainsi utiliser un Polyfill ou encore, si on dĂ©cide de ne pas implĂ©menter du tout cette fonctionnalitĂ© dans ce cas, alerter l’utilisateur que la fonctionnalitĂ© n’est pas disponible. Un Polyfill est un plugin qui fournit une fonctionnalitĂ© que le navigateur devrait possĂ©der nativement. Une longue liste de Polyfill est rĂ©fĂ©rencĂ©e sur GitHub par Modernizr. Ci-dessous un exemple de champ de saisie textuel avec le nouvel attribut placeholder (texte d’aide dans le champ de saisie lorsque celui-ci est vide).
Code HTML :
1
<input type="text" placeholder="exemple de placeholder" />
Code JavaScript permettant de gĂ©rer le non support de l’attribut placeholder :
1 2 3 4 5
// si le navigateur ne supporte pas placeholder
if (!Modernizr.input.placeholder) {
// ajout du comportement avec un plugin jQuery
$('input[placeholder]').placeholder();
}
L’avantage de cette technique est d’isoler le code liĂ© Ă la solution de contournement. Ceci nous permettra de le supprimer sans crainte lorsque vos utilisateurs n’utiliseront plus de navigateurs ne supportant pas cet attribut.
L’utilisation de la cascade pour les CSSEn CSS3, certaines propriĂ©tĂ©s ont de nouvelles valeurs possibles. Il est alors possible de dĂ©finir deux fois une propriĂ©tĂ© avec deux valeurs diffĂ©rentes. Prenons par exemple une boite avec un fond semi-transparent :
Si votre navigateur est récent, le fond de ce paragraphe est vert et transparent. Sinon il est rouge vif.
1 2 3 4
.fond-avec-transparence {
background-color: #ff0000;
background-color: rgba(0,255,0,0.5);
}
Les navigateurs ne supportant pas CSS3 ne comprendront que la première valeur donc le fond sera rouge. Quant aux navigateurs supportant CSS3, ils comprendront les deux valeurs. Ils appliqueront donc la dernière valeur rencontrée pour la propriété ce qui nous donnera un fond vert avec une transparence de 50%.
Des comportements dĂ©gradĂ©s pour les nouvelles APIs ?HTML5 apporte de nouvelles APIs JavaScript (Web Storage, Geolocation, etc.). Ces APIs sont directement utilisables sans import puisque exposĂ©es par le navigateur. Des erreurs JavaScript seront donc levĂ©es si vous les utilisez alors que votre navigateur ne les possède pas. Aucun comportement dĂ©gradĂ© n’existe par dĂ©faut, c’est Ă vous de tester la disponibilitĂ© de ces APIs avant de les utiliser. Comme pour les balises HTML5 ou le CSS3, Modernizr permet de tester facilement la disponibilitĂ© de ces nouvelles API pour proposer une solution alternative ou non. Un exemple ci-dessous avec l’API localStorage :
1 2 3 4 5
// si le navigateur supporte le localStorage
if (Modernizr.localstorage) {
// stockage d'une valeur dans le Web Storage local
localStorage.setItem("clé", "valeur");
}
Aucune raison de ne plus utiliser HTML5 et CSS3
Des solutions existent pour pallier l’absence de support HTML5, parfois simple et fiable, parfois trop complexe ou trop impactant sur les performances du client. C’est un choix Ă prendre sur la solution de contournement lorsque vous dĂ©cidez d’utiliser HTML5 et CSS3. Le site HTML5 Please pourra vous aider Ă prendre ces dĂ©cisions en vous donnant le support des fonctionnalitĂ©s et en vous conseillant sur leur utilisation. D’après les statistiques de StatCounter du mois de janvier, près de 70% des français utilisent un navigateur rĂ©cent qui supporte relativement bien HTML5 et CSS3. Profitez des nouvelles fonctionnalitĂ©s HTML5 et CSS3, des comportements dĂ©gradĂ©s natifs et ne prĂ©voyez de solution alternative que si c’est indispensable.
Suggestion d'articles :
La plateforme Java EE conserve de nos jours encore une mauvaise rĂ©putation. Les fameux EJB 2 et conteneurs lourds dĂ©marrant en plusieurs minutes vous rappelleront quelques bons souvenirs. L’arrivĂ©e de Spring a ouvert la voie aux conteneurs lĂ©gers, Ă l’inversion de contrĂ´le, ou encore Ă l’injection de dĂ©pendances; et est devenue la solution de rĂ©fĂ©rence. Cependant, la plateforme Java EE a beaucoup Ă©voluĂ© entre temps.
Nous allons voir que Java EE 6 n’a maintenant rien Ă envier Ă Spring. Cette plateforme est devenue lĂ©gère et simple Ă prendre en main. Toutes les spĂ©cifications ne seront pas abordĂ©es en dĂ©tails. Nous parlerons plutĂ´t de conteneurs lĂ©gers et testables, de managed beans, d’EJB Lite, ainsi que des nombreux services et patterns offert par la plateforme. Nous terminerons par la spĂ©cification CDI et ses extensions portables, qui offrent de belles perspectives Ă la plateforme Java EE 6.

La revue de presse hebdomadaire des écosystèmes Java/JEE proposée par Xebia.
Actualité éditeurs / SSII
RIA
Le coin de la technique
Vous l'avez peut-être remarqué, les méthodes et leur intention originelle, leur spécificité s'efface peu à peu dans l'ombre portée de la pensée unique agileCscrum et scrumCagile, agileEtscrumCpareil.
Scrum, coquille vide, phagocyte tout ce qui passe : scrum developpeur, scrumban...
Il faut bien dire qu'au quotidien, nous bénéficions d'une boite à outil, un framework agile constitué des dizaines de principes et pratiques issues de différentes sources.
Il reste que les méthodes ont chacune leur spécificité et la "pensée unique" gomme cette diversité, ce qui est un gaspillage.

L'intention est capitale : c'est elle qui, explicite ou non, donne forme aux pratiques.
Vous voyez que les intentions sont sensiblement différentes.
Une différence d'approcheCertaines approches supposent une marche significative : Scrum ou XP, itératives, imposent de nouveaux rôles, un itératif court. Parfois c'est une marche bien (trop) haute.
Attention au scrum-gachisD'où parfois un gâchis : quand le scrummaster est appelé "chef", quand les tests et la qualité sont sacrifiés sur l'autel du lucre, nous sommes loin d'une approche véritablement agile (voir les 12 principes agiles).
Améliorer l'existantLean&Kanban partent de l'existant pour l'améliorer. Parions que, à terme, nous retrouvons quelque chose proche Scrum ou XP. Mais le rythme et la stratégie de changement sont radicalement différents.
Voila un produit hybride qui, comme scrum, peut aussi ĂŞtre agile. Il constitue un "moyen" terme entre
qui peut ĂŞtre une solution pertinente selon le contexte.
Selon le contexte...Voila bien la clé, le contexte. La capacité à changer, plus ou moins rapidement.
Que préférez-vous : réussir un changement progressif (Lean Kanban, AUP) ou rater un changement plus radical ?

Ne gommez pas les méthodes, la diversité des approches est une richesse. Et tout comme des pratiques agiles peuvent compenser des inconvénients d'une approche CMMI ou ITIL, de même le framework constitué des différentes pratiques peut être une aide dans la mise en oeuvre d'une approche, essentiellement choisie en fonction de son intention et de ses impacts en termes de changements qui seront plus ou moins acceptés, possibles, rejetés.