我正在尝试从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模块,但我相信必须有一种更简单的方法(没有OSGi!)。谁能告诉我怎么样?
答案 0 :(得分:32)
如果要显式读取配置目录中的文件(例如$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模块对您有所帮助。
答案 1 :(得分:7)
以下是仅使用CDI的完整示例,取自此site。
在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)
这会将以下内容添加到您的服务器配置文件(standalone.xml或domain.xml)中:
<system-properties>
<property name="application.properties" value="${jboss.server.config.dir}/application.properties"/>
</system-properties>
创建加载和存储应用程序范围属性的单例会话bean
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 bean
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;
}
}
答案 2 :(得分:4)
您可以做的最简单的事情是使用引用您的属性文件的standalone.sh
选项运行-P
(您需要网址file:/path/to/my.properties
,或者将文件放在$WILDFLY_HOME/bin
中)。
然后,文件中的所有属性都将作为系统属性加载。
要将配置属性注入应用程序类,请查看DeltaSpike Configuration,它支持不同的属性源,如系统属性,环境变量,JNDI条目,并隐藏应用程序中的特定源。
或者,为了避免设置系统属性(在部署到WildFly实例的所有应用程序都可见的情况下将是全局属性),您还可以为DeltaSpike定义从任何给定位置读取属性文件的自定义属性源,这些属性将是您的应用程序的本地属性。
答案 3 :(得分:0)
听起来您要解决的问题是管理不同(但可能类似)的配置文件,以便在不同环境(即生产,QA甚至不同客户)中运行您的应用程序。如果是这种情况,请查看Jfig http://jfig.sourceforge.net/。它可以避免在类路径之外存储属性文件的需要(但你仍然可以)。
需要的是配置文件的分层方法。可以在基本文件中维护未更改的百分之九十的配置值。其他百分之十(或更少)可以在其自己的不同配置文件中维护。在运行时,文件彼此叠加,以提供灵活,可管理的配置。例如,在开发环境中,myhost.config.xml与dev.config.xml和base.config.xml组合以形成我的唯一配置。
然后可以在版本控制中维护每个配置文件,因为它们具有唯一的名称。基值更改时,只需要修改基本文件,并且很容易看到版本之间的差异。另一个主要好处是在部署之前将对基本配置文件的更改进行详尽测试。
答案 4 :(得分: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){
}
}
答案 5 :(得分:0)
为避免此类问题,问题在于在VM参数中设置jboss.server.config.dir
如下:
-Djboss.server.config.dir="[jboss_repository]/server/[default-all-standard-standalone]/conf" –server
答案 6 :(得分:0)
如果您拥有standalone.xml属性:
<property name="my.properties" value="propertyValue"/>
您可以通过以下方式随意阅读它:
static final String MY_PROPERTY = System.getProperty("my.properties");
或者如果您在web.xml中指定上下文参数,例如:
<context-param>
<param-name>MyProperty</param-name>
<param-value>MyPropertyValue</param-value>
</context-param>
您可以在Java bean中阅读它:
String myProperty= getServletContext().getInitParameter("MyProperty");
答案 7 :(得分:0)
如果您的应用程序部署在 MicroProfile 兼容环境中,标准解决方案是将属性放置在 ConfigSource 元素(例如 microprofile-config.properties 文件)或自定义定义的 ConfigSource 中。 WildFly 支持开箱即用的 MicroProfile API。
的示例