Подтвердить что ты не робот

Spring Загрузка: возможно ли использовать внешние файлы application.properties в произвольных каталогах с использованием толстой банки?

Возможно ли иметь несколько файлов application.properties? ( РЕДАКТИРОВАТЬ: обратите внимание, что этот вопрос эволюционировал с тем, который был на названии.)

Я попытался иметь 2 файла.

  • Первый находится в корневой папке в приложении Jar.
  • Второй находится в каталоге, указанном в пути к классам.

2 файла называются "application.properties".

Возможно ли "объединить" содержимое обоих файлов? (и второе значение свойства переопределяет первый) Или, если у меня есть один файл, то другой файл игнорируется?

ОБНОВЛЕНИЕ 1: можно объединить содержимое. Вчера казалось, что первый был проигнорирован, но кажется, что это потому, что тогда что-то было сломано. Теперь он работает хорошо.

ОБНОВЛЕНИЕ 2: он снова! Опять применяется только один из двух файлов. Это странно... Это началось после того, как я создал файл приложения jar с помощью Spring Tool Suite. И кажется, что версия Jar всегда игнорирует вторую (в classpath), в то время как поведение расширенной версии, которая работает на STS, меняется. Откуда я могу начать расследование?

ОБНОВЛЕНИЕ 3:

Поведение версии Jar было фактически правильным. Это спецификация java.exe. Когда указан параметр -jar, java.exe игнорирует параметр -classpath и переменную среды CLASSPATH, а путь к классу будет содержать только файл jar. Таким образом, игнорируется второй файл application.properties в пути к классам.

Теперь, как я могу загрузить второй файл application.properties в пути к классам?

ОБНОВЛЕНИЕ 4:

Мне удалось загрузить файл application.properties по внешнему пути при использовании опции -jar.

Ключ был 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 не удалось использовать утилиту загрузки свойств. BTW, In Spring Загрузочный файл Boot Maven (http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/repackage-mojo.html), нет упоминания о том, что задаются триггеры ZIP, которые используется PropertiesLauncher. (Возможно, в другом документе?)

После того, как файл jar был создан, я мог видеть, что свойство PropertiesLauncher используется, проверяя свойство Main-Class в META-INF/MENIFEST.MF в банке.

Теперь я могу запустить банку следующим образом (в 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.

Теперь загружается файл application.properties в папке C:\My\External\Dir\config.

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

Что касается не-jar (расширенной) версии, упомянутой в UPDATE 2, возможно, была проблема с порядком пути к классам.

(Кстати, я изменил заголовок вопроса, чтобы быть более конкретным для этой проблемы.)

4b9b3361

Ответ 1

Мне удалось загрузить файл application.properties по внешнему пути при использовании опции -jar.

Ключ был 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 Maven Plugin (http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/repackage-mojo.html) нет упоминания об указании триггеров ZIP что PropertiesLauncher используется. (Возможно в другом документе?)

После того, как файл jar был собран, я увидел, что PropertiesLauncher используется, проверив свойство Main-Class в META-INF/MENIFEST.MF в jar.

Теперь я могу запустить 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.

Теперь файл application.properties загружен в C:\My\External\Dir\config.

В качестве бонуса jar может получить доступ к любому файлу (например, статическому html файлу) в этом каталоге, поскольку он находится в пути к загрузчику.

Что касается не -jar (расширенной) версии, упомянутой в UPDATE 2, возможно, возникла проблема с порядком пути к классам.

Ответ 2

Если вы не изменили значения по умолчанию Spring Boot (что означает, что вы используете @EnableAutoConfiguration или @SpringBootApplication и не изменили обработку Property Source), тогда он будет искать свойства со следующим порядком (самые высокие переопределения самый низкий):

  • A /config поддиректор текущего каталога
  • Текущий каталог
  • Пакет classpath /config
  • Корень classpath

Список выше приведен в этой части документации

Это означает, что если свойство найдено, например, application.properties в src/resources, оно будет переопределено свойством с тем же именем, которое находится в application.properties в каталоге /config, которое находится "рядом" с упакованная банка.

Этот порядок по умолчанию, используемый Spring Boot, позволяет очень упростить конфигурацию, что в свою очередь упрощает настройку приложений в нескольких средах (dev, staging, production, cloud и т.д.).

Чтобы увидеть весь набор функций, предоставляемых Spring Загрузка для чтения свойств (подсказка: есть намного больше, чем чтение из application.properties), зайдите this часть документации.

Как видно из моего краткого описания выше или из полной документации, Spring Приложения для загрузки очень полезны для DevOps!

Ответ 3

Все объяснено здесь в документах:

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

Это объясняет, что это порядок приоритета:

  • Подкаталог A/config текущего каталога.
  • Текущий каталог
  • Пакет classpath/config
  • Корень classpath

Он также указывает, что вы можете определить дополнительные файлы свойств для таких переопределений:

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

Если вы используете spring.config.location, тогда также включаются все местоположения по умолчанию для application.properties. Это означает, что вы можете установить значения по умолчанию в application.properties и переопределить, как требуется для конкретной среды.

Ответ 4

Вы могли бы запустить свою загрузку spring с помощью пути к файлам внешних свойств следующим образом:

java -jar {jar-file-name}.jar 
--spring.config.location=file:///C:/{file-path}/{file-name}.properties

Ответ 5

<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

Ответ 6

Это может произойти в конце, но я думаю, что я нашел лучший способ загрузить внешние конфигурации, особенно когда вы запускаете приложение spring -boot, используя java jar myapp.war вместо @PropertySource ( "classpath: some. свойства" )

Конфигурация будет загружена из корня проекта или из места, в котором файл войны /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));

            }

        }
    }

}

Надеюсь, что это поможет.

Ответ 7

Другой гибкий способ - использование пути к классам, содержащего толстый файл jar (-cp fat.jar) или все файлы jar (-cp "$ JARS_DIR/*"), и другой пользовательский путь к классу конфигурации или папку, содержащую файлы конфигурации, обычно в других местах и за пределами jar. Таким образом, вместо ограниченной Java -jar, используйте более гибкий путь classpath следующим образом:

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

Смотрите Spring-boot исполняемый файл jar doc и эту ссылку

Если у вас есть несколько MainApps, что является общим, вы можете использовать Как мне сказать Spring Boot, какой основной класс использовать для исполняемого jar?

Вы можете добавить дополнительные местоположения, установив переменную среды LOADER_PATH или loader.path в loader.properties (разделенный запятыми список каталогов, архивов или каталогов внутри архивов). В основном loader.path работает как для java -jar, так и для java -cp.

И, как всегда, вы можете переопределить и точно указать application.yml, который он должен использовать для отладки.

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

Ответ 8

Решение для файла yml:

1. Скопируйте yml в тот же каталог, в котором находится jar-приложение.

2. Запустите команду, пример для xxx.yml:

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

Работает нормально, но при запуске логгера есть ИНФО:

No active profile set .........

Ответ 9

Когда вы создаете весенний загрузочный jar с помощью maven install и хотите, чтобы все ресурсы, такие как файл свойств и папка lib, создавались вне jar..., добавьте следующий код в pom.xml, где я определяю выходную папку, где я хочу извлечь и сохранить нужные ресурсы банку.

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

Ответ 10

Я знаю, что это заостренный вопрос, и ОП хотел загрузить другой файл свойств.

Мой ответ таков: делать пользовательские хаки, как это, ужасная идея.

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

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

Он загружает и объединяет определенные свойства по умолчанию /dev/project-default/project-dev, такие как magic

Опять же, загрузка Spring уже дает вам достаточно способов сделать это правильно https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Пожалуйста, не изобретайте велосипед заново.

Ответ 11

java -jar server-0.0.1-SNAPSHOT.jar --spring.config.location=application-prod.properties