IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Modifier constante sans recompiler


Sujet :

avec Java

  1. #1
    Membre confirmé
    Inscrit en
    Mars 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2003
    Messages : 88
    Par défaut Modifier constante sans recompiler
    Bonjour,

    Je developpe une application en java pour me former sur ce langage, et j'ai une question:
    J'utilise un fichier properties pour que l'utilisateur puisse configurer l'application. J'utilise des constantes pour definir les differentes options de ce properties. Est-il possible de mettre ces constantes dans un fichier a part, sans devoir recompiler le code a chaque fois que l'on souhaite modifier une constante ?

    Exemple de mon fichier properties
    Exemple de la classe contenant les constantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static final String USERNAME = "Name";
    Si je veux modifier le mot clef "Name" de mon fichier properties en "Nom", je serais obliger de modifier aussi la constante, et donc de recompiler. J'aimerais savoir s'il est possible de pouvoir faire ces modifications sans avoir a recompiler.

    Merci pour votre aide !

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    325
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 325
    Par défaut
    A moins d'utiliser un framework tiers (Spring par exemple pourrait apporter un peu de souplesse), je ne crois pas que ça soit possible.
    Il faudra toujours que tu aies une référence en dur dans le code.

    Si je me trompe et que quelqu'un a une solution à ce problème, je suis preneur !

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 152
    Par défaut
    Une technique possible, c'est d'attribuer une valeur à ta constante dans un construteur.Dans ce cas, la constante ne prend une valeur qu'à l'instanciation (donc après compilation)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class User
    {
        final String USERNAME;
        public User()
        {
            ...
            USERNAME = "name";
        }
    ...
    }

  4. #4
    Membre confirmé
    Inscrit en
    Mars 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2003
    Messages : 88
    Par défaut
    Citation Envoyé par @Ikey Voir le message
    Une technique possible, c'est d'attribuer une valeur à ta constante dans un construteur.Dans ce cas, la constante ne prend une valeur qu'à l'instanciation (donc après compilation)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class User
    {
        final String USERNAME;
        public User()
        {
            ...
            USERNAME = "name";
        }
    ...
    }
    Oui mais le compilateur aura deja transformer ma classe en ByteCode, donc je ne pourrais pas modifier le code, non ?

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    325
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 325
    Par défaut
    Citation Envoyé par @Ikey Voir le message
    Une technique possible, c'est d'attribuer une valeur à ta constante dans un construteur.Dans ce cas, la constante ne prend une valeur qu'à l'instanciation (donc après compilation)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class User
    {
        final String USERNAME;
        public User()
        {
            ...
            USERNAME = "name";
        }
    ...
    }
    Ca ne le dispensera pas de devoir recompiler s'il souhaite modifier le nom de sa propriété.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    325
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 325
    Par défaut
    Citation Envoyé par Sylk Voir le message
    Oui mais le compilateur aura deja transformer ma classe en ByteCode, donc je ne pourrais pas modifier le code, non ?
    C'est tout à fait ça, la solution proposée ne répond pas au problème.
    Comme ça à froid, si vraiment tu veux pouvoir adresser des propriétés (dans un fichier properties par exemple) et que tu veux pouvoir modifier les noms des propriétés dans ton fichier, et bien sur que l'application continue de fonctionner sans la recompiler, tu peux utiliser un fichier intermédiaire. Dans ce fichier tu peux avoir une correspondance entre la clef du fichier properties et la clef utilisée dans ton code.
    Ca déporte le problème et ajoute un fichier à maintenir mais au moins tu as un moyen de récupérer tes propriétés sans recompiler et ce, même si tu veux modifier les clefs.

    Le mieux étant quand même de se fixer une logique dans le choix des clefs, ça évite d'avoir à les changer après que l'appli soit compilée et livrée au client.

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 152
    Par défaut
    C'est fou ca! C'est juste un exemple du principe

    Classe user
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class User
    {
        final String USERNAME;
        public User(String name)
        {
            ...
            USERNAME = name;
        }
    ...
    }
    Programme de test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    import java.util.Scanner;
     
    public static void main(String[] args)
    {
            Scanner sc = new Scanner(System.in);
            String name = sc.next();
     
            User toto = new User(name);
            System.out.println(toto.USERNAME);
    }
    Alors la valeur de la constante est toujours attribuée lors de la compilation?

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 152
    Par défaut
    Si ce n'est pas assez clair autre exemple avec le fichier de propriétés.

    user.properties
    User.class
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import java.util.Locale;
    import java.util.ResourceBundle;
     
    public class User
    {
        final String USERNAME;
        private ResourceBundle resourceBundle;
     
        public User()
        {
            resourceBundle = ResourceBundle.getBundle("user");
            USERNAME = resourceBundle.getString("Username");
        }
    }
    J'ai comme l'impression que ca répond à la question.
    Ensuite tu utilises le pattern Singleton et le problème est réglé!

    Edit:
    J'anticipe la prochaine question.
    Pour modifier un fichier properties par ton programme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    String key = "Username";
    String value = "Momo";
     
    Properties properties = new Properties();
    try {		
    	String propertiesFilePath = ("user.properties");
    	FileInputStream fis = new FileInputStream(propertiesFilePath);
    	properties.load(fis);
    	properties.setProperty(key, value);
    	FileOutputStream fos = new FileOutputStream(propertiesFilePath);
    	properties.store(fos, null);
    	System.out.println("Mise à jour effectuée.");
    }
    catch(Exception e) {
    	System.out.println("Echec de la mise à jour.");
    }
    Je le redis si ce n'est pas clair, ce n'est qu'un exemple. J'ai codé en dur la variable value. En "mode programmtion réelle", tu recupérerais cette valeur d'un scanner ou d'un input graphique!
    A noter que pour que la modif prenne effet, il faut redémarrer l'application (redémarrer, pas recompiler!!), puisque ta constante a déjà une valeur, que tu ne peux pas modifier par définition, donc c'est la seule solution.
    Mais en utilisant un singleton, une constante n'est pas indispensable. Il suffit de créer une variable "username" privée, et d'utiliser des accesseurs. Enfin après c'est une question de gout et surtout de facilité d'utilisation.

    ==================================================
    Edit 2:
    Solution complète qui évitera les conneries que je peux lire.
    Le fichier .properties reste le même

    User.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public class User
    {
    	private static User user;
     
    	private String username;
    	private ResourceBundle resourceBundle;
     
    	private User()
    	{
    		resourceBundle = ResourceBundle.getBundle("user");
    		username = resourceBundle.getString("Username");
    	}
     
    	public static User getInstance()
    	{
    		if(user == null)
    		{
    			user = new User();
    		}
    		return user;
    	}
     
    	public void setUsername(String username)
    	{
    		this.username = username;
    	}
     
    	public String getUsername()
    	{
    		return username;
    	}
    }

    ProgTest.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public ProgTest
    {
    	public static void main(String[] args)
        { 
                    String key = "Username";
    		// Pour récupérer l'instance de l'objet User dans n'importe quelle classe, 
    		// il suffit d'écrire la ligne suivante :
    		// Ca évite les: User user = new User();
    		// ou de passer "user" en paramètres de contructeur en constructeur
    		User user = User.getInstance();
     
    		System.out.println("Nom avant modification récupéré du fichier properties: " + user.getUsername());
     
    		Scanner sc = new Scanner(System.in);
            String value = sc.next();
     
    		Properties properties = new Properties();
    		try 
    		{		
    			String propertiesFilePath = ("user.properties");
    			FileInputStream fis = new FileInputStream(propertiesFilePath);
    			properties.load(fis);
    			properties.setProperty(key, value);
    			FileOutputStream fos = new FileOutputStream(propertiesFilePath);
    			properties.store(fos, null);
    			user.setUsername(value);
    			System.out.println("Mise à jour effectuée.");
    		}
    		catch(Exception e) 
    		{
    			System.out.println("Echec de la mise à jour.");
    		}
     
    		System.out.println("Nom après modification: " + user.getUsername());
    	}
    }
    Sauf erreur, il ne manque que les "import".
    Tu peux tester. Le nom qui s'affichera à chaque démarrage du programme sera toujours le dernier saisit.
    C'est bien ce que tu voulais?!

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    325
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 325
    Par défaut
    c'est mieux

  10. #10
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Citation Envoyé par Sylk Voir le message
    J'utilise un fichier properties pour que l'utilisateur puisse configurer l'application. J'utilise des constantes pour definir les differentes options de ce properties. Est-il possible de mettre ces constantes dans un fichier a part, sans devoir recompiler le code a chaque fois que l'on souhaite modifier une constante ?
    Sans entrer dans une solution technique, quel est l'intérêt ? Dans ce "fichier a part", tu vas définir un mapping entre une propriété compréhensible par ton application et celle du fichier de conf. final. La clé dans ce fichier à part est aussi défini en tant que constante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Fichier à part :
    cle.dans.fichier.config.nom.utilisateur = name

  11. #11
    Membre confirmé
    Inscrit en
    Mars 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2003
    Messages : 88
    Par défaut
    Merci pour votre aide !

    L'interet est de pouvoir modifier le fichier properties sans avoir a recompiler l'application, chacun peut donc personnaliser son fichier properties.

    Merci

  12. #12
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Si quelqu'un veut personnaliser son fichier de properties, alors il faudra qu'il modifie 2 fichiers : le fichier de properties ET le fichier qui référence le nom qu'il a choisi pour telle ou telle propriété.
    C'est donc effectivement possible

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Modifier le Assembly Information sans recompiler
    Par Mast3rMind dans le forum C#
    Réponses: 1
    Dernier message: 15/10/2009, 09h13
  2. Réponses: 3
    Dernier message: 20/06/2007, 11h11
  3. Compiler un module sans recompiler tout le noyau
    Par khayyam90 dans le forum Administration système
    Réponses: 7
    Dernier message: 22/09/2005, 03h16
  4. Onglet version : modif sans recompiler
    Par Jerome0075 dans le forum Windows
    Réponses: 3
    Dernier message: 29/07/2004, 10h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo