Comment est-il possible de générer une séquence de date à partir d’une simple requête SQL sur un base de données Oracle ?
Pour comprendre le principe, il faut savoir que ce type de résultat est obtenu en deux étapes. La première est la génération d’un nombre défini de données à partir d’une requête SQL. La seconde est la transformation des données générées pour obtenir des dates.
Génération d’une série de données
Il existe plusieurs façons de générer un nombre défini de données qui peuvent être exploitées par la suite. Voici un exemple simple :
SELECT 1
FROM DUAL
CONNECT BY LEVEL <= < n >
Avec n le nombre de données que vous souhaitez obtenir. Voici le résultat pour n = 3 :
1
———————-
1
1
1
Transformation de la série en séquence de dates
A partir des données générées précédemment, il est possible de créer une séquence de date avec ce type de requête SQL :
SELECT TRUNC(TO_DATE('20080415','yyyymmdd'),'MM')+ROWNUM -1 DATES FROM (
SELECT 1
FROM DUAL
CONNECT BY LEVEL <= <n>
)
Voici le résultat pour n = 3 :
DATES
————————-
01/04/08
02/04/08
03/04/08
Sources : Pour plus d’explications, vous pouvez vous référer au site internet qui m’a servi de référence : http://www.dba-oracle.com/t_test_data_date_generation_sql.htm. Vous y retrouverez entre autre deux façons différentes de générer une série de données.
Dans ce ticket, je vais expliquer comment bien configurer le plugin jaxb2-maven-plugin dans le cas où l’on souhaite transformer des fichiers XSD en classes java vers des packages différents. Il faut savoir qu’avec ce plugin il n’est pas possible de définir plusieurs packages de destination dans une même exécution.
Dans l’exemple choisi, je génère deux classes Java à partir de deux fichier XSD vers deux packages différents :
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<executions>
<execution>
<id>id1</id>
<phase>generate-sources</phase>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<clearOutputDir>false</clearOutputDir>
<staleFile>${project.build.directory}/generated-sources/jaxb/.staleFlag-id1</staleFile>
<schemaDirectory>${basedir}/src/main/resources/id1</schemaDirectory>
<packageName>id1</packageName> <!-- The name of your generated source package -->
</configuration>
</execution>
<execution>
<id>id2</id>
<phase>generate-sources</phase>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<clearOutputDir>false</clearOutputDir>
<staleFile>${project.build.directory}/generated-sources/jaxb/.staleFlag-id2</staleFile>
<schemaDirectory>${basedir}/src/main/resources/id2</schemaDirectory>
<packageName>id2</packageName> <!-- The name of your generated source package -->
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.8.1</version>
</dependency>
</dependencies>
</plugin>
A noter que pour chaque exécution :
- Il est nécessaire d’utiliser un identifiant unique. Sinon maven n’arrivera pas à exécuter le plugin.
- Il faut impérativement utiliser l’option staleFile pour associer un fichier différent à chaque exécution (ce fichier sert au plugin pour savoir si les classes Java sont déjà générées). Sans cela, la seconde exécution ne génèrera pas de classe Java.
- Il faut indiquer au plugin de ne pas nettoyer le répertoire de génération avant l’exécution (option clearOutputDir à false) car c’est son comportement par défaut. Sans cela, la seconde exécution supprimera les classes générées pas la première.
Voici l’adresse de l’exemple associé : https://subversion.assembla.com/svn/everythingiswrong/tutorial-jaxb2-maven-plugin/.
Les intercepteurs sont des petits programmes qui interviennent avant et après l’exécution d’une méthode. ils permettent de faire de la programmation orientée AOP sur les méthodes publics des EJB. Il est possible de s’en servir pour logger les entrées et sorties d’une méthode comme je le propose dans mon exemple qui se base sur un simple “HelloWorld” en EJB3. J’utilise openEJB pour simplifier l’exécution et vous permettre d’utiliser l’exemple tel quel.
Création de l’intercepteur : c’est un EJB standard avec une méthode public annotée avec @AroundInvoke.
public @Stateless class LoggerServiceBean implements LoggerService {
@AroundInvoke
public Object c(InvocationContext ctx) throws Exception {
// Affiche le nom de la méthode
System.out.println(ctx.getMethod().toGenericString());
// Liste les paramètres passés à la méthode
for (int i = 0; i < ctx.getParameters().length; i++) {
if (i != 0) {
System.out.print(",");
}
System.out.print("parameter " + i +" : " + ctx.getParameters()[i]);
}
System.out.println();
return ctx.proceed(); //Exécute de la méthode
}
}
Comme vous pouvez le voir, c’est l’objet InvocationContext qui va vous permettre de visualiser la méthode et les paramètres utilisés.
Déclaration de l’EJB en tant qu’intercepteur : ajouter ces quelques lignes dans le fichier META-INF/ejb-jar.xml :
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
version="3.0">
<interceptors>
<interceptor>
<interceptor-class>org.everythingiswrong.tutorial.interceptor_openejb.interceptor.LoggerServiceBean</interceptor-class>
</interceptor>
</interceptors>
<assembly-descriptor>
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>org.everythingiswrong.tutorial.interceptor_openejb.interceptor.LoggerServiceBean</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
</ejb-jar>
Voici l’adresse SVN du projet : https://subversion.assembla.com/svn/everythingiswrong/tutorial-interceptor-openejb
Dans ce poste je vais générer des services SOAP java à partir de deux fichiers WSDL. La contrainte que je m’impose est de générer dans un même package toutes les classes java. Il faut paramétrer le plugin jaxws-maven-plugin en lui donnant un nom de package pour l’ensemble des WSDL (ou bien utiliser le même namespace pour les deux WSDL et leurs objets associés) :
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<packageName>com.example.myschema</packageName>
</configuration>
...
</plugin>
Le problème c’est que le plugin génère les objets dans l’ordre de traitement des WSDL. Cela implique que la classe ObjectFactory.java qui permet d’instancier les objets issus de la génération est créée une première fois pour les objets du premier WSDL puis écrasée par la seconde génération avec les objets du second WSDL.
Pour résoudre ce problème, il est possible de mutualiser les objets des deux WSDL dans un même schéma XSD qui va englober tous les objets des deux WSDL. La première génération va toujours être écrasée par la seconde mais cette fois si, les deux générations produisent exactement les mêmes objets et l’objet ObjectFactory va pouvoir instancier tous les objets des deux WSDL.
Voici un exemple : https://subversion.assembla.com/svn/everythingiswrong/multiple-wsdl-same-package/
Aujourd’hui, j’ai découvert un plugin eclipse très pratique pour apprendre petit à petit les raccourcis clavier d’Eclipse : mousefeed. Lorsqu’une action est faite avec la souris, une popup apparaît pour vous montrer le raccourcis clavier qui aurait pu être utilisé pour faire la même opération. Par exemple, si vous demander le rafraichissement de votre projet eclipse avec la souris, voici la popup qui va s’afficher :

Cette semaine, j’ai appris qu’il existait une extention Firefox pour récupérer des informations personnelles sur nos voisins de réseaux (d’autres machine du même réseau IP) lorsqu’ils naviguent sur des sites tels que Facebook : Firesheep. L’auteur présente cette extension comme révolutionnaire car elle permet de voir le trafic internet d’un autre ordinateur. C’est oublier qu’aujourd’hui, nous sommes tous connectés sur des switchs et non des hubs. Cela veut dire qu’une machine ne peut pas voir le trafic généré par une autre même si elles sont sur le même réseau IP.
Il est possible cependant de contourner ce problème en trompant la machine victime en faisant passer son trafic par la machine attaquante comme sur l’illustration suivante :

Voici un site internet qui va vous aider à faire cette opération avec la ligne de commande. Il existe aussi un logiciel spécialement fait pour ce genre d’attaque : Ettercap. Voici un tutorial pour utiliser Ettercap. De mon coté j’ai du installer ettercap-ng puis utiliser la commande avec l’utilisateur root car autrement, j’avais une erreur sur les interfaces réseaux.
Pour éviter de tomber dans ce piège, la machine victime doit vérifier systématiquement la validité des certificats utilisés sur les sites Internet. En générale, cette information apparaît sous la forme d’un icon d’un cadena fermé sur votre navigateur).
Eclipse propose l’autocompletion sur les méthodes des objets importés statiquement qu’après les avoir déclarés manuellement. Par exemple, pour utiliser les asserts JUnit dans un test TestNg, il faut ajouter l’import statique suivant avant de pouvoir bénéficier de l’aide à la saisie :
import static org.testng.AssertJUnit.*;
Pour profiter de l’autocompletion sans ajouter cette ligne au préalable, il faut se diriger dans le menu : Window -> Preferences puis Java -> Editor -> Content Assist -> Favorites et ajouter le nouveau type org.testng.AssertJUnit.
Il est toujours difficile de paramétrer les conteneurs embarqués. Encore plus lorsque ces derniers ne sont plus très récents et donc pas très bien documentés. C’est pourquoi je vous propose cet article qui va vous apprendre à enregistrer une chaine de caractère (java.lang.String) dans l’annulaire JNDI de JBoss embedded. Pour cela, il faut ajouter ce code XML dans le fichier embedded-jboss-beans.xml de votre classpath :
<bean name="" class="org.jboss.ejb3.embedded.JndiBinder">
<property name="target">La valeur de la variable</property>
<property name="bindTo">variableName</property>
<property name="serializable">true</property>
</bean>
Voici un exemple concret : https://subversion.assembla.com/svn/everythingiswrong/embedded-jboss-jndi-exemple.
Pour plus d’information sur le conteneur embarqué de JBoss que j’utilise dans l’exemple : http://docs.jboss.org/ejb3/embedded/embedded.html.
En programmation Java il arrive de temps en temps qu’un programme tombe en erreur car il manque des classes dans le classpath d’exécution. Jusqu’à présent, je me suis toujours arrangé pour retrouver les artefacts (jar) contenant les classes manquant avec de l’expérience et surtout de la change.
Maintenant c’est fini ! Je viens de découvrir le site internet findjar. Grâce à lui, je retrouve facilement les artefacts contenant ma classe absente !
Depuis que j’ai modifié ma version d’éclipse, je remarque que le démarrage est très lent et que certains processus ont l’air de rester bloqués. Par exemple : Initialize Java Tooling et Loading Web Service Dom.
Mes recherches m’ont permis de découvrir qu’il était possible de paramétrer le démarrage des processus Eclipse a l’ouverture d’un workspace dans le fenêtre Window -> Preferences puis General -> Startup and Shutdown.
Mes la solution réelle à mes problèmes de lenteur a été de supprimer un répertoire de mon workspace : WORKSPACE_HOME/.metadata/.plugins/org.eclipse.core.resources/.projects. Eclipse ne freeze plus au démarrage par contre il faut reconfigurer tous les projets du workspace. Par exemple, j’ai du réactiver maven sur mes projets et les reconnecter à subversion. Pour les projets maven multimodule il m’a fallu supprimer les sous-modules puis les réimporter à partir du projet père.