web-dev-qa-db-ja.com

Spring Boot:任意のディレクトリで外部のapplication.propertiesファイルをファットjarで使用できますか?

複数のapplication.propertiesファイルを持つことは可能ですか? (EDIT:この質問はタイトルの質問に進化したことに注意してください。)

2つのファイルを作成しようとしました。

  • 最初のものは、アプリケーションJarのルートフォルダにあります。
  • 2つ目は、クラスパスで指定されたディレクトリ上にあります。

2つのファイルは両方とも「application.properties」という名前です。

両方のファイルの内容を「マージ」することは可能ですか? (および2番目のプロパティ値が最初のプロパティ値をオーバーライドします)または、1つのファイルがある場合、他のファイルは無視されますか?

UPDATE 1:コンテンツを「マージ」することが可能です。昨日は最初のものが無視されたように見えましたが、それは何かが壊れたためだと思われます。今ではうまく機能します。

UPDATE 2:また戻ってきました!ここでも、2つのファイルのうち1つだけが適用されています。奇妙なことです... Spring Tool Suiteを使用してアプリjarファイルを作成した後に開始しました。また、Jarバージョンは常に2つ目(クラスパス内)を無視するようですが、STSで実行される拡張バージョンの動作はさまざまです。どこから調査を開始できますか?

更新3

Jarバージョンの動作は実際には正しいものでした。これはJava.exeの仕様です。 -jarオプションを指定すると、Java.exeは-classpathオプションとCLASSPATH環境変数の両方を無視し、クラスパスにはjarファイルのみが含まれます。したがって、クラスパス上の2番目のapplication.propertiesファイルは無視されます。

さて、クラスパス上の2番目のapplication.propertiesをロードするにはどうすればよいですか?

更新4

-jarオプションを使用しながら、外部パスにapplication.propertiesファイルを読み込むことができました。

キーはPropertiesLauncherでした。

PropertiesLauncherを使用するには、pom.xmlファイルを次のように変更する必要があります。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>  <!-- added -->
                <layout>Zip</layout> <!-- to use PropertiesLaunchar -->
            </configuration>
        </plugin>
    </plugins>
</build>

このために、次のStackOverflowの質問を参照しました: spring boot properties launcher not use 。ところで、Spring Boot Mavenプラグインドキュメント( http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/repackage-mojo.html )、そこにPropertiesLauncherが使用されるZipトリガーを指定することは言及されていません。 (おそらく別の文書で?)

Jarファイルが作成された後、jarのMETA-INF/MENIFEST.MFのMain-Classプロパティを調べると、PropertiesLauncherが使用されていることがわかりました。

これで、次のようにjarを実行できます(Windowsの場合):

Java -Dloader.path=file:///C:/My/External/Dir,MyApp-0.0.1-SNAPSHOT.jar -jar MyApp-0.0.1-SNAPSHOT.jar

アプリケーションjarファイルはloader.pathに含まれていることに注意してください。

これで、C:\ My\External\Dir\configのapplication.propertiesファイルがロードされます。

おまけとして、そのディレクトリ内のファイル(たとえば、静的htmlファイル)も、ローダーパスにあるため、jarからアクセスできます。

UPDATE 2に記載されている非jar(拡張)バージョンについては、クラスパスの順序に問題がある可能性があります。

(ところで、私は質問のタイトルをこの問題により特定のものに変更しました。)

51
zeodtr

-jarオプションを使用しながら、外部パスにapplication.propertiesファイルを読み込むことができました。

キーはPropertiesLauncherでした。

PropertiesLauncherを使用するには、pom.xmlファイルを次のように変更する必要があります。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>  <!-- added -->
                <layout>Zip</layout> <!-- to use PropertiesLaunchar -->
            </configuration>
        </plugin>
    </plugins>
</build>

このために、次のStackOverflowの質問を参照しました: spring boot properties launcher not use 。ところで、Spring Boot Mavenプラグインドキュメント( http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/repackage-mojo.html )、そこにPropertiesLauncherが使用されるZipトリガーを指定することは言及されていません。 (おそらく別の文書で?)

Jarファイルが作成された後、jarのMETA-INF/MENIFEST.MFのMain-Classプロパティを調べると、PropertiesLauncherが使用されていることがわかりました。

これで、次のようにjarを実行できます(Windowsの場合):

Java -Dloader.path=file:///C:/My/External/Dir,MyApp-0.0.1-SNAPSHOT.jar -jar MyApp-0.0.1-SNAPSHOT.jar

アプリケーションjarファイルはloader.pathに含まれていることに注意してください。

これで、C:\ My\External\Dir\configのapplication.propertiesファイルがロードされます。

おまけとして、そのディレクトリ内のファイル(たとえば、静的htmlファイル)も、ローダーパスにあるため、jarからアクセスできます。

UPDATE 2に記載されている非jar(拡張)バージョンについては、クラスパスの順序に問題がある可能性があります。

9
zeodtr

Spring Bootのデフォルトを変更していない場合(@EnableAutoConfigurationまたは@SpringBootApplicationを使用していて、プロパティソースの処理を変更していない場合)、次の順序でプロパティを検索します(最高のオーバーライドが最低):

  1. 現在のディレクトリの/configサブディレクトリ
  2. 現在のディレクトリ
  3. classpath/configパッケージ
  4. クラスパスのルート

上記のリストは、ドキュメントの this 部分に記載されています

つまり、たとえばapplication.propertiesの下にあるsrc/resourcesのプロパティが見つかった場合、application.propertiesディレクトリの/configにある同じ名前のプロパティによって上書きされます。パッケージ化されたjarの「次」です。

Spring Bootで使用されるこのデフォルトの順序により、構成の外部化が非常に簡単になり、アプリケーションを複数の環境(開発、ステージング、運用、クラウドなど)で簡単に構成できます。

プロパティの読み取り用にSpring Bootが提供する機能のセット全体を確認するには(ヒント:application.propertiesからの読み取りよりもはるかに多くの機能があります) this ドキュメントの一部を確認してください。

上記の短い説明または完全なドキュメントからわかるように、Spring Bootアプリは非常にDevOpsフレンドリーです!

44
geoand

ここではすべてドキュメントで説明されています。

http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

これは、これが優先順位であることを説明しています。

  • 現在のディレクトリの/ configサブディレクトリ。
  • 現在のディレクトリ
  • クラスパス/ configパッケージ
  • クラスパスのルート

また、次のようなオーバーライド用の追加のプロパティファイルを定義できることも示しています。

Java -jar myproject.jar 
    --spring.config.location=classpath:/overrides.properties

spring.config.locationを使用する場合、application.propertiesのデフォルトの場所もすべて含まれます。これは、application.propertiesにデフォルト値を設定し、特定の環境の必要に応じてオーバーライドできることを意味します。

16
Steve

次のように、外部プロパティファイルのパスを使用して、スプリングブートアプリケーションを起動できます。

Java -jar {jar-file-name}.jar 
--spring.config.location=file:///C:/{file-path}/{file-name}.properties
8
kk.
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <layout>Zip</layout> 
            </configuration>
        </plugin>
    </plugins>
</build>

Java -Dloader.path=file:///absolute_path/external.jar -jar example.jar
2

Mavenインストールを使用してスプリングブートjarを作成し、プロパティファイルやlibフォルダーなどのすべてのリソースをjarの外部に作成する場合...次に、必要な出力フォルダーを定義しているpom.xml内に次のコードを追加しますjarの目的のリソースを抽出して保存します。

<build>
<finalName>project_name_Build/project_name</finalName>
   <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/project_name_Build/lib</outputDirectory>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>write here the qualified or complete path of main class of application</mainClass>
                    </manifest>
                    <manifestEntries>
                        <Class-Path>. resources/</Class-Path>
                    </manifestEntries>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>

    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>application.properties</include>
                <include>log4j.properties</include>
            </includes>
            <targetPath>${project.build.directory}/ConsentGatewayOfflineBuild/resources</targetPath>
        </resource>

        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>application.properties</include>
                <include>log4j.properties</include>
            </includes>
        </resource>

    </resources>

    <pluginManagement>
        <plugins>
            <!-- Ignore/Execute plugin execution -->
            <plugin>
                <groupId>org.Eclipse.m2e</groupId>
                <artifactId>lifecycle-mapping</artifactId>
                <version>1.0.0</version>
                <configuration>
                    <lifecycleMappingMetadata>
                        <pluginExecutions>
                            <!-- copy-dependency plugin -->
                            <pluginExecution>
                                <pluginExecutionFilter>
                                    <groupId>org.Apache.maven.plugins</groupId>
                                    <artifactId>maven-dependency-plugin</artifactId>
                                    <versionRange>[1.0.0,)</versionRange>
                                    <goals>
                                        <goal>copy-dependencies</goal>
                                    </goals>
                                </pluginExecutionFilter>
                                <action>
                                    <ignore />
                                </action>
                            </pluginExecution>
                        </pluginExecutions>
                    </lifecycleMappingMetadata>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
0
PulkitRajput

Ymlファイルの解決策:

1. jarアプリケーションと同じディレクトリにymlをコピーします

2. xxx.ymlの例のコマンドを実行します。

Java -jar app.jar --spring.config.location=xxx.yml

それはうまくいきますが、スタートアップロガーではINFOです:

No active profile set .........
0
Piotr R

ファットjar(-cp fat.jar)またはすべてのjar(-cp "$ JARS_DIR/*")を含むクラスパスと、通常は他の場所およびjarの外部にある構成ファイルを含む別のカスタム構成クラスパスまたはフォルダーを使用する別の柔軟な方法。そのため、限定されたJava -jarの代わりに、次のように、より柔軟なクラスパスを使用します。

Java \
   -cp fat_app.jar \ 
   -Dloader.path=<path_to_your_additional_jars or config folder> \
   org.springframework.boot.loader.PropertiesLauncher

Spring-boot executable jar doc および this link を参照してください

一般的な複数のMainAppがある場合は、 実行可能jarに使用するメインクラスをSpring Bootに指示するにはどうすればよいですか を使用できます。

Loader.properties(ディレクトリ、アーカイブ、またはアーカイブ内のディレクトリのコンマ区切りリスト)で環境変数LOADER_PATHまたはloader.pathを設定することにより、追加の場所を追加できます。基本的に、loader.pathはJava -jarまたはJava -cpの両方の方法で機能します。

そして、いつものように、application.ymlをオーバーライドして正確に指定することができ、デバッグ目的でピックアップする必要があります

--spring.config.location=/some-location/application.yml --debug
0
kisna

これは後期に来るかもしれませんが、特にJava jar myapp.war@ PropertySource( "classpath:some.properties"の代わりに)を使用してスプリングブートアプリを実行する場合、外部構成を読み込むより良い方法を見つけたと思います)

設定は、プロジェクトのルートから、またはwar/jarファイルが実行されている場所からロードされます。

public class Application implements EnvironmentAware {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void setEnvironment(Environment environment) {
        //Set up Relative path of Configuration directory/folder, should be at the root of the project or the same folder where the jar/war is placed or being run from
        String configFolder = "config";
        //All static property file names here
        List<String> propertyFiles = Arrays.asList("application.properties","server.properties");
        //This is also useful for appending the profile names
        Arrays.asList(environment.getActiveProfiles()).stream().forEach(environmentName -> propertyFiles.add(String.format("application-%s.properties", environmentName))); 
        for (String configFileName : propertyFiles) {
            File configFile = new File(configFolder, configFileName);
            LOGGER.info("\n\n\n\n");
            LOGGER.info(String.format("looking for configuration %s from %s", configFileName, configFolder));
            FileSystemResource springResource = new FileSystemResource(configFile);
            LOGGER.log(Level.INFO, "Config file : {0}", (configFile.exists() ? "FOund" : "Not Found"));
            if (configFile.exists()) {
                try {
                    LOGGER.info(String.format("Loading configuration file %s", configFileName));
                    PropertiesFactoryBean pfb = new PropertiesFactoryBean();
                    pfb.setFileEncoding("UTF-8");
                    pfb.setLocation(springResource);
                    pfb.afterPropertiesSet();
                    Properties properties = pfb.getObject();
                    PropertiesPropertySource externalConfig = new PropertiesPropertySource("externalConfig", properties);
                    ((ConfigurableEnvironment) environment).getPropertySources().addFirst(externalConfig);
                } catch (IOException ex) {
                    LOGGER.log(Level.SEVERE, null, ex);
                }
            } else {
                LOGGER.info(String.format("Cannot find Configuration file %s... \n\n\n\n", configFileName));

            }

        }
    }

}

それが役に立てば幸い。

0
JohnTheBeloved
Java -jar server-0.0.1-SNAPSHOT.jar --spring.config.location=application-prod.properties
0
HimalayanCoder

私はそれが先の尖った質問であることを知っています、そして、オペレーションは異なるプロパティファイルをロードしたかったです。

私の答えは、このようなカスタムハックを行うことはひどい考えです。

クラウドファウンドリなどのクラウドプロバイダーでスプリングブートを使用している場合は、ご自身でサポートを行い、クラウド構成サービスを使用してください

https://spring.io/projects/spring-cloud-config

Default/dev/project-default/project-dev固有のプロパティ(magicなど)をロードしてマージします

繰り返しになりますが、Springブートは既にこれを正しく行うための十分な方法を提供しています https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html =

車輪を再発明しないでください。

0
Kalpesh Soni