Domanda

Ho ereditato un'applicazione Java (servlet) che funziona con Tomcat. Per motivi storici, il codice ha differenti "aspetto grafico" opzioni basate su dove verrà distribuita l'applicazione (essenzialmente una questione di branding).

Esistono diverse costanti che controllano questo processo di branding, che hanno funzioni diverse e non devono essere compattate in un'unica costante (ad es. BRAND, MULTI-LANGUAGE, oltre alle posizioni delle icone e dei fogli di stile CSS, ecc.).

Attualmente il team di sviluppo deve modificare manualmente le costanti (sono almeno localizzate in una classe di dati e ben documentate), quindi ricompilare l'applicazione utilizzando ANT.

Qual è il modo migliore per automatizzare questo processo assumendo almeno Ant 1.8 e Java 6.x?

So che non ci sono state buone soluzioni usando gli argomenti del compilatore (come si potrebbe fare in C o C ++), e mi sto appoggiando ad alcuni "migliori modi". per modificare il file di origine contenente le costanti o inserirle in un altro file e scambiarle utilizzando il processo di generazione di formiche. Mi piacerebbe avere un risultato che funzionerebbe usando qualcosa come " ant build brand-x " dove cambiare il marchio cambierebbe la build risultante.

Grazie,

-Richard

È stato utile?

Soluzione

Utilizzare l'attività di sostituzione in Ant per modificare i valori.

Altri suggerimenti

Inserisci i tuoi valori in un file delle proprietà, ad esempio " myapp.properties " e poi caricali nelle tue costanti dal percorso di classe all'avvio (vedi sotto per come questo si adatta al processo di compilazione):

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 ...
    }
}

Ora, disponi di un file di proprietà separato per ciascun marchio. Passa il suo nome a ANT tramite -D o build.properties e copia il file nella tua directory di build proprio prima di salvarlo (o di metterlo in guerra).

Ovviamente, il codice sopra funzionerà, ma ci sono molti modi per ripulirlo e renderlo a prova di proiettile.

C'è anche una " primavera " modo, che consiste nell'utilizzare un file delle proprietà e un bean che estrae il valore dalle proprietà e le inietta nelle classi che ne hanno bisogno, ad es .:

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

e quindi, puoi iniettare proprietà con un " ant-like " sintassi:

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

che probabilmente comporterebbe una riscrittura maggiore di quanto desideri. Se cambierai costanti in ogni compilazione, farei attenzione a questo gotcha (se stai usando finali statiche, cioè).

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

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

Se poi cambi SOME_CONSTANT in Foo in 2 ma non ricompili Bar, Bar manterrà il valore 1 per SOME_CONSTANT, poiché vengono compilate le finali statiche (poiché il compilatore vede che non dovrebbe mai essere necessario calcolare di nuovo fuori).

Preferisco usare il filtro expandproperties di ant invece del task di sostituzione . Con l'attività di sostituzione, il file di build tende a diventare principalmente tokenizzazione. expandproperties ti consente di incorporare le proprietà della formica direttamente nel tuo testo.

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

Ho una soluzione che funziona come necessario per questa situazione particolare. Ho usato il compito di sostituire la formica insieme a un "salvato". versione della classe costante:

<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>

Faccio solo copie di questo blocco e cambio le sostituzioni per i casi di cui ho bisogno - nel mio caso particolare ora ci sono 3 set, ma più previsti.

Grazie a tutti per le ottime risposte.

Usa Ant file delle proprietà e costruisci con " -Dbrand = X ".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top