wildfly: чтение свойств из каталога конфигурации

Я пытаюсь прочитать конкретную информацию о развертывании из файла свойств в папке конфигурации wildfly. Я попробовал:

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

но, по-видимому, это не работает, так как папка конфигурации больше не находится в пути к классам. Теперь я не могу найти простой способ сделать это. Моим любимым было бы что-то вроде этого:

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

единственное решение, которое я нашел в интернете до сих пор, включает в себя создание моего собственного модуля OSGi, но я считаю, что должен быть более простой способ сделать он (один без Осги!). Кто-нибудь может показать мне как?

5 ответов


если вы хотите явно прочитать файл из каталога конфигурации (например,$WILDFLY_HOME/standalone/configuration или domain/configuration) есть системное свойство с путем в нем. Просто сделай System.getProperty("jboss.server.config.dir"); и добавьте к этому имя файла, чтобы получить файл.

вы бы не читали его как ресурс, хотя, так что...

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

затем файл будет загружен для вас.

кроме того, поскольку WildFly больше не поставляется с поддержкой OSGi, я не знаю, как создание модуля OSGi поможет вам здесь.


вот полный пример использования только CDI, взятый из этого сайт.

  1. создать и заполнить файл свойств внутри папки конфигурации WildFly

    $ echo 'docs.dir=/var/documents' >> .standalone/configuration/application.properties
    
  2. добавьте системное свойство в файл конфигурации WildFly.

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

это добавит следующее в файл конфигурации сервера (автономный.xml или домен.XML-код):

<system-properties>
    <property name="application.properties" value="${jboss.server.config.dir}/application.properties"/>
</system-properties>
  1. создайте одноэлементный компонент сеанса, который загружает и сохраняет широкие свойства приложения

    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. создайте квалификатор CDI. Мы будем использовать эту аннотацию для переменных Java, которые мы хотим ввести.

    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. создайте метод производителя; это генерирует объект, который будет введен

    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. наконец впрысните свойство в одно из ваши 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;
        }
    }
    

самое простое, что вы можете сделать, это запустить standalone.sh с -P опция, ссылающаяся на ваш файл свойств (вам нужен URL file:/path/to/my.properties, или поместите файл в $WILDFLY_HOME/bin).

тогда все свойства из файла будут загружены как системные свойства.

для ввода свойств конфигурации в классы приложений, посмотрите на Конфигурация DeltaSpike, который поддерживает различные источники свойств, такие как системные свойства, переменные среды, JNDI записи и скрывает конкретный источник из приложения.

кроме того, чтобы избежать установки системных свойств (которые будут глобальными в том смысле, что будут видны всем приложениям, развернутым в вашем экземпляре WildFly), вы также можете определить пользовательский источник свойств для DeltaSpike, считывающего файл свойств из любого заданного местоположения, и эти свойства будут локальными для вашего приложения.


похоже, что проблема, которую вы пытаетесь решить, - это управление различными (но, вероятно, похожими) файлами конфигурации для запуска вашего приложения в разных средах (т. е., производство, QA или даже разные клиенты). Если это так, взгляните на Jfighttp://jfig.sourceforge.net/ . Это избавит вас от необходимости хранить файлы свойств вне вашего пути к классам (но вы все равно можете).

необходим иерархический подход к конфигурационный файл. Девяносто процентов значений конфигурации, которые не изменяются, можно сохранить в базовом файле. Остальные десять процентов (или меньше) могут поддерживаться в их собственном файле конфигурации. Во время выполнения файлы накладываются друг на друга для обеспечения гибкой и управляемой конфигурации. Например, в среде разработки myhost.конфиг.xml сочетается с dev.конфиг.xml и база.конфиг.xml для формирования моей уникальной конфигурации.

каждой конфигурации файл может затем поддерживаться в системе управления версиями, поскольку они имеют уникальные имена. Только базовые файлы должны быть изменены при изменении базовых значений, и легко увидеть разницу между версиями. Другим важным преимуществом является то, что изменения в базовом файле конфигурации будут тщательно протестированы перед развертыванием.


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){
    }
}