web-dev-qa-db-fra.com

wildfly: lecture des propriétés depuis le répertoire de configuration

J'essaie de lire les informations spécifiques au déploiement à partir d'un fichier de propriétés dans mon dossier de configuration wildfly. J'ai essayé ceci:

@Singleton
@Startup
public class DeploymentConfiguration {

  protected Properties props;

  @PostConstruct
  public void readConfig() {

    props = new Properties();
    try {
      props.load(getClass().getClassLoader().getResourceAsStream("my.properties"));
    } catch (IOException e) {
      // ... whatever
    }
  }

Mais apparemment, cela ne fonctionne pas car le dossier de configuration ne se trouve plus dans le chemin de classe. Maintenant, je ne peux pas trouver un moyen facile de le faire. Mon préféré serait quelque chose comme ça:

@InjectProperties("my.properties")
protected Properties props;

La seule solution que j'ai trouvée jusqu'à présent sur le Web consiste à créer mon propre module OSGi, mais je pense qu'il doit exister un moyen plus simple de le faire (un sans OSGi!). Quelqu'un peut-il me montrer comment?

11

Si vous souhaitez explicitement lire un fichier à partir du répertoire de configuration (par exemple, $WILDFLY_HOME/standalone/configuration ou domain/configuration), une propriété système contenant le chemin d'accès Faites simplement System.getProperty("jboss.server.config.dir"); et ajoutez votre nom de fichier à celui-ci pour obtenir le fichier.

Cependant, vous ne le liriez pas comme une ressource, alors ...

String fileName = System.getProperty("jboss.server.config.dir") + "/my.properties";
try(FileInputStream fis = new FileInputStream(fileName)) {
  properties.load(fis);
}

Ensuite, le fichier serait chargé pour vous.

De plus, comme WildFly n’a plus de support OSGi, je ne sais pas comment créer un module OSGi pourrait vous aider ici.

29
John Ament

Voici un exemple complet utilisant seulement CDI, tiré de ce site .

  1. Créer et remplir un fichier de propriétés dans le dossier de configuration WildFly

    $ echo 'docs.dir=/var/documents' >> .standalone/configuration/application.properties
    
  2. Ajoutez une propriété système au fichier de configuration WildFly.

    $ ./bin/jboss-cli.sh --connect
    [standalone@localhost:9990 /] /system-property=application.properties:add(value=${jboss.server.config.dir}/application.properties)
    

Ceci ajoutera les éléments suivants au fichier de configuration de votre serveur (standalone.xml ou domain.xml):

<system-properties>
    <property name="application.properties" value="${jboss.server.config.dir}/application.properties"/>
</system-properties>
  1. Créez le bean singleton session qui charge et stocke les propriétés de l'application

    import Java.io.File;
    import Java.io.FileInputStream;
    import Java.io.IOException;
    import Java.util.HashMap;
    import Java.util.Map;
    import Java.util.Properties;
    
    import javax.annotation.PostConstruct;
    import javax.ejb.Singleton;
    
    @Singleton
    public class PropertyFileResolver {
    
        private Logger logger = Logger.getLogger(PropertyFileResolver.class);
        private String properties = new HashMap<>();
    
        @PostConstruct
        private void init() throws IOException {
    
            //matches the property name as defined in the system-properties element in WildFly
            String propertyFile = System.getProperty("application.properties");
            File file = new File(propertyFile);
            Properties properties = new Properties();
    
            try {
                properties.load(new FileInputStream(file));
            } catch (IOException e) {
                logger.error("Unable to load properties file", e);
            }
    
            HashMap hashMap = new HashMap<>(properties);
            this.properties.putAll(hashMap);
        }
    
        public String getProperty(String key) {
            return properties.get(key);
        }
    }
    
  2. Créez le qualificatif CDI. Nous allons utiliser cette annotation sur les variables Java dans lesquelles nous souhaitons nous injecter.

    import Java.lang.annotation.ElementType;
    import Java.lang.annotation.Retention;
    import Java.lang.annotation.RetentionPolicy;
    import Java.lang.annotation.Target;
    
    import javax.inject.Qualifier;
    
    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR })
    public @interface ApplicationProperty {
    
        // no default meaning a value is mandatory
        @Nonbinding
        String name();
    }
    
  3. Créer la méthode du producteur; cela génère l'objet à injecter

    import javax.enterprise.inject.Produces;
    import javax.enterprise.inject.spi.InjectionPoint;
    import javax.inject.Inject;
    
    public class ApplicaitonPropertyProducer {
    
        @Inject
        private PropertyFileResolver fileResolver;
    
        @Produces
        @ApplicationProperty(name = "")
        public String getPropertyAsString(InjectionPoint injectionPoint) {
    
            String propertyName = injectionPoint.getAnnotated().getAnnotation(ApplicationProperty.class).name();
            String value = fileResolver.getProperty(propertyName);
    
            if (value == null || propertyName.trim().length() == 0) {
                throw new IllegalArgumentException("No property found with name " + value);
            }
            return value;
        }
    
        @Produces
        @ApplicationProperty(name="")
        public Integer getPropertyAsInteger(InjectionPoint injectionPoint) {
    
            String value = getPropertyAsString(injectionPoint);
            return value == null ? null : Integer.valueOf(value);
        }
    }
    
  4. Injectez enfin la propriété dans l’un de vos haricots CDI

    import javax.ejb.Stateless;
    import javax.inject.Inject;
    
    @Stateless
    public class MySimpleEJB {
    
        @Inject
        @ApplicationProperty(name = "docs.dir")
        private String myProperty;
    
        public String getProperty() {
            return myProperty;
        }
    }
    
6
Chris Ritchie

La solution la plus simple consiste à exécuter standalone.sh avec une option -P référençant votre fichier de propriétés (vous avez besoin d'une URL file:/path/to/my.properties ou mettez le fichier dans $WILDFLY_HOME/bin).

Toutes les propriétés du fichier seront ensuite chargées en tant que propriétés système.

Pour injecter des propriétés de configuration dans vos classes d’application, consultez DeltaSpike Configuration , qui prend en charge différentes sources de propriétés, telles que les propriétés système, les variables d’environnement, les entrées JNDI et masque la source spécifique de votre application.

Sinon, pour éviter de définir des propriétés système (qui seront globales dans le sens où elles seront visibles par toutes les applications déployées sur votre instance WildFly), vous pouvez également définir une source de propriétés personnalisées pour que DeltaSpike lise un fichier de propriétés à partir de n'importe quel emplacement donné. sera local à votre application.

4
Harald Wellmann

Il semble que le problème que vous essayez de résoudre concerne la gestion de fichiers de configuration différents (mais probablement similaires) pour exécuter votre application dans différents environnements (c.-à-d. Production, Assurance qualité ou même des clients différents). Si c'est le cas, jetez un coup d'œil à Jfig http://jfig.sourceforge.net/ . Cela éliminerait la nécessité de stocker des fichiers de propriétés en dehors de votre chemin de classe (mais vous le pouvez toujours).

Ce qu'il faut, c'est une approche hiérarchique des fichiers de configuration. Les quatre-vingt-dix pour cent des valeurs de configuration qui ne changent pas peuvent être conservées dans un fichier de base. Les dix pour cent restants (ou moins) peuvent être conservés dans leur propre fichier de configuration distinct. Au moment de l'exécution, les fichiers sont superposés pour fournir une configuration flexible et gérable. Par exemple, dans un environnement de développement, myhost.config.xml se combine avec dev.config.xml et base.config.xml pour former ma configuration unique.

Chaque fichier de configuration peut ensuite être maintenu dans le contrôle de version car ils ont des noms uniques. Seuls les fichiers de base doivent être modifiés lorsque les valeurs de base changent, et il est facile de voir la différence entre les versions. Un autre avantage majeur est que les modifications apportées au fichier de configuration de base seront testées de manière exhaustive avant le déploiement.

0
Sr Bruno
InputStream in = null;
File confDir = new File(System.getProperty("jboss.server.config.dir"));
File fileProp = new File(confDir, "my.properties");

try{
    //teste fileProp.exists etc.

    in = new FileInputStream(fileProp);
    Properties properties = new Properties();
    properties.load(in);

    //You should throws or handle FileNotFoundException and IOException
}finally{
    try{
        in.close();
    }catch(Exception ignored){
    }
}
0
Wender