wake-up-neo.net

wildfly: Eigenschaften aus dem Konfigurationsverzeichnis lesen

Ich versuche, bereitstellungsspezifische Informationen aus einer Eigenschaftendatei in meinem Wildfly-Konfigurationsordner zu lesen. Ich habe das versucht:

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

Aber anscheinend funktioniert das nicht, da sich der Konfigurationsordner nicht mehr im Klassenpfad befindet. Jetzt kann ich keinen einfachen Weg finden. Mein Favorit wäre so etwas:

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

Die einzige Lösung, die ich bisher im Web gefunden habe, besteht darin, mein eigenes OSGi-Modul zu erstellen, aber ich glaube, es muss einen einfacheren Weg geben (eine ohne OSGi!). Kann mir jemand zeigen wie?

11

Wenn Sie eine Datei explizit aus dem Konfigurationsverzeichnis lesen möchten (z. B. $WILDFLY_HOME/standalone/configuration oder domain/configuration), gibt es eine Systemeigenschaft mit dem Pfad. Machen Sie einfach System.getProperty("jboss.server.config.dir"); und hängen Sie Ihren Dateinamen an, um die Datei zu erhalten.

Sie würden es jedoch nicht als Ressource lesen, also ...

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

Dann würde die Datei für Sie geladen werden.

Da WildFly nicht mehr mit OSGi-Support ausgeliefert wird, weiß ich nicht, wie die Erstellung eines OSGi-Moduls Ihnen hier helfen würde.

29
John Ament

Hier ist ein vollständiges Beispiel, das nur CDI verwendet, von dieser site .

  1. Erstellen und füllen Sie eine Eigenschaftendatei im WildFly-Konfigurationsordner

    $ echo 'docs.dir=/var/documents' >> .standalone/configuration/application.properties
    
  2. Fügen Sie der WildFly-Konfigurationsdatei eine Systemeigenschaft hinzu.

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

Dies fügt der Serverkonfigurationsdatei (standalone.xml oder domain.xml) Folgendes hinzu:

<system-properties>
    <property name="application.properties" value="${jboss.server.config.dir}/application.properties"/>
</system-properties>
  1. Erstellen Sie die Singleton-Session-Bean, die die anwendungsweiten Eigenschaften lädt und speichert

    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. Erstellen Sie den CDI-Qualifier. Wir werden diese Annotation für die Java-Variablen verwenden, in die wir injizieren möchten.

    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. Erstellen Sie die Producer-Methode. Dadurch wird das zu injizierende Objekt generiert

    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. Zum Schluss injizieren Sie die Eigenschaft in eine Ihrer CDI-Beans

    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

Am einfachsten können Sie standalone.sh mit einer -P-Option ausführen, die auf Ihre Eigenschaftendatei verweist (Sie benötigen einen URL file:/path/to/my.properties oder fügen die Datei in $WILDFLY_HOME/bin ein).

Dann werden alle Eigenschaften aus der Datei als Systemeigenschaften geladen.

Informationen zum Einfügen von Konfigurationseigenschaften in Ihre Anwendungsklassen finden Sie in DeltaSpike Configuration , das verschiedene Eigenschaftenquellen wie Systemeigenschaften, Umgebungsvariablen und JNDI-Einträge unterstützt und die jeweilige Quelle aus Ihrer Anwendung verbirgt.

Um zu vermeiden, dass Systemeigenschaften festgelegt werden (die in dem Sinne global sind, dass sie für alle auf Ihrer WildFly-Instanz bereitgestellten Anwendungen sichtbar sind), können Sie alternativ auch eine benutzerdefinierte Eigenschaftsquelle für DeltaSpike definieren, die eine Eigenschaftendatei von einem bestimmten Speicherort und diese Eigenschaften liest wird für Ihre Anwendung lokal sein.

4
Harald Wellmann

Es hört sich so an, als ob das Problem, das Sie lösen möchten, darin besteht, verschiedene (aber wahrscheinlich ähnliche) Konfigurationsdateien für die Ausführung Ihrer Anwendung in verschiedenen Umgebungen (z. B. Produktion, Qualitätssicherung oder sogar verschiedenen Kunden) zu verwalten. Wenn dies der Fall ist, werfen Sie einen Blick auf Jfig http://jfig.sourceforge.net/ . Das Speichern von Eigenschaftendateien außerhalb Ihres Klassenpfads entfällt (aber Sie könnten es trotzdem tun).

Was benötigt wird, ist ein hierarchischer Ansatz für Konfigurationsdateien. Die neunzig Prozent der Konfigurationswerte, die sich nicht ändern, können in einer Basisdatei verwaltet werden. Die anderen zehn Prozent (oder weniger) werden möglicherweise in ihrer eigenen Konfigurationsdatei verwaltet. Zur Laufzeit werden die Dateien übereinander gelegt, um eine flexible, verwaltbare Konfiguration bereitzustellen. In einer Entwicklungsumgebung wird myhost.config.xml beispielsweise mit dev.config.xml und base.config.xml kombiniert, um meine eindeutige Konfiguration zu bilden.

Jede Konfigurationsdatei kann dann in der Versionskontrolle verwaltet werden, da sie eindeutige Namen hat. Nur die Basisdateien müssen geändert werden, wenn sich die Basiswerte ändern, und es ist leicht, den Unterschied zwischen den Versionen zu erkennen. Ein weiterer wichtiger Vorteil ist, dass Änderungen an der Basiskonfigurationsdatei vor der Bereitstellung ausführlich getestet werden.

0
Sr Bruno

Um dieses Problem zu vermeiden, müssen Sie jboss.server.config.dir in VM Argumenten wie diesen:

-Djboss.server.config.dir="[jboss_repository]/server/[default-all-standard-standalone]/conf" –server

Wenn Sie eine eigenständige.xml-Eigenschaft haben:

<property name="my.properties" value="propertyValue"/>

sie können es leicht lesen mit:

static final String MY_PROPERTY = System.getProperty("my.properties");

Oder wenn Sie den Kontextparameter in der Datei web.xml wie folgt angeben:

<context-param>
    <param-name>MyProperty</param-name>
    <param-value>MyPropertyValue</param-value>
</context-param>

Sie können es in Java bean lesen:

String myProperty= getServletContext().getInitParameter("MyProperty");
0
stakahop
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