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, взятый из этого сайт.
-
создать и заполнить файл свойств внутри папки конфигурации WildFly
$ echo 'docs.dir=/var/documents' >> .standalone/configuration/application.properties
-
добавьте системное свойство в файл конфигурации 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>
-
создайте одноэлементный компонент сеанса, который загружает и сохраняет широкие свойства приложения
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); } }
-
создайте квалификатор 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(); }
-
создайте метод производителя; это генерирует объект, который будет введен
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); } }
-
наконец впрысните свойство в одно из ваши 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){
}
}