example - spring boot properties
Spring Boot: ¿Es posible usar archivos externos application.properties en directorios arbitrarios con un tarro gordo? (11)
¿Es posible tener múltiples archivos application.properties? ( EDITAR : tenga en cuenta que esta pregunta evolucionó a la del título).
Traté de tener 2 archivos.
- El primero está en la carpeta raíz en la aplicación Jar.
- El segundo está en el directorio que se especifica en classpath.
2 archivos se denominan ''application.properties''.
¿Es posible ''fusionar'' el contenido de ambos archivos? (y los valores de propiedad del segundo anulan al del primero) O, si tengo un archivo, ¿se ignora el otro archivo?
ACTUALIZACIÓN 1 : es posible ''fusionar'' los contenidos. Ayer parecía que el primero fue ignorado, pero parece que es porque algo se rompió entonces. Ahora funciona bien.
ACTUALIZACIÓN 2 : ¡Ha vuelto otra vez! De nuevo, solo se está aplicando uno de los dos archivos. Es extraño ... Comenzó después de que construí el archivo jar de la aplicación usando Spring Tool Suite. Y parece que la versión Jar siempre ignora la segunda (en classpath), mientras que el comportamiento de la versión expandida que se ejecuta en STS varía. ¿Desde dónde puedo comenzar a investigar?
ACTUALIZACIÓN 3 :
El comportamiento de la versión Jar era de hecho correcto. Es la especificación de java.exe. Cuando se especifica la opción -jar, java.exe ignora la opción -classpath y la variable de entorno CLASSPATH, y el classpath contendrá solo el archivo jar. Por lo tanto, se ignora el segundo archivo application.properties en el classpath.
Ahora, ¿cómo puedo dejar que se carguen las segundas aplicaciones.propiedades en el classpath?
ACTUALIZACIÓN 4 :
Logré cargar un archivo application.properties en una ruta externa mientras usaba la opción -jar.
La clave fue PropertiesLauncher.
Para usar PropertiesLauncher, el archivo pom.xml debe cambiarse así:
<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>
Para esto, hice referencia a la siguiente pregunta de StackOverflow: el lanzador de propiedades de arranque de primavera no se puede usar . Por cierto, en el documento Spring Boot Maven Plugin ( http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/repackage-mojo.html ), no se menciona que especifique desencadenantes ZIP que se utiliza PropertiesLauncher. (¿Quizás en otro documento?)
Después de que se haya creado el archivo jar, pude ver que PropertiesLauncher se usa al inspeccionar la propiedad Main-Class en META-INF / MENIFEST.MF en el jar.
Ahora, puedo ejecutar el jar de la siguiente manera (en Windows):
java -Dloader.path=file:///C:/My/External/Dir,MyApp-0.0.1-SNAPSHOT.jar -jar MyApp-0.0.1-SNAPSHOT.jar
Tenga en cuenta que el archivo jar de la aplicación se incluye en loader.path.
Ahora se carga un archivo application.properties en C: / My / External / Dir / config.
Como beneficio adicional, cualquier archivo (por ejemplo, archivo html estático) en ese directorio también puede ser accedido por el jar ya que está en la ruta del cargador.
En cuanto a la versión no jar (expandida) mencionada en la ACTUALIZACIÓN 2, tal vez hubo un problema de orden de classpath.
(Por cierto, cambié el título de la pregunta para ser más específico a este problema).
Cuando esté creando un tarro de arranque de primavera utilizando la instalación de Maven y desee que todos los recursos como el archivo de propiedades y la carpeta lib se creen fuera del tarro ... luego agregue el siguiente código dentro de pom.xml donde estoy definiendo la carpeta de salida donde quiero para extraer y almacenar los recursos deseados de 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>
Esto puede llegar tarde, pero creo que descubrí una mejor manera de cargar configuraciones externas, especialmente cuando ejecuta su aplicación Spring-boot usando
java jar myapp.war
lugar de @PropertySource ("classpath: some.properties")
La configuración se cargaría desde la raíz del proyecto o desde la ubicación desde la que se ejecuta el archivo 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));
}
}
}
}
Espero eso ayude.
Logré cargar un archivo application.properties en una ruta externa mientras usaba la opción -jar.
La clave fue PropertiesLauncher.
Para usar PropertiesLauncher, el archivo pom.xml debe cambiarse así:
<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>
Para esto, hice referencia a la siguiente pregunta de : el lanzador de propiedades de arranque de primavera no se puede usar . Por cierto, en el documento Spring Boot Maven Plugin ( http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/repackage-mojo.html ), no se menciona que especifique desencadenantes ZIP que se utiliza PropertiesLauncher. (¿Quizás en otro documento?)
Después de que se haya creado el archivo jar, pude ver que PropertiesLauncher se usa al inspeccionar la propiedad Main-Class en META-INF / MENIFEST.MF en el jar.
Ahora, puedo ejecutar el jar de la siguiente manera (en Windows):
java -Dloader.path=file:///C:/My/External/Dir,MyApp-0.0.1-SNAPSHOT.jar -jar MyApp-0.0.1-SNAPSHOT.jar
Tenga en cuenta que el archivo jar de la aplicación se incluye en loader.path.
Ahora se carga un archivo application.properties en C: / My / External / Dir / config.
Como beneficio adicional, cualquier archivo (por ejemplo, archivo html estático) en ese directorio también puede ser accedido por el jar ya que está en la ruta del cargador.
En cuanto a la versión no jar (expandida) mencionada en la ACTUALIZACIÓN 2, tal vez hubo un problema de orden de classpath.
Otra forma flexible de utilizar classpath que contiene fat jar (-cp fat.jar) o todos los jar (-cp "$ JARS_DIR / *") y otra classpath o carpeta de configuración personalizada que contiene archivos de configuración, generalmente en otro lugar y fuera de jar. Entonces, en lugar del java -jar limitado, use la forma classpath más flexible de la siguiente manera:
java /
-cp fat_app.jar /
-Dloader.path=<path_to_your_additional_jars or config folder> /
org.springframework.boot.loader.PropertiesLauncher
Consulte el documento jar ejecutable Spring-boot y este enlace
Si tiene múltiples MainApps que es común, puede usar ¿Cómo le digo a Spring Boot qué clase principal usar para el jar ejecutable?
Puede agregar ubicaciones adicionales configurando una variable de entorno LOADER_PATH o loader.path en loader.properties (lista de directorios, archivos o directorios separados por comas). Básicamente loader.path funciona tanto para java -jar como para java -cp.
Y, como siempre, puede anular y especificar exactamente la aplicación.yml que debe recuperarse para fines de depuración
--spring.config.location=/some-location/application.yml --debug
Podrá iniciar su aplicación de arranque de primavera con la ruta del archivo de propiedades externo de la siguiente manera:
java -jar {jar-file-name}.jar
--spring.config.location=file:///C:/{file-path}/{file-name}.properties
Sé que es una pregunta puntual, y el operador quería cargar diferentes archivos de propiedades.
Mi respuesta es que hacer hacks personalizados como este es una idea terrible.
Si está utilizando Spring-boot con un proveedor de la nube, como la fundición de la nube, hágase un favor y use los servicios de configuración de la nube
https://spring.io/projects/spring-cloud-config
Carga y combina propiedades específicas de default / dev / project-default / project-dev como magic
Nuevamente, Spring boot ya le ofrece suficientes formas de hacerlo correctamente https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Por favor, no reinventes la rueda.
Si no ha cambiado los valores predeterminados de Spring Boot (lo que significa que está utilizando
@EnableAutoConfiguration
o
@SpringBootApplication
y no ha cambiado ningún manejo de Origen de propiedades), buscará propiedades con el siguiente orden (el más alto anula el más bajo):
-
Un subdirectorio
/config
del directorio actual - El directorio actual
-
Un paquete
classpath
/config
- La raíz de classpath
La lista anterior se menciona en this parte de la documentación.
Lo que eso significa es que si se encuentra una propiedad, por ejemplo,
application.properties
en
src/resources
se anulará con una propiedad con el mismo nombre que se encuentra en
application.properties
en el directorio
/config
que está "al lado" del jar empaquetado.
Este orden predeterminado utilizado por Spring Boot permite una externalización de configuración muy fácil que a su vez hace que las aplicaciones sean fáciles de configurar en múltiples entornos (desarrollo, puesta en escena, producción, nube, etc.)
Para ver el conjunto completo de características proporcionadas por Spring Boot para la lectura de propiedades (pista: hay mucho más disponible que leer desde
application.properties
), consulte
this
parte de la documentación.
Como se puede ver en mi breve descripción anterior o en la documentación completa, ¡las aplicaciones Spring Boot son muy amigables para DevOps!
Solución para el archivo yml:
1. Copie yml en el mismo directorio que la aplicación jar
2. Comando de ejecución, ejemplo para
xxx.yml
:
java -jar app.jar --spring.config.location=xxx.yml
Funciona bien, pero en el registrador de inicio es INFO:
No active profile set .........
Todo se explica aquí en los documentos:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Lo que explica que este es el orden de precedencia:
- Un subdirectorio / config del directorio actual.
- El directorio actual
- Un paquete classpath / config
- La raíz de classpath
También señala que puede definir archivos de propiedades adicionales para anulaciones de esta manera:
java -jar myproject.jar
--spring.config.location=classpath:/overrides.properties
Si usa
spring.config.location
, también se incluyen todas las ubicaciones predeterminadas para
application.properties
.
Esto significa que puede configurar valores predeterminados en
application.properties
y anular según sea necesario para un entorno particular.
java -jar server-0.0.1-SNAPSHOT.jar --spring.config.location=application-prod.properties
<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