Wednesday, May 4, 2011

Java, Oracle, NLS i tests

Aplicació Java amb Oracle 11g. En dos entorns diferent una consulta amb ORDER BY dóna resultats en ordre diferent. El problema està, evidentment, en la configuració del NLS.

El driver JDBC d'Oracle, la versió purament Java (la versió thin), no fa servir la variable d'entorn NLS_LANG des de la versió 10g. En comptes d'això dedueix els valors de NLS de l'idioma del sistema operatiu. La manera de canviar l'idioma consisteix en passar els següents paràmetres a la VM:
-Duser.language=en -Duser.country=EN

Arrencant amb aquest valors l'ordenació anava bé, per que agafava el NLS_LANGUAGE, NLS_TERRITORY, NLS_SORT i NLS_COMP als valors que esperàvem. Experimentant una mica, vaig veure que amb NLS_SORT si poses BINARY és el més eficient, però si vols que ignori majúscules i minúscules pots fer BINARY_CI i si vols que ignori accents pots fer BINARY_AI. Però això no és l'important.

El cas és que no volíem haver de llençar les nostres màquines virtuals amb paràmetres especials, així que vam mirar de configurar-ho directament a l'aplicació.

La teoria diu que -Dparam=valor és el mateix que des del Java System.setProperty("param", "valor"), però no és així pel que fa a la resolució del NLS. I vam trigar molt en descobrir-ho. En aquest cas el que realment l'interessa és el "default locale" i no aquestes variables d'entorn (que només es fan servir per definir el default locale. Així que tal i com apunten en aquest tutorial de java, el que cal és fer cridar a Locale.setDefault(). En el nostre cas Locale.setDefault(Locale.ENGLISH).

Com això ho volíem fer des de Spring hem pogut aprofitar el que comentava algú al fòrum de Spring.

Ara ja no depenem dels paràmetres d'inicialització.

Conclusions:
  • Les proves automàtiques t'ajuden a trobar els errors ben aviat
  • La configuració de NLS amb Java és un mal de cap

2 comments:

Anonymous said...

Demà et passo la NOTE que varem fer l'Albert i jo per probar aquestes cosetes... efectivament, el JDBC driver.. hereda del locale.

Jomo

Anonymous said...

At http://support.oracle.com

1) Note 375807.1 - Sample Application to Troubleshoot NLS Issues in Application Server / OC4J / JDBC

2) Note 351919.1 - Globalization Support : JavaVM, Oracle JDBC Driver, NLS_LANG and OC4J

3) Note 98065.1 - How to Change NLS_LANG Settings With JDBC Client Applications

;)