mardi 17 juin 2008

Débuter avec axis2

Installer Axis2 sous Linux

  • Télécharger Axis2
  • Extraire le jar dans /usr/axis2-1.4
  • Effectuer des liens ln -s /usr/axis2-1.4/bin/wsdl2java.sh /usr/bin/wsdl2java.sh
  • Effectuer des liens ln -s /usr/axis2-1.4/bin/axis2.sh /usr/bin/axis2.sh
  • Modifier la première ligne dir=/usr/axis2-1.4/bin/ avec le chemin d'installation réel dans /usr/axis2-1.4/bin/axis2.sh et /usr/axis2-1.4/bin/wsdl2java.sh
  • Télécharger ANT
  • Extraire le jar dans /usr/apache-ant-xxx
  • Effectuer des liens ln -s /usr/apache-ant-xxx/bin/ant /usr/bin/
  • Exporter la variable export AXIS2_HOME=/usr/axis2-1.4



Supprimer le SOAP12 sur axis2
Modifier le fichier axis2.xml
   <parameter name="disableSOAP12" locked="true">true</parameter>


Utiliser avec Hibernate 3.6.2

Il faut utiliser antlr-1.7.7 et faire ettention au classpath d'une manière générale.
(Le classloader de l'application axis ne permet pas de redescendre plus bas au scope service s'il utilise le scope application.)
Concrètement cela signifie qu'il est impossible de mettre le fichier hibernate dans les librairies de AXIS.
Effectuer une première génération

  • Créer un répertoire pour votre projet
  • wsdl2java.sh -uri http://urlduwebservice.com/monservice
  • Taper ant

Structure d'une archive AXIS2
On peut déployer un service axis sous forme d'un fichier aar.

META-INF/services.xml
lib/*.jar



Il est également possible de le déployer sous forme d'un répertore ayant la même structure.

Note pour se servir du mapping adb à partir de POJO.

Si le bean retourné contient une liste d'élément, il n'est pas possible de se servir des typecast de liste, il faut se servir de tableau.

Génerer un Web Service à partir d'un WSDL et de Maven

Ajouter le bloc

<build>
<plugins>
<plugin>
<groupId>org.apache.axis2.maven2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>wsdl2code</goal>
</goals>
<configuration>
<package>com.foo.myservice</package>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>




mvn -U axis2-wsdl2code:wsdl2code -DwsdlFile=http://10.202.48.12:8080/axis2/services/OrganisationControleService?wsdl -Daxis2.wsdl2code.package=joe.bigood


Il faut rajouter manuellement et en local la dépendance au plugin.

<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.2</version>
</dependency>

dimanche 15 juin 2008

Utiliser xpath

Dans cet article, je présente une petite collection de requête exemple de xpath. En la matière, l'empirisme est roi !

Comment retrouver tous les élément img dans un document html (Quelque soit leur hiérarchie)

XPath xpath = XPathFactory.newInstance().newXPath();
InputSource is = new InputSource(new FileInputStream(
"src/test/resources/testXpath.xml"));
NodeList str =(NodeList) xpath.evaluate("//img",
is,XPathConstants.NODESET);
log.debug(str.getLength());


Comment effectuer une transformation à l'aide de XPATH (Sans utiliser XQuery)
XPath xpath = XPathFactory.newInstance().newXPath();
DocumentBuilder db = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document document = db.parse(new File(
"src/test/resources/testXpath.xml"));
InputSource is = new InputSource(new FileInputStream(
"src/test/resources/testXpath.xml"));
NodeList str = (NodeList) xpath.evaluate("//img", document,
XPathConstants.NODESET);
Element el = (Element) str.item(0);
el.setAttribute("src", "newValue");
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
Source source = new DOMSource(document);
StreamResult sr = new StreamResult(System.out);
transformer.transform(source, sr);



Attention à la manipulation des namespaces dans XPATH !

Quand les requêtes xpath utilisent des namespaces, deux options sont possible :

La première est d'utiliser les noms absolus et non pas les alias pour effectuer la recherche :

//urn:oasis:names:tc:opendocument:xmlns:text:1.0:span


Malheureusement, cette méthode ne fonctionne lorsque les namespaces comportent le caractère '/' (qui sont descaractère utilisé pour écrire les requête Xpath). Dans ce cas, une deuxième méthode consiste à fournir à Xpath les alias des namspaces que nous utiliserons dans la requête. Cette approche est préférable, car les namespaces qui ne comportent pas de '/' sont plutôt rares.


NamespaceContext ctx = new NamespaceContext() {
public String getNamespaceURI(String prefix) {
String uri;
if (prefix.equals("w")) {
uri = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
}
else if (prefix.equals("ns2")) {
uri = "http://www.davber.com/sales-format";
}
else {
uri = null;
}
return uri;
}
public String getPrefix(String namespaceURI) {
return null;
}
public Iterator getPrefixes(String namespaceURI) {
return null;
}
};
xpath.setNamespaceContext(ctx);


Il faut également rappeler que les namespaces sont héritables par les balise fille lorsque le namespace est déclaré par un attribut xmlns. Concrétement, dans l'exemple suivant, la balise Relationship est à rechercher dans le namespace : http://schemas.openxmlformats.org/package/2006/relationships car la balise parente Relationships est affectée à ce namespace par l'attribut xmlns.


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer1.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rId2"



Dans le cas ou le JDK a une version inférieure à la 1.5, JDOM fournira l'api XPath.



SAXBuilder sxb = new SAXBuilder();
File file = new File(filename);
FileInputStream fis = new FileInputStream(file);
InputSource is = new InputSource(fis);
is.setEncoding("ISO-8859-1");
org.jdom.Document document = sxb.build(is);
// On initialise un nouvel élément racine avec l'élément racine du
// document.
Element racine = document.getRootElement();
XPath xpath = XPath.newInstance("count(/document/firstBranch/order/orderStatus/OrderStatusCode[text()='MARECHERCHE'])");
String result = xpath.valueOf(racine);


Exemple de requête

Pour compter le nombre de balise ayant l'arborescence /document/firstBranch/order/orderStatus/OrderStatusCode et contenant le texte 'MARECHERCHE'

/document/firstBranch/order/orderStatus/OrderStatusCode[text()='MARECHERCHE'])



Pour récuppérer toutes les balises img sous forme de nodeset


xpath.evaluate("//img", document,
XPathConstants.NODESET);

mercredi 9 avril 2008

Cloner des beans JAVA

La methode BeanUtils.cloneBean(Object obj1,Object obj2) permet de répliquer des beans en faisant une introspection sur les méthodes get et set du bean, ceci peut se faire sans utiliser l'interface clonable.

La librairie permettant de faire ceci se télécharge sur http://commons.apache.org/beanutils

    <dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutilsartifactId>
<version>1.8</version>
</dependency>

mardi 8 avril 2008

Problème de synchronisation avec hibernate

Lors de l'appel de saveOrUpdate() or update() j'ai une NonUniqueObjectException.

La session utilise un cache entre la persistance et l'objet instance, ce cache est unique (Il se manifeste par les proxy cglig). L'appel de saveOrUpdate determine premièrement si cet objet existe en base, si oui, il construit son proxy CGLIB, ainsi hibernate sait si cet objet existe ou non en base de données. La comparaison de l'objet proxié et de l'objet que nous tentons d'insérer (Non proxié) provoque une incohérence et retourne l'erreur ci dessus.

L'utilisation de la fonction saveOrUpdate() ne sert pas comme on le croit d'abord, à permettre de procéder à des insert ou des update en aveugle.

La solution de ce problème est soit de connaitre l'état de l'objet avant de faire l'insertion en base. (Ce qui diminue notablement le charme de la fonction saveOrUpdate) soit d'utiliser la fonction merge, qui permet de cloné un objet sur son proxy.

marge prend en argument un objet non proxié et retourne un objet proxié clone exact de l'objet passé en argument.

mercredi 2 avril 2008

Créer dynamiquement des QUEUE

Dans le cadre de la création d'un bus de routage je souhaitais pouvoir créer dynamiquement des queues à l'aide de la méthode createQueue(String queuename).

if (queue == null) {
log.info("Création de la queue " +
queueName); queue = session.createQueue(queueName);
}

Cela n'a pas fonctionné car JORAM n'implémente pas cette fonction. Après quelques recherche sur internet, cette fonction devrait être utilisée de manière marginale et pas dans le cadre d'un bus et n'est pas recommandable

12:35:29,484 ERROR BusServiceMdb:96 - Le transfert du message a échoué !
javax.jms.InvalidDestinationException: Proxy could not forward the request to incorrectly identified destination: java.lang.IllegalArgumentException: QUEUELOUCHE: bad id

mardi 1 avril 2008

Modifier le niveau de securité sur Mandriva

Ayant installé Mandriva 2008, je me suis retrouvé avec un niveau de sécurité trop élevé pour mes besoins (4).

Concrétement, les répertoire home changeais constamment de droits de sorte qu'il n'était pas possible à plusieurs utilisateur de se lire les fichiers

Pour y remédier le commande :
msec -o log=stderr 2 

effectue le changement de niveau.

Ces informations sont stockée dans le fichier /etc/sysconfig/msec

UMASK_ROOT=022 (Donne les droit d'accès du repertoire root)
SECURE_LEVEL=3 (Donne le niveau de sécurité)
UMASK_USER=022 (Donne les droit d'accès des répertoire utilisateur)
TMOUT=0



msec est lancé quotidiennement, on le trouve dans /etc/cron.daily

http://club.mandriva.com/xwiki/bin/view/KB/SecureSmsec2?language=fr#HQuelniveaudesC3A9curitC3A9choisir3F

jeudi 13 mars 2008

Installer posfix Mandriva avec un relay smtp authentifié

Dans la fichier /etc/postfix/main.cf

Ajouter les lignes :

smtpd_sasl_path = /etc/postfix/sasl:/usr/lib/sasl2
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
relayhost = smtp.my.network
smtp_sasl_security_options =



Créer le fichier /etc/postfix/sasl_passwd et ajouter les lignes

smtp.my.network monuser:monpassword



Redémarrer postfix