Java: Configuration and Preferences API

Lidiar con la configuración siempre es un tema complejo, históricamente los Properties y los XML siempre han salido al rescate.
La problemática viene cuando empiezan a crecer el número de parámetros, de ficheros de configuración y el número de entornos donde debes desplegar (desarrollo, test, producción), ya sean urls de conexión, configuraciones de bbdd o directorios de almacenamiento. Lo peor es cuando esos parametros van empaquetados dentro del jar o el war, entonces tienes q hacer modificaciones manuales, usar profiles de maven o cosas similares.

Si estas cosas te suenan… Una alternativa es usar el API de Preferences de Java (usando las systemRoot); un ejemplo de uso:

package com.acme.foo;

import java.util.prefs.Preferences;

public class Bar {
    public static void main(final String[] args) throws Throwable {
        final Preferences config = Preferences.systemNodeForPackage(Bar.class);
        System.out.println(config.get("mykey", "my-default-value"));
    }
}

Esto te devuelve un Preferences que apunta a “com.acme.foo” y del cual puedes recuperar las claves que desees, por ejemplo “mykey” y si el valor no existe, te devolverá el valor por defecto que le hayas indicado (my-default-value).

El uso es sencillo, con una puntualización, la implementación por defecto de Preferences de Java varía en función del sistema operativo, ya sea una máquina Windows u otra. También puedes usar tu propia implementación (lo cual comentaré más adelante).

Para los curiosos, las implementaciones default son:

  • java.util.prefs.WindowsPreferencesFactory (Windows)
  • java.util.prefs.FileSystemPreferencesFactory (El resto)

En Windows usa el registro del sistema, lo cual es… molesto.
La version FileSystem usa ficheros XML (algo q a los sysadmin no les suele gustar especialmente) y la estructura de almacenamiento es un arbol con subdirectorios por package (ejemplo: com/acme/example) almacenado en:
Para systemRoot:

  • ${java.util.prefs.systemRoot}/
  • /etc/.java/.systemPrefs/
  • ${java.home}/.systemPrefs/

Para userRoot:

  • ${java.util.prefs.userRoot}/
  • ${user.home}/.java/.userPrefs/

Pero aunque te gusten los XML, no puedes forzar el uso de FileSystem/XML si tu máquina es Windows (la implementación FileSystem no viene incluida en el JRE de Oracle), así que pasar de una plataforma a otra no es tan fácil como copiar ficheros.

Hasta aquí sus interioridades, pero… Se puede usar el API de Preferences de un modo sencillo y portable?

Si, aunque con un pequeño trabajo, en mi caso he hecho una implementación (standalone-preferences) basada en Properties (para systemRoot; la userRoot es dummy -intencionadamente-), en la que los ficheros se nombran por el package, sin subdirectorios. Algo tal que así:

  • com.acme.foo.properties
  • com.acme.bar.properties

Más adelante haré otra basada en WS/ReST.

Source code:
standalone-preferences in Github

Referencias:
Preferences API
java.util.prefs.Preferences

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: