web-dev-qa-db-ja.com

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モジュールを作成することですが、それを行うにはもっと簡単な方法(OSGiがないもの)が必要だと思います。誰も方法を教えてもらえますか?

13

構成ディレクトリからファイルを明示的に読み取りたい場合(例、_$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モジュールの作成がここでどのように役立つかわかりません。

33
John Ament

これは、 site から取得した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)
    

これにより、サーバー構成ファイル(standalone.xmlまたはdomain.xml)に以下が追加されます。

<system-properties>
    <property name="application.properties" value="${jboss.server.config.dir}/application.properties"/>
</system-properties>
  1. アプリケーション全体のプロパティをロードおよび保存するシングルトンセッション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);
        }
    }
    
  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 Beanの1つにプロパティを注入します

    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;
        }
    }
    
7
Chris Ritchie

できる最も簡単なことは、standalone.sh とともに -Pプロパティファイルを参照するオプション(URLが必要file:/path/to/my.properties、または$WILDFLY_HOME/bin)。

次に、ファイルのすべてのプロパティがシステムプロパティとしてロードされます。

構成プロパティをアプリケーションクラスに注入するには、システムプロパティ、環境変数、JNDIエントリなどのさまざまなプロパティソースをサポートし、アプリケーションから特定のソースを非表示にする DeltaSpike Configuration をご覧ください。

または、システムプロパティ(WildFlyインスタンスにデプロイされたすべてのアプリケーションに表示されるという意味でグローバルになる)の設定を回避するために、特定の場所からプロパティファイルを読み取るDeltaSpikeのカスタムプロパティソースを定義することもできます。アプリケーションのローカルになります。

6
Harald Wellmann

解決しようとしている問題は、異なる環境(実稼働環境、QA、さらには異なる顧客)でアプリケーションを実行するための異なる(ただしおそらく類似の)構成ファイルを管理しているようです。その場合は、Jfig http://jfig.sourceforge.net/ をご覧ください。クラスパスの外部にプロパティファイルを保存する必要がなくなります(ただし、可能です)。

必要なのは、構成ファイルへの階層的なアプローチです。変更されない構成値の90%は、ベースファイルで維持できます。他の10パーセント(またはそれ以下)は、独自の個別の構成ファイルで維持できます。実行時に、ファイルは互いの上に階層化され、柔軟で管理可能な構成を提供します。たとえば、開発環境では、myhost.config.xmlはdev.config.xmlおよびbase.config.xmlと組み合わされて独自の構成を形成します。

各構成ファイルは、一意の名前を持っているため、バージョン管理で管理できます。基本値を変更する場合は、基本ファイルのみを変更する必要があり、バージョン間の違いを簡単に確認できます。もう1つの大きな利点は、展開前に基本構成ファイルへの変更が徹底的にテストされることです。

0
Sr Bruno

この種の問題を回避するには、問題はjboss.server.config.dir in VMそのような引数:

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

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");
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