Flyway wildcard is not working in Spring Boot - spring-boot

I get the following error:
Flyway failed to initialize: none of the following migration scripts locations could be found:
- classpath:db/*/migrations/
This is what the directory structure looks like:
And this is what I've tried:
# examples, obviously I tried these independently from each other
spring:
flyway:
# these work:
locations: "classpath:db"
locations: "classpath:db/release_1.0/migrations/"
# these don't work: (I am getting the same error as shown above)
locations: "classpath:db/**/migrations/"
locations: "classpath:db/release*/migrations/"
locations: "classpath:db/*/migrations/"
But they should work according to this blogpost from version 6.4. (I don't see it documented that they have removed it)
I am using spring-boot-starter-parent 2.4.1, so it is Flyway 7.1.1.
Can anyone explain to me how to specify the migrations folder using a wildcard in Flyway and why is it not working?

As Flyway's location support has grown to support wildcards, cloud storage, etc., Spring Boot's ability to accurately check the locations has decreased as described in this issue. As a result, support for location checking was deprecated in Spring Boot 2.5 and, after the deprecation period, it will be removed entirely. In the meantime, you can switch it off by setting spring.flyway.check-location to false.

Related

Specifying files by absolute path was removed in Liquibase 4.0

I am getting the following liquibase error when I run my Spring Boot application:
Specifying files by absolute path was removed in Liquibase 4.0. Please use a relative path or add '/' to the classpath parameter.
Here is the class path in application.yaml:
liquibase:
change-log: classpath:db/changelog/db-changelog-master.xml
I also tried:
liquibase:
change-log: classpath:/db/changelog/db-changelog-master.xml
Here is folder structure:
Changlog master:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="db-changelog-1.0.xml"/>
</databaseChangeLog>
I got this issue when putting the changelog files outside the resources folder, but if I include them under resources/db/changelog, then it would work fine with setting the bellow config.
spring.liquibase.change-log=classpath:/db/changelog/changelog-master.xml
Tested under 4.6.2
This is still an open issue unfortunately. See 2281.
Looks like this was fixed in v4.4.3
As explained here
How the Liquibase classpath worked before version 4.0
Before version 4.0, one of the default locations Liquibase added to
the classpath was the root directory in your filesystem (/). The
change caused issues because of a machine-dependent changelog path,
such as /home/my-user/projects/liquibase/changelog.xml, found under
the / directory. This way, Liquibase uses the given path as part of
the changeset identifier stored in the DATABASECHANGELOG table, and
when you run Liquibase from
/home/other-user/projects/liquibase/changelog.xml, Liquibase sees it
as a different changelog and tries to rerun all the previously run
changesets.
To prevent identification issues from happening, a / was removed as a
default part of the classpath. How the Liquibase classpath works in
4.0 and later versions
Starting with Liquibase 4.0, the root directory (/) is no longer a
default part of the classpath because of the issue mentioned in the
previous section.
...
The message "Please use a relative path or add '/' to the classpath parameter." refers to the root directory '/', and does not mean to add a slash to the start of your classpath path. Afaik, classpath:x and classpath:/x are the same.
Also, the message appears when the master changelog is not found, for whatever reason, so also a typo can cause this message. It's only a hint telling you that it might not be found because the file is not on the classpath, because they removed the root directory from the classpath, but it could also not be found because you specified the wrong path (I just did that).
To configure it correctly, the master changelog must be on the Liquibase classpath. In Spring Boot, the Liquibase classpath is set to the application's classpath, i.e. you can use src/main/resources.
Tl;dr: When your file is src/main/resources/db/changelog/db.changelog-master.xml use
spring.liquibase.change-log=classpath:/db/changelog/db.changelog-master.xml
I don't know, whether there was or is a bug in regards to that with certain Liquibase versions, but that's how it's supposed to work, anyway.
Just try to remove "classpath:" from "change-log:" parameter.
Also try to check your pom.xml ("changeLogFile" tag in configuration):
there should not be a "${basedir}" before change log file path.
<changeLogFile>
/src/main/resources/liquibase/changelog.xml
</changeLogFile>

SpringBoot 2.4.0, no log file written (logging.file.name)

I tried to use logging.file.name=springboot.log to set my log file, but no log file would written. But it's very confusing that springboot.txt works. This following is my settings in application.properties:
logging.level.com.demo=trace
# For the following files, I just keep one and comment the others
logging.file.name=springboot.yml # Works
logging.file.name=springboot.xml # Works
logging.file.name=springboot.txt # Works
logging.file.name=springboot.log # Does not work
logging.file.name=logging/springboot.yml # Works
logging.file.name=logging/springboot.log # Does not work
I have just upgraded the dependencies a springboot application that uses multiple profiles and hit a similar issue - for me it works, but fails to work if profiles are involved.
logging.file.name which has been running for at least 6 months now without problems suddenly stopped working after dependency upgrade from 2.3.8 -> 2.4.2.
Thus think looks like a 2.4 issue.
For a temporary fix you could try downgrading - in gradle the following works for me:
plugins
{
id 'com.github.ben-manes.versions' version '0.36.0'
id 'org.springframework.boot' version '2.3.8.RELEASE'
}
Having done some further investigation it appears to fail for me because of overrides in the profiles.
So I have two profiles: base and dev which are used together --spring.profiles.active=base,dev
My base sets logging.file.name for the default live. my dev profile overrides this and sets it to ./blah.log.
For me that is not picked up under 2.4.2 and fails, but overrides correctly with 2.3.8.
If you are using multiple profiles this may be the problem.
EDIT: I've raised a big report on Spring Boot on github: https://github.com/spring-projects/spring-boot/issues/25058

javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;

I'm getting the below error when running Spring Boot app in Intellij:
The following method did not exist:
javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
The method's class, javax.servlet.ServletContext, is available from the following locations:
jar:file:/C:/Program%20Files/Java/jdk1.8.0_05/jre/lib/ext/servlet-api.jar!/javax/servlet/ServletContext.class
jar:file:/C:/Program%20Files/Java/jdk1.8.0_05/jre/lib/ext/servlet-api.jar!/javax/servlet/ServletContext.class
jar:file:/C:/Users/adi/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.29/tomcat-embed-core-9.0.29.jar!/javax/servlet/ServletContext.class
It was loaded from the following location:
file:/C:/Program%20Files/Java/jdk1.8.0_05/jre/lib/ext/servlet-api.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of javax.servlet.ServletContext
I would just delete the entire C:/Program Files/Java/jdk1.8.0_05/jre/lib/ext/ directory.
Servlet API should not be a part of the JDK.
This Java version is also ancient, so installing a more recent Java build and using it for your project is probably an even better solution.

Spring Application won't start: jaxb-impl-2.2.3-1.jar referenced one or more files that do not exist:

I'm stuck behind this error in IDEA. I was working as usual debugging some classes and everything was working just fine. But at a given moment my spring application stopped initializing and this line appear on the console every time now, and the application remains in a infinite loop, trying to initialize:
The Class-Path manifest attribute in /home/user/maven/repository/com/sun/xml/bind/jaxb-impl/2.2.3-1/jaxb-impl-2.2.3-1.jar referenced one or more files that do not exist: file:/home/user/maven/repository/com/sun/xml/bind/jaxb-impl/2.2.3-1/jaxb-api.jar,file:/home/user/maven/repository/com/sun/xml/bind/jaxb-impl/2.2.3-1/activation.jar,file:/home/user/maven/repository/com/sun/xml/bind/jaxb-impl/2.2.3/jsr173_1.0_api.jar,file:/home/user/maven/repository/com/sun/xml/bind/jaxb-impl/2.2.3-1/jaxb1-impl.jar
And these lines :
project: 1.1.0-iron-man-SNAPSHOT
Spring Boot version: (v1.5.10.RELEASE)
Java Version: 1.8.0_141
Source Encoding: UTF-8
turned out to this:
project: #project.version#
Spring Boot version: (v1.5.10.RELEASE)
Java Version: #java.version#
Source Encoding: #project.build.sourceEncoding#
I'm didn't change any config files in the project.
I have tried mvn clean install.
I have tried to force IDEA to read the maven dependecies again.
None of them have worked.
Maybe File -> Invalidate Caches / Restart helps
First Picture MANIFEST.MF defines the classpath
But they are stored in different maven repository forlders

Springboot Strange Resource Loading Behavior

I'm working on a springboot 1.5.1 application that I'm trying to load a WSDL included in my resources directory in the wsdl directory. Depending on where my application executes I'm getting different results (command line, intellij, cloud foundry) and I can't seem to get all three to work at the same time.
I've tried several ways of locating the resource:
From prior to the migration to springboot we had this (worked in IntelliJ but not java -jar myboot.jar):
this.getClass().getResource("/wsdl/my.wsdl");
I switched it to the typically more correct version and got it to work in IntelliJ and java -jar but not Cloud Foundry:
this.getClass().getClassLoader().getResource("/wsdl/my.wsdl");
I switched it to use the Spring Resource Loader version and it worked in IntelliJ and CloudFoundry but not java -jar:
#Value("classpath:/wsdl/my.wsdl")
private Resource wsdlResource;
wsdlResource.getURL();
On the command line what I've noticed is that it seems to be thinking that BOOT-INF/classes is a JAR file (Note the ! after classes):
Caused by: javax.xml.ws.WebServiceException: Failed to access the WSDL at: jar:file:/C:/dev/redacted/build/libs/redacted.jar!/BOOT-INF/classes!/wsdl/my.wsdl. It failed with:
JAR entry BOOT-INF/classes!/wsdl/my.wsdl not found in C:\dev\redacted\build\libs\redacted.jar.
From looking at IntelliJ's URL, it's referring to the actual source folder which explains why it seems to always work.
What is causing this and how might I universally load these class path resources successfully with springboot?

Resources