parent
cf8e667795
commit
d15ec4cdb4
|
|
@ -85,6 +85,7 @@ dependencies {
|
||||||
testImplementation("com.squareup.okhttp3:mockwebserver")
|
testImplementation("com.squareup.okhttp3:mockwebserver")
|
||||||
testImplementation("org.testcontainers:junit-jupiter")
|
testImplementation("org.testcontainers:junit-jupiter")
|
||||||
|
|
||||||
|
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||||
testRuntimeOnly("io.projectreactor.netty:reactor-netty-http")
|
testRuntimeOnly("io.projectreactor.netty:reactor-netty-http")
|
||||||
testRuntimeOnly("javax.xml.bind:jaxb-api")
|
testRuntimeOnly("javax.xml.bind:jaxb-api")
|
||||||
testRuntimeOnly("org.apache.tomcat.embed:tomcat-embed-el")
|
testRuntimeOnly("org.apache.tomcat.embed:tomcat-embed-el")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2020 the original author or authors.
|
* Copyright 2012-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -115,10 +115,10 @@ class LiquibaseEndpointTests {
|
||||||
.liquibaseBeans().getContexts().get(context.getId()).getLiquibaseBeans();
|
.liquibaseBeans().getContexts().get(context.getId()).getLiquibaseBeans();
|
||||||
assertThat(liquibaseBeans.get("liquibase").getChangeSets()).hasSize(1);
|
assertThat(liquibaseBeans.get("liquibase").getChangeSets()).hasSize(1);
|
||||||
assertThat(liquibaseBeans.get("liquibase").getChangeSets().get(0).getChangeLog())
|
assertThat(liquibaseBeans.get("liquibase").getChangeSets().get(0).getChangeLog())
|
||||||
.isEqualTo("classpath:/db/changelog/db.changelog-master.yaml");
|
.isEqualTo("db/changelog/db.changelog-master.yaml");
|
||||||
assertThat(liquibaseBeans.get("liquibaseBackup").getChangeSets()).hasSize(1);
|
assertThat(liquibaseBeans.get("liquibaseBackup").getChangeSets()).hasSize(1);
|
||||||
assertThat(liquibaseBeans.get("liquibaseBackup").getChangeSets().get(0).getChangeLog())
|
assertThat(liquibaseBeans.get("liquibaseBackup").getChangeSets().get(0).getChangeLog())
|
||||||
.isEqualTo("classpath:/db/changelog/db.changelog-master-backup.yaml");
|
.isEqualTo("db/changelog/db.changelog-master-backup.yaml");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2020 the original author or authors.
|
* Copyright 2012-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -27,8 +27,6 @@ import javax.sql.DataSource;
|
||||||
|
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import liquibase.integration.spring.SpringLiquibase;
|
import liquibase.integration.spring.SpringLiquibase;
|
||||||
import liquibase.logging.core.Slf4jLogger;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.condition.EnabledOnJre;
|
import org.junit.jupiter.api.condition.EnabledOnJre;
|
||||||
import org.junit.jupiter.api.condition.JRE;
|
import org.junit.jupiter.api.condition.JRE;
|
||||||
|
|
@ -37,15 +35,11 @@ import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.boot.DefaultBootstrapContext;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||||
import org.springframework.boot.context.event.ApplicationStartingEvent;
|
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||||
import org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener;
|
|
||||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
|
@ -78,12 +72,6 @@ import static org.assertj.core.api.Assertions.contentOf;
|
||||||
@ExtendWith(OutputCaptureExtension.class)
|
@ExtendWith(OutputCaptureExtension.class)
|
||||||
class LiquibaseAutoConfigurationTests {
|
class LiquibaseAutoConfigurationTests {
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void init() {
|
|
||||||
new LiquibaseServiceLocatorApplicationListener().onApplicationEvent(new ApplicationStartingEvent(
|
|
||||||
new DefaultBootstrapContext(), new SpringApplication(Object.class), new String[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class))
|
.withConfiguration(AutoConfigurations.of(LiquibaseAutoConfiguration.class))
|
||||||
.withPropertyValues("spring.datasource.generate-unique-name=true");
|
.withPropertyValues("spring.datasource.generate-unique-name=true");
|
||||||
|
|
@ -315,11 +303,7 @@ class LiquibaseAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
void logging(CapturedOutput output) {
|
void logging(CapturedOutput output) {
|
||||||
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
|
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
|
||||||
.run(assertLiquibase((liquibase) -> {
|
.run(assertLiquibase((liquibase) -> assertThat(output).doesNotContain(": liquibase:")));
|
||||||
Object log = ReflectionTestUtils.getField(liquibase, "log");
|
|
||||||
assertThat(log).isInstanceOf(Slf4jLogger.class);
|
|
||||||
assertThat(output).doesNotContain(": liquibase:");
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -933,12 +933,10 @@ bom {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
library("Liquibase", "3.10.3") {
|
library("Liquibase", "4.2.2") {
|
||||||
group("org.liquibase") {
|
group("org.liquibase") {
|
||||||
modules = [
|
modules = [
|
||||||
"liquibase-core" {
|
"liquibase-core"
|
||||||
exclude group: "ch.qos.logback", module: "logback-classic"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
plugins = [
|
plugins = [
|
||||||
"liquibase-maven-plugin"
|
"liquibase-maven-plugin"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2020 the original author or authors.
|
* Copyright 2012-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,13 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.boot.liquibase;
|
package org.springframework.boot.liquibase;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
|
|
||||||
import liquibase.exception.ChangeLogParseException;
|
import liquibase.exception.ChangeLogParseException;
|
||||||
|
|
||||||
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
|
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
|
||||||
import org.springframework.boot.diagnostics.FailureAnalysis;
|
import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link AbstractFailureAnalyzer} that analyzes exceptions of type
|
* An {@link AbstractFailureAnalyzer} that analyzes exceptions of type
|
||||||
|
|
@ -32,21 +29,20 @@ import org.springframework.util.StringUtils;
|
||||||
*/
|
*/
|
||||||
class LiquibaseChangelogMissingFailureAnalyzer extends AbstractFailureAnalyzer<ChangeLogParseException> {
|
class LiquibaseChangelogMissingFailureAnalyzer extends AbstractFailureAnalyzer<ChangeLogParseException> {
|
||||||
|
|
||||||
|
private static final String MESSAGE_SUFFIX = " does not exist";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FailureAnalysis analyze(Throwable rootFailure, ChangeLogParseException cause) {
|
protected FailureAnalysis analyze(Throwable rootFailure, ChangeLogParseException cause) {
|
||||||
FileNotFoundException fileNotFound = findCause(cause, FileNotFoundException.class);
|
if (cause.getMessage().endsWith(MESSAGE_SUFFIX)) {
|
||||||
if (fileNotFound != null) {
|
|
||||||
String changelogPath = extractChangelogPath(cause);
|
String changelogPath = extractChangelogPath(cause);
|
||||||
if (StringUtils.hasText(changelogPath)) {
|
return new FailureAnalysis(getDescription(changelogPath),
|
||||||
return new FailureAnalysis(getDescription(changelogPath),
|
"Make sure a Liquibase changelog is present at the configured path.", cause);
|
||||||
"Make sure a Liquibase changelog is present at the configured path.", cause);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractChangelogPath(ChangeLogParseException cause) {
|
private String extractChangelogPath(ChangeLogParseException cause) {
|
||||||
return cause.getMessage().substring("Error parsing ".length());
|
return cause.getMessage().substring(0, cause.getMessage().length() - MESSAGE_SUFFIX.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDescription(String changelogPath) {
|
private String getDescription(String changelogPath) {
|
||||||
|
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012-2020 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.boot.liquibase;
|
|
||||||
|
|
||||||
import liquibase.servicelocator.CustomResolverServiceLocator;
|
|
||||||
import liquibase.servicelocator.ServiceLocator;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.event.ApplicationStartingEvent;
|
|
||||||
import org.springframework.context.ApplicationListener;
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link ApplicationListener} that replaces the liquibase {@link ServiceLocator} with a
|
|
||||||
* version that works with Spring Boot executable archives.
|
|
||||||
*
|
|
||||||
* @author Phillip Webb
|
|
||||||
* @author Dave Syer
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
public class LiquibaseServiceLocatorApplicationListener implements ApplicationListener<ApplicationStartingEvent> {
|
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(LiquibaseServiceLocatorApplicationListener.class);
|
|
||||||
|
|
||||||
private static final boolean LIQUIBASE_PRESENT = ClassUtils.isPresent(
|
|
||||||
"liquibase.servicelocator.CustomResolverServiceLocator",
|
|
||||||
LiquibaseServiceLocatorApplicationListener.class.getClassLoader());
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onApplicationEvent(ApplicationStartingEvent event) {
|
|
||||||
if (LIQUIBASE_PRESENT) {
|
|
||||||
new LiquibasePresent().replaceServiceLocator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inner class to prevent class not found issues.
|
|
||||||
*/
|
|
||||||
private static class LiquibasePresent {
|
|
||||||
|
|
||||||
void replaceServiceLocator() {
|
|
||||||
CustomResolverServiceLocator customResolverServiceLocator = new CustomResolverServiceLocator(
|
|
||||||
new SpringPackageScanClassResolver(logger));
|
|
||||||
ServiceLocator.setInstance(customResolverServiceLocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012-2019 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.boot.liquibase;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import liquibase.servicelocator.DefaultPackageScanClassResolver;
|
|
||||||
import liquibase.servicelocator.PackageScanClassResolver;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
|
||||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
|
||||||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
|
||||||
import org.springframework.core.type.classreading.MetadataReader;
|
|
||||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Liquibase {@link PackageScanClassResolver} implementation that uses Spring's resource
|
|
||||||
* scanning to locate classes. This variant is safe to use with Spring Boot packaged
|
|
||||||
* executable JARs.
|
|
||||||
*
|
|
||||||
* @author Phillip Webb
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
public class SpringPackageScanClassResolver extends DefaultPackageScanClassResolver {
|
|
||||||
|
|
||||||
private final Log logger;
|
|
||||||
|
|
||||||
public SpringPackageScanClassResolver(Log logger) {
|
|
||||||
this.logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void findAllClasses(String packageName, ClassLoader loader) {
|
|
||||||
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(loader);
|
|
||||||
try {
|
|
||||||
Resource[] resources = scan(loader, packageName);
|
|
||||||
for (Resource resource : resources) {
|
|
||||||
Class<?> clazz = loadClass(loader, metadataReaderFactory, resource);
|
|
||||||
if (clazz != null) {
|
|
||||||
addFoundClass(clazz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException ex) {
|
|
||||||
throw new IllegalStateException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Resource[] scan(ClassLoader loader, String packageName) throws IOException {
|
|
||||||
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(loader);
|
|
||||||
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
|
|
||||||
+ ClassUtils.convertClassNameToResourcePath(packageName) + "/**/*.class";
|
|
||||||
return resolver.getResources(pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Class<?> loadClass(ClassLoader loader, MetadataReaderFactory readerFactory, Resource resource) {
|
|
||||||
try {
|
|
||||||
MetadataReader reader = readerFactory.getMetadataReader(resource);
|
|
||||||
return ClassUtils.forName(reader.getClassMetadata().getClassName(), loader);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException | LinkageError ex) {
|
|
||||||
handleFailure(resource, ex);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (Throwable ex) {
|
|
||||||
if (this.logger.isWarnEnabled()) {
|
|
||||||
this.logger.warn("Unexpected failure when loading class resource " + resource, ex);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleFailure(Resource resource, Throwable ex) {
|
|
||||||
if (this.logger.isDebugEnabled()) {
|
|
||||||
this.logger.debug("Ignoring candidate class resource " + resource + " due to " + ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -43,8 +43,7 @@ org.springframework.boot.context.FileEncodingApplicationListener,\
|
||||||
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
|
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
|
||||||
org.springframework.boot.context.config.DelegatingApplicationListener,\
|
org.springframework.boot.context.config.DelegatingApplicationListener,\
|
||||||
org.springframework.boot.context.logging.LoggingApplicationListener,\
|
org.springframework.boot.context.logging.LoggingApplicationListener,\
|
||||||
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener,\
|
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener
|
||||||
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
|
|
||||||
|
|
||||||
# Environment Post Processors
|
# Environment Post Processors
|
||||||
org.springframework.boot.env.EnvironmentPostProcessor=\
|
org.springframework.boot.env.EnvironmentPostProcessor=\
|
||||||
|
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012-2019 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.boot.liquibase;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import liquibase.servicelocator.CustomResolverServiceLocator;
|
|
||||||
import liquibase.servicelocator.DefaultPackageScanClassResolver;
|
|
||||||
import liquibase.servicelocator.ServiceLocator;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.WebApplicationType;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.core.io.DefaultResourceLoader;
|
|
||||||
import org.springframework.util.ReflectionUtils;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for {@link LiquibaseServiceLocatorApplicationListener}.
|
|
||||||
*
|
|
||||||
* @author Phillip Webb
|
|
||||||
* @author Stephane Nicoll
|
|
||||||
*/
|
|
||||||
class LiquibaseServiceLocatorApplicationListenerTests {
|
|
||||||
|
|
||||||
private ConfigurableApplicationContext context;
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
void cleanUp() {
|
|
||||||
if (this.context != null) {
|
|
||||||
this.context.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void replacesServiceLocator() throws IllegalAccessException {
|
|
||||||
SpringApplication application = new SpringApplication(Conf.class);
|
|
||||||
application.setWebApplicationType(WebApplicationType.NONE);
|
|
||||||
this.context = application.run();
|
|
||||||
Object resolver = getClassResolver();
|
|
||||||
assertThat(resolver).isInstanceOf(SpringPackageScanClassResolver.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void replaceServiceLocatorBacksOffIfNotPresent() throws IllegalAccessException {
|
|
||||||
SpringApplication application = new SpringApplication(Conf.class);
|
|
||||||
application.setWebApplicationType(WebApplicationType.NONE);
|
|
||||||
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
|
|
||||||
resourceLoader.setClassLoader(new ClassHidingClassLoader(CustomResolverServiceLocator.class));
|
|
||||||
application.setResourceLoader(resourceLoader);
|
|
||||||
this.context = application.run();
|
|
||||||
Object resolver = getClassResolver();
|
|
||||||
assertThat(resolver).isInstanceOf(DefaultPackageScanClassResolver.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object getClassResolver() throws IllegalAccessException {
|
|
||||||
ServiceLocator instance = ServiceLocator.getInstance();
|
|
||||||
Field field = ReflectionUtils.findField(ServiceLocator.class, "classResolver");
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field.get(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
static class Conf {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class ClassHidingClassLoader extends URLClassLoader {
|
|
||||||
|
|
||||||
private final List<Class<?>> hiddenClasses;
|
|
||||||
|
|
||||||
private ClassHidingClassLoader(Class<?>... hiddenClasses) {
|
|
||||||
super(new URL[0], LiquibaseServiceLocatorApplicationListenerTests.class.getClassLoader());
|
|
||||||
this.hiddenClasses = Arrays.asList(hiddenClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
|
||||||
if (isHidden(name)) {
|
|
||||||
throw new ClassNotFoundException();
|
|
||||||
}
|
|
||||||
return super.loadClass(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isHidden(String name) {
|
|
||||||
for (Class<?> hiddenClass : this.hiddenClasses) {
|
|
||||||
if (hiddenClass.getName().equals(name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012-2019 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.boot.liquibase;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import liquibase.logging.Logger;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for SpringPackageScanClassResolver.
|
|
||||||
*
|
|
||||||
* @author Phillip Webb
|
|
||||||
*/
|
|
||||||
class SpringPackageScanClassResolverTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testScan() {
|
|
||||||
SpringPackageScanClassResolver resolver = new SpringPackageScanClassResolver(LogFactory.getLog(getClass()));
|
|
||||||
resolver.addClassLoader(getClass().getClassLoader());
|
|
||||||
Set<Class<?>> implementations = resolver.findImplementations(Logger.class, "liquibase.logging.core");
|
|
||||||
assertThat(implementations).isNotEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue