Pregunta

He heredado una aplicación Java (servlets) que se ejecuta bajo Tomcat. Por razones históricas, el código tiene " aspecto y sensación " " opciones basadas en dónde se implementará la aplicación (esencialmente una cuestión de marca).

Hay varias constantes que controlan este proceso de marca, que tienen diferentes funciones y no se deben compactar en una sola constante (es decir, MARCA, MULTI-IDIOMA, más las ubicaciones de los iconos y las hojas de estilo css, etc.).

Actualmente, el equipo de desarrollo debe cambiar manualmente las constantes (al menos están localizadas en una clase de datos y están bien documentadas), luego recompilar la aplicación usando ANT.

¿Cuál es la mejor manera de automatizar este proceso suponiendo al menos Ant 1.8 y Java 6.x?

Sé que no ha habido ninguna buena solución utilizando argumentos del compilador (como se podría hacer en C o C ++), y me estoy inclinando hacia alguna de las "mejores maneras" para editar el archivo de origen que contiene las constantes, o colocarlas en otro archivo e intercambiarlas usando el proceso de compilación ant. Me gustaría tener un resultado que funcionaría usando algo como " ant build brand-x " donde cambiar la marca cambiaría la construcción resultante.

Gracias,

-Richard

¿Fue útil?

Solución

Use la tarea de reemplazo en Ant para cambiar los valores.

Otros consejos

Coloque sus valores en un archivo de propiedades, diga " myapp.properties " y luego cárguelos en sus constantes desde el classpath al inicio (vea a continuación cómo encaja esto en el proceso de compilación):

public class Constants
{
    private static final Properties props = new Properties();
    public static final String MY_CONSTANT;

    static
    {
        InputStream input = Constants.class.getResourceAsStream("/myapp.properties");
        if(input != null)
        {
           try
           {
              properties.load(input);
           }
           catch(IOException e)
           {
              // TODO log error
           }
        }

        // Initialize constants (dont' forget defaults)
        MY_CONSTANT = properties.getProperty("constant", "default");
        // .. other constants ...
    }
}

Ahora, tenga un archivo de propiedades separado para cada marca. Pase su nombre a ANT a través de -D o build.properties y copie el archivo en su directorio de compilación justo antes de juntarlo (o armarlo).

Obviamente, el código anterior funcionará, pero hay muchas formas de limpiarlo y hacerlo a prueba de balas.

También hay un " primavera " forma, que es usar un archivo de propiedades, y un bean que extrae el valor de las propiedades y los inyecta en las clases que los necesitan, por ejemplo:

<bean id="propertyPlaceholder"  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:configuration.properties" />
</bean>

y luego, puedes inyectar propiedades con un " ant-like " sintaxis:

<bean id="connectionPool"  class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
    <property name="databaseName" value="mydb" />
    <property name="url" value="${db.url}" />
    ...

lo que probablemente implicaría más reescritura de la que te gustaría. Si vas a cambiar las constantes en cada compilación, cuidaría de esto (si es que estás usando finales estáticas).

public class Foo {
 public static final int SOME_CONSTANT=1;
..
}

public class Bar {
  ...
   int x=5+Foo.SOME_CONSTANT;
  ...
}

Si luego cambia SOME_CONSTANT en Foo a 2 pero no vuelve a compilar Bar, Bar conservará el valor de 1 para SOME_CONSTANT, ya que las finales estáticas están compiladas (ya que el compilador ve que no debería tener que figurar nunca) ellos fuera de nuevo).

Prefiero usar el expandproperties de ant en lugar de la tarea de reemplazo . Con la tarea de reemplazo, el archivo de compilación tiende a crecer para ser en su mayoría tokenización. expandproperties le permite incrustar propiedades ant directamente en su texto.

<copy file="from" tofile="to">
  <filterchain>
    <expandproperties />
  </filterchain>
</copy>

Tengo una solución que funciona según sea necesario para esta situación en particular. He utilizado la tarea de reemplazo de Ant junto con un " guardado " versión de la clase constante:

<target name="one" description="constant substitution #1">
  <delete file="./tme3/MyConst.java" />
  <copy file="./save/MyConst.java" tofile="./tme3/MyConst.java" />
  <replace file="./tme3/MyConst.java" token="@BRANDING@" value="ONE_BRAND"/>
  <replace file="./tme3/MyConst.java" token="@STYLESHEET@"
           value="../stylesheet/onebrand.css"/>
  <replace file="./tme3/MyConst.java" token="@FAVICON@" value="../images/onebrand.ico"/>
  <replace file="./tme3/MyConst.java" token="@SHOW_LANGUAGES@" value="false"/>
</target>

Acabo de hacer copias de este bloque y cambio las sustituciones de los casos que necesito. En mi caso particular, ahora hay 3 conjuntos, pero se esperan más.

Gracias a todos por las excelentes respuestas.

Use los archivos de propiedades , y compile con " -Dbrand = X " ;.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top