Il est parfois nécessaire d’appeler une Class à partir d’un bloc PL/SQL pour des traitements spécifiques comme par exemple le cryptage ou bien l’analyse d’expression Quartz. Dans l’article ci-dessous, j’aborderai l’appel d’une Class de Cryptage dont le source est en annexe à la fin de l’article.
- Compilation de la Class java
Il faut impérativement compiler la Class dans une version de java identique à celle du serveur de base de données.
Exemple :
Si la version de Java du serveur BDD est en 1.5 et que celle de l’IDE est en 1.7, il faut ajouter les mots clefs suivants lors de la compilation : -source 1.5 -target 1.5 sinon l’erreur suivante se produit lors de l’exécution
de la fonction PL/SQL
ORA-29532: appel Java arrêté par une exception Java non interceptée : System error : java/lang/UnsupportedClassVersionError ORA-06512: à ".....", ligne 1 ORA-06512: à ligne 4
- Chargement de la Class dans la BDD
Certaines Class pouvant faire appel à des libraires, il faut donc les charger avant la Class fonctionnelle. Dans notre exemple, la Class d’encrytage fait appel aux librairies suivantes :
- log4j-1.2.14.jar
- commons-logging-api-1.1.jar
- xmlsec-1.4.2.jar
Après avoir téléchargé les librairies et la Class sur le serveur de BDD (par exemple dans /home/oracle/java4oracle/), ouvrir une session sur le serveur (par exemple Putty) avec un profil Oracle puis lancer les commandes suivantes :
loadjava -verbose -genmissing -user user1 /home/oracle/java4oracle/log4j-1.2.14.jar loadjava -verbose -genmissing -user user1 /home/oracle/java4oracle/commons-logging-api-1.1.jar loadjava -verbose -genmissing -user user1 /home/oracle/java4oracle/xmlsec-1.4.2.jar loadjava -verbose -resolve -user user1 /home/oracle/java4oracle/DataEncryption.class
Le mot clef –genmissing permet de ne pas résoudre les références au moment du chargement des librairies. Cette résolution s’effectuera lors du chargement de la Class proprement dite avec le mot clef –resolve.
- Création de la fonction PL/SQL
Sous SQLPLUS, créer la fonction suivante :
CREATE OR REPLACE FUNCTION FCT_ENCRYPT (plainText VARCHAR2, encryptProperties VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'com/..../..../..../DataEncryption.encrypt(java.lang.String,java.lang.String) return java.lang.String';
- Test de la fonction PL/SQL
Sous SQLPLUS,
select FCT_ENCRYPT('Chaine de caractère à crypter','true') from dual;
Annexe : Code source Class Java
package com...; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.log4j.Logger; import org.apache.xml.security.exceptions.Base64DecodingException; import org.apache.xml.security.utils.Base64; public class DataEncryption { public DataEncryption() { super(); } /** * @param plainText * String that must be encrypted * @param encryptProperties * Only if the propertie insert.crypt of the file properties is set * to true, input data is encrypted. * * @return * Encrypted string * @throws Exception */ Public static String encrypt(final String plainText,final String encryptProperties ) { .... .... .... return plainText; } } }