Springboot Liquibase database-changelog.xml Loading From External Folder - spring-boot

my-project
|
|-kube
|_kustomize
|_base
|_sql
|_dbsturct
|_liqubase
|-db.changelog-master.xml
|-src
|_my.java.code
|_ resources
In my project I kept database-chagelog.xml outside resources folder and not included in the classpath.This folder structure is not included in the pom.xml as part of resources.
I have configured spring.liquibase.change-log=file:///C:/my-project/kube/kustomize/base/sql/dbsruct/liquibase/db.changelog-master.xml
It throws file not found exception.
Is there a way to configure db.changelog-master.xml without including as resource folder inside pom.xml?

Related

How to make #SpringBootTest use application.properties from external config folder (inside project root)?

I have a multi-module Spring Boot Gradle project (Kotlin) with the following directory structure.
root
|- domain (Module containing entities and interfaces)
|- application (Spring boot Kotlin application)
|- src/main
|- kotlin (app sources)
|- resources
|- application.properties (default config)
|- src/test/kotlin/long/package/name/ApplicationTests.kt
|- build.gradle.kts (and also gradle folder)
|- config
|- application.properties (config to override classpath properties)
|- build.gradle.kts (and settings.gradle.kts and other gradle folder)
When I run the Application.kt file, it is able to pick up this file (both with IDE and gradle), and it runs successfully.
Since my config folder is outside my application folder, running my ApplicationTests.kt results in the error below. The output is same when running through IDE (IntelliJ) run button and ./gradlew clean test.
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection
I am expecting the tests to find the application.properties file inside the config folder. How can I register my config/application.properties so that I can keep it separate from my classpath:application.properties?
UPDATE:
I tried adding the following copy task to gradle.
tasks.create("copy", Copy::class.java) {
from("../config")
into("$buildDir/resources/main")
}
tasks.named("test").configure {
dependsOn("copy")
}
This enables me to overwrite the application.properties from config folder (meaning any property not added in config/app.prop is no longer present). Test runs successfully now (if I add all entries from classpath properties to config/app.props). How can I merge the contents of these two properties files inside application/build.gradle.kts?
If you want to override your application.properties with an external application.properties, you can copy the external file to build/classes directory using Gradle and append a profile name, like application-ext.properties. Then, activate default and ext profiles using spring.profiles.active.
Another option would be to use Spring Config server, but that may be overkill for this simple task.
By default, Spring will look in your current working directory for the directory named, config. As you've noted, you're not executing the application in the directory containing the config directory. You can override where Spring looks for this config folder with the -Dspring.config.location option or via the environment variable, SPRING_CONFIG_LOCATION
If your config directory is located at /opt/myconfigs/config, you would start your service with -Dspring.config.location=/opt/myconfigs/config. Another option is to export SPRING_CONFIG_LOCATION=/opt/myconfigs/config and start your app without any additional JVM options.
If you're running tests in the application directory, then the config folder would be one level up from the current working directory. Annotating your tests with
#TestPropertySource(properties = "spring.config.location=../config/,classpath:/application.properties") would load the application.properties from both the config folder and the src/main/resources folder, properties in the config props would override properties in the local application properties.
The same thing can be achieved with the VM argument of -Dspring.config.location=classpath:/application.yml,file:../config/, here order is important.

Where to put external config files in a Kotlin Gradle project?

I use a standard Maven/Gradle project structure putting source code under src/main/kotlin and automatically collected resources under src/main/resources:
\myapp
-\src
-\main
-\kotlin
-\com
-\projectname
-\MyApp.kt
-\resources
- som_file.txt
This works fine to package my distribution with the distZip task and all resources end up in a jar which is then zipped into the following structure:
myapp
-\bin\
-\libs\
I am not sure where to put external config files in my Kotlin project (e.g. db.config) which the user could edit later. Is there a correct location for external config files in Gradle project?

Location to add view files: SPRING MVC

In SPRING MVC project, Which is the right folder location to create a new JSP(view) file:
WebContent\new_jsp_file.jsp
or
Java Resources\src\com.example.view\new_jsp_file.jsp
Note: com.example.view is a manually created package
Usually JSP file is located here:
%projectfolder%/src/main/webapp/WEB-INF/jsp/
JSP files should be put inside WEB-INF directory, because contents of WEB-INF aren't directly accessible by users, which is needed for application security.
If you are using Maven or Gradle:
project-name
|- src
|- main
|- java
|- resources
|- webapp
|- WEB-INF
|--- put JSPs here, can create subdirectories if needed

how to give classpath for a property file using spring

Resource resource = new ClassPathResource("classpath:src/main/resources/template/datafields.properties");
Properties props = PropertiesLoaderUtils.loadProperties(resource);
Your problem is that your file is actually not in the application classpath. Looking at your folder paths I am assuming that you have a maven project structure and your properties file is present within resources directory. When your project is compiled, everything inside the resources directory is at the root of the classpath along with your compiled java classes. So you should instead use
Resource resource = new ClassPathResource("template/datafields.properties");
Classpath resource loads resources from the application classpath, so you need to be aware what all directories/jar files are in your classpath and their directory structure to successfully load resources.

Maven war has META-INF folder in two places

I'm working on a project which uses JAAS and unfortunately for me Tomcat requires a file to be put in a META-INF folder in the root of the war
app.war
|__META-INF
| |___context.xml
...
I think that it's already weird since the default META-INF location for WAR's is in the classes folders.
app.war
|__WEB-INF
| |__classes
| |__META-INF
...
So I'm using Maven, which states that anything in src/main/resources/META-INF will be copied to the appropriate place, which it does. The weird thing is that it is also creating a META-INF folder in the root of the file structure leaving me with 2 META-INF folders.
Project Structure
app
|__src/main/java
|__src/main/resources
| |__META-INF
| |__context.xml
...
After mvn package
app
|__META-INF [1]
|__WEB-INF
| |__classes
| |__META-INF [2]
| |__context.xml
...
So, if the war standard states that META-INF should be under classes folder, as in #2, why maven war creates the #1 folder. And is there a way to make it copy files into that folder instead of #2?
Regards
So I found this:
Two Meta-Inf folders - normal structure?
which states that having 2 META-INF folders is not a problem. Digging a little I found:
JAR File Specification
which states about the META-INF folder:
A JAR file is essentially a zip file that contains an optional META-INF directory. ...The META-INF directory, if it exists, is used to store package and extension configuration data, including security, versioning, extension and services.
and this:
JSR-000315 JavaTM Servlet 3.0
which, on section 10.6, states about the WAR file structure:
When packaged into such a form, a META-INF directory will be present which
contains information useful to Java archive tools. This directory must not be directly
served as content by the container in response to a Web client’s request, though its
contents are visible to servlet code via the getResource and getResourceAsStream
calls on the ServletContext. Also, any requests to access the resources in META-INF
directory must be returned with a SC_NOT_FOUND(404) response.
So from the WAR spec the right place is WEB-INF/classes/META-INF. Yet, since war is a special jar file, it makes sense to have /META-INF as a point for extensions. One can see such different uses in JPA persistence.xml vs. Tomcat context.xml files: the former should be placed in WEB-INF/classes/META-INF while the latter in /META-INF.

Resources