2015-01-14 13 views
8

Sto provando a leggere le informazioni specifiche della distribuzione da un file delle proprietà nella mia cartella di configurazione di wildfly. Ho provato questo:wildfly: lettura delle proprietà dalla directory di configurazione

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

Ma a quanto pare questo non funziona poiché la cartella di configurazione non è più nel classpath. Ora non riesco a trovare un modo semplice per farlo. Il mio preferito sarebbe qualcosa di simile a questo: (! Uno senza OSGi)

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

L'unica soluzione che ho trovato sul web comporta finora fare il mio modulo di OSGi, ma credo che ci deve essere un modo più semplice per farlo . Qualcuno può mostrarmi come?

+0

Se il file si trova nella cartella di configurazione wildfly, allora è globale e non distribuzione specifica. Questo è un po 'di confusione ... –

+0

forse ho abusato del termine "specifica di implementazione". Il file si trova nella cartella wildfly/standalone/configuration. – EasterBunnyBugSmasher

+0

Se ricordo chiaramente, avevo le mie configurazioni sotto questa cartella, e io semplicemente facendo File ("myfile.properties") risolto su questo percorso (immagino che questa potrebbe essere la directory di lavoro per jboss) – maress

risposta

26

Se si desidera leggere esplicitamente un file dalla directory di configurazione (ad esempio $WILDFLY_HOME/standalone/configuration o domain/configuration), esiste una proprietà di sistema con il percorso. Basta fare System.getProperty("jboss.server.config.dir"); e aggiungere il nome del file a quello per ottenere il file.

Non avrebbe letto come una risorsa, però, così ...

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

Poi il file sarebbe stato caricato per voi.

Inoltre, poiché WildFly non viene più fornito con il supporto OSGi, non so come sia possibile creare un modulo OSGi qui.

+0

così semplice, perché non l'ho inventato io stesso? Stavo pensando al classpath. – EasterBunnyBugSmasher

+0

L'inputstream rimane aperto. non passare direttamente per le proprietà.carica – Wender

+1

Hai ragione @Wender ma onestamente l'ho inteso solo come pseudo codice. –

4

La cosa più semplice che si può fare è quello di eseguire standalone.sh con un'opzione -P riferimento del file delle proprietà (è necessario un URL file:/path/to/my.properties, o mettere il file in $WILDFLY_HOME/bin).

Quindi tutte le proprietà del file verranno caricate come proprietà di sistema.

Per l'iniezione di proprietà di configurazione nelle classi dell'applicazione, dare un'occhiata a DeltaSpike Configuration, che supporta diverse origini di proprietà come proprietà di sistema, variabili di ambiente, voci JNDI e nasconde la sorgente specifica dall'applicazione.

In alternativa, per evitare di impostare le proprietà di sistema (che saranno globali nel senso di essere visibili a tutte le applicazioni distribuite nell'istanza WildFly), è anche possibile definire un'origine proprietà personalizzata per DeltaSpike che legge un file di proprietà da qualsiasi posizione specificata e queste proprietà saranno locali alla tua applicazione.

+0

quindi ho trovato questo snippet sul sito deltaspike: @Inject @InjectableResource ("myfile.properties") private InputStream inputStream; Non ho ancora scaricato DeltaSpike, quindi non ho potuto testarlo ancora. La mia domanda è: come fa DeltaSpike a leggere questo file dalla cartella di configurazione se la cartella di configurazione non si trova nel classpath e non ho configurato dove cercare? – EasterBunnyBugSmasher

+0

WildFly legge il file, non DeltaSpike - DeltaSpike legge le proprietà di sistema impostate da WildFly. Per leggere il file tramite DeltaSpike (ultimo paragrafo della mia risposta), è necessario implementare un'origine di configurazione DeltaSpike personalizzata e registrarla con DeltaSpike. Dovresti usare un percorso file, non il classpath per accedere al file. –

+0

grazie per l'input, ma un po 'troppo complicato per me. – EasterBunnyBugSmasher

6

Ecco un esempio completo che utilizza solo CDI, preso da questo site.

  1. creare e popolare un file di proprietà all'interno della cartella di configurazione wildfly

    $ echo 'docs.dir=/var/documents' >> .standalone/configuration/application.properties 
    
  2. Aggiungere una proprietà di sistema per il file di configurazione wildfly.

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

Ciò aggiungerà il seguente al file di configurazione del server (standalone.xml o dominio.xml):

<system-properties> 
    <property name="application.properties" value="${jboss.server.config.dir}/application.properties"/> 
</system-properties> 
  1. Creare bean di sessione Singleton che carica e memorizza le proprietà di vasta applicazione

    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. Creare il CDI Qualifier. Useremo questa annotazione sulle variabili Java che desideriamo inserire.

    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. Creare il metodo produttore; questo genera l'oggetto da iniettare

    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. Infine iniettare la proprietà in uno dei vostri fagioli 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; 
        } 
    } 
    
0

Sembra che il problema che si sta tentando di risolvere sta gestendo diversi (ma probabilmente simili) file di configurazione per l'esecuzione dell'applicazione in ambienti diversi (ad es. produzione, controllo qualità o anche clienti diversi). In questo caso, dai un'occhiata a Jfig http://jfig.sourceforge.net/. Eviterebbe la necessità di memorizzare i file delle proprietà al di fuori del classpath (ma si potrebbe ancora).

Ciò che è necessario è un approccio gerarchico ai file di configurazione. Il novanta percento dei valori di configurazione che non cambiano può essere mantenuto in un file di base. L'altro dieci percento (o meno) può essere mantenuto nel proprio file di configurazione distinto. In fase di esecuzione, i file vengono sovrapposti l'uno sull'altro per fornire una configurazione flessibile e gestibile. Ad esempio, in un ambiente di sviluppo myhost.config.xml si combina con dev.config.xml e base.config.xml per formare la mia configurazione univoca.

Ogni file di configurazione può quindi essere mantenuto nel controllo di versione in quanto hanno nomi univoci. Solo i file di base devono essere modificati quando i valori di base cambiano, ed è facile vedere la differenza tra le versioni. Un altro importante vantaggio è che le modifiche al file di configurazione di base verranno sottoposte a test esaurienti prima della distribuzione.

0
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){ 
    } 
} 
Problemi correlati