Question

J'ai hérité d'une application Java (servlets) s'exécutant sous Tomcat. Pour des raisons historiques, le code a un aspect différent. options en fonction du lieu où l'application sera déployée (essentiellement une question de marque).

Plusieurs constantes contrôlent ce processus de personnalisation. Elles ont des fonctions différentes et ne doivent pas être condensées en une seule constante (par exemple, MARQUE, MULTI-LANGUES, plus l'emplacement des icônes et des feuilles de style CSS, etc.).

Actuellement, l'équipe de développement doit modifier manuellement les constantes (elles sont au moins localisées dans une classe de données et bien documentées), puis recompilez l'application à l'aide de ANT.

Quel est le meilleur moyen d'automatiser ce processus en supposant au moins Ant 1.8 et Java 6.x?

Je sais qu’il n’ya pas eu de bonnes solutions utilisant les arguments du compilateur (comme on pourrait le faire en C ou C ++), et j’applique plutôt à la "meilleure façon". pour éditer le fichier source contenant les constantes, ou les mettre dans un autre fichier et les échanger à l'aide du processus ant-build. J'aimerais obtenir un résultat qui fonctionnerait en utilisant quelque chose comme "ant build brand-x". où changer la marque changerait la construction résultante.

Merci,

-Richard

Était-ce utile?

La solution

Utilisez la tâche de remplacement dans Ant pour modifier les valeurs.

Autres conseils

Mettez vos valeurs dans un fichier de propriétés, dites " myapp.properties " puis chargez-les dans vos constantes à partir du classpath au démarrage (voir ci-dessous comment cela s’intègre dans le processus de construction):

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

Maintenant, créez un fichier de propriétés distinct pour chaque marque. Transmettez son nom à ANT via -D ou build.properties et copiez le fichier dans votre répertoire de construction juste avant de le lancer (ou de le déclarer).

Évidemment, le code ci-dessus fonctionnera, mais il existe de nombreuses façons de le nettoyer et de le rendre infaillible.

Il existe également un "ressort". manière, qui consiste à utiliser un fichier de propriétés et un bean qui extrait la valeur des propriétés et les injecte dans les classes qui en ont besoin, par exemple:

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

et ensuite, vous pouvez injecter des propriétés avec un "ant-like" syntaxe:

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

ce qui entraînerait probablement plus de réécriture que vous ne le souhaitez. Si vous envisagez de modifier les constantes à chaque compilation, vous devez vous méfier des pièges (si vous utilisez des finales statiques, c'est bien le cas).

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

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

Si vous modifiez ensuite SOME_CONSTANT dans Foo en 2 mais ne recompilez pas Bar, Bar conservera la valeur 1 pour SOME_CONSTANT, car les finales statiques sont compilées (car le compilateur voit qu'il ne devrait pas avoir besoin de calculer les sortir à nouveau).

Je préfère utiliser le filtre expandproperties de ant, au lieu de la tâche de remplacement. . Avec la tâche de remplacement, le fichier de construction tend à devenir principalement une tokenization. expandproperties vous permet d’incorporer les propriétés des ant directement dans votre texte.

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

J'ai une solution qui fonctionne selon les besoins pour cette situation particulière. J'ai utilisé la tâche Remplacer Ant en conjonction avec l'option "enregistré". version de la classe 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>

Je ne fais que des copies de ce bloc et modifie les substitutions des cas dont j'ai besoin - dans mon cas particulier, il en existe 3 ensembles, mais il en attend plus.

Merci à tous pour ces bonnes réponses.

Utilisez les fichiers de propriétés et créez-les avec " -Dbrand = X ".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top