2008-12-31 14 views
5

He heredado una aplicación Java (servlets) que se ejecuta bajo Tomcat. Por razones históricas, el código tiene diferentes opciones de "apariencia" según el lugar donde se implementará la aplicación (esencialmente, una cuestión de desarrollo de la marca).La mejor manera de alterar las constantes en el proceso de compilación de Java

Existen varias constantes que controlan este proceso de marca, que tienen diferentes funciones y no deben compactarse en una sola constante (es decir, MARCA, IDIOMA MULTIPLES, más la ubicación de iconos y 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 recompila 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 de compilación (como se podría hacer en C o C++), y me estoy refiriendo a la "mejor manera" de editar el archivo fuente que contiene las constantes o ponerlas en otro archivo y cambiarlos usando el proceso de compilación de ant. Me gustaría tener un resultado que funcione usando algo como "ant build-brand-x" donde cambiar la marca cambiaría la compilación resultante.

Gracias,

-Richard

Respuesta

2

Utilice la tarea sustituir en hormiga para cambiar los valores.

+0

Esto es fuerza bruta, pero funciona. Sin embargo, sobrescribe el archivo, por lo que debe crear una copia guardada (o plantilla) del archivo y copiarlo cada vez. -R – Huntrods

+0

Seguimiento ... He estado usando esto desde esta respuesta en 2008 y ha estado funcionando perfectamente. Al desarrollar, puedo compilar el sistema más de 20 veces a la semana y es genial. (cuando no se desarrolla, el sistema se ejecuta estable durante meses y meses). – Huntrods

1

Hay también una forma de "primavera", que consiste en utilizar un archivo de propiedades, y un grano que se saca 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 a continuación, se puede inyectar propiedades con una sintaxis "como hormigas":

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

que probablemente implicaría más reescritura de lo que quisiera. Si va a cambiar las constantes en cada compilación, estaría atento a este problema (si está usando finales estáticos, eso es).

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

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

Si cambia SOME_CONSTANT de Foo a 2, pero no volver a compilar Bar, Bar retendrá el valor de 1 para SOME_CONSTANT, como las finales estáticas se recogen en (ya que el compilador ve que no debería necesita alguna vez resolverlos de nuevo).

1

Prefiero usar el filtro expandproperties de horm en lugar de la tarea de reemplazar. Con la tarea de reemplazo, el archivo de compilación tiende a convertirse en tokenización principalmente. expandproperties le permite incrustar propiedades de hormiga directamente en su texto.

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

Coloque sus valores en un archivo de propiedades, diga "myapp.Propiedades" y luego cargarlos en sus constantes de la ruta de clase en el arranque (ver a continuación cómo esto encaja en el proceso de construcció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, tienen un archivo de propiedades separadas para cada marca Pase su nombre a ANT. vía -D o build.properties y copie el archivo en su directorio de compilación justo antes de que lo cargue (o guerra).

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

+0

Esta es una buena solución, pero no funciona para constantes que no sean cadenas (lo intenté de varias maneras). Es por eso que terminé yendo con el método de reemplazo de hormigas menos elegante. -Richard – Huntrods

+0

No se puede simplemente agregar un método de ayuda "private static int getInt (String name, int def)"? No veo ninguna razón por la que no funcione para cadenas que no sean, al menos con un poco más de código. –

1

Tengo una solución que funciona como se necesita para este si particular tuación. He usado la hormiga reemplazar tarea en conjunto con un "salvado" 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="@[email protected]" value="ONE_BRAND"/> 
    <replace file="./tme3/MyConst.java" token="@[email protected]" 
      value="../stylesheet/onebrand.css"/> 
    <replace file="./tme3/MyConst.java" token="@[email protected]" value="../images/onebrand.ico"/> 
    <replace file="./tme3/MyConst.java" token="@[email protected]" value="false"/> 
</target> 

acabo de hacer copias de este bloque y cambiar las sustituciones para los casos que necesito - en mi caso particular, no Son 3 sets ahora, pero más esperados.

Gracias a todos por las excelentes respuestas.

Cuestiones relacionadas