Skip to content

Commit 08ec3d2

Browse files
committed
Improve class condition check
This commit improves a class condition check on the actual implementation rather than the general purpose interface. Closes gh-11608
1 parent 8529913 commit 08ec3d2

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

spring-boot/src/main/java/org/springframework/boot/liquibase/LiquibaseServiceLocatorApplicationListener.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2016 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,7 +40,8 @@ public class LiquibaseServiceLocatorApplicationListener
4040

4141
@Override
4242
public void onApplicationEvent(ApplicationStartingEvent event) {
43-
if (ClassUtils.isPresent("liquibase.servicelocator.ServiceLocator", null)) {
43+
if (ClassUtils.isPresent("liquibase.servicelocator.CustomResolverServiceLocator",
44+
event.getSpringApplication().getClassLoader())) {
4445
new LiquibasePresent().replaceServiceLocator();
4546
}
4647
}

spring-boot/src/test/java/org/springframework/boot/liquibase/LiquibaseServiceLocatorApplicationListenerTests.java

+58-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2016 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,14 +17,21 @@
1717
package org.springframework.boot.liquibase;
1818

1919
import java.lang.reflect.Field;
20+
import java.net.URL;
21+
import java.net.URLClassLoader;
22+
import java.util.Arrays;
23+
import java.util.List;
2024

25+
import liquibase.servicelocator.CustomResolverServiceLocator;
26+
import liquibase.servicelocator.DefaultPackageScanClassResolver;
2127
import liquibase.servicelocator.ServiceLocator;
2228
import org.junit.After;
2329
import org.junit.Test;
2430

2531
import org.springframework.boot.SpringApplication;
2632
import org.springframework.context.ConfigurableApplicationContext;
2733
import org.springframework.context.annotation.Configuration;
34+
import org.springframework.core.io.DefaultResourceLoader;
2835
import org.springframework.util.ReflectionUtils;
2936

3037
import static org.assertj.core.api.Assertions.assertThat;
@@ -33,6 +40,7 @@
3340
* Tests for {@link LiquibaseServiceLocatorApplicationListener}.
3441
*
3542
* @author Phillip Webb
43+
* @author Stephane Nicoll
3644
*/
3745
public class LiquibaseServiceLocatorApplicationListenerTests {
3846

@@ -46,20 +54,66 @@ public void cleanUp() {
4654
}
4755

4856
@Test
49-
public void replacesServiceLocator() throws Exception {
57+
public void replacesServiceLocator() throws IllegalAccessException {
5058
SpringApplication application = new SpringApplication(Conf.class);
5159
application.setWebEnvironment(false);
5260
this.context = application.run();
61+
Object resolver = getServiceLocator();
62+
assertThat(resolver).isInstanceOf(SpringPackageScanClassResolver.class);
63+
}
64+
65+
@Test
66+
public void replaceServiceLocatorBacksOffIfNotPresent()
67+
throws IllegalAccessException {
68+
SpringApplication application = new SpringApplication(Conf.class);
69+
application.setWebEnvironment(false);
70+
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
71+
resourceLoader.setClassLoader(new ClassHidingClassLoader(
72+
CustomResolverServiceLocator.class));
73+
application.setResourceLoader(resourceLoader);
74+
this.context = application.run();
75+
Object resolver = getServiceLocator();
76+
assertThat(resolver).isInstanceOf(DefaultPackageScanClassResolver.class);
77+
}
78+
79+
private Object getServiceLocator() throws IllegalAccessException {
5380
ServiceLocator instance = ServiceLocator.getInstance();
5481
Field field = ReflectionUtils.findField(ServiceLocator.class, "classResolver");
5582
field.setAccessible(true);
56-
Object resolver = field.get(instance);
57-
assertThat(resolver).isInstanceOf(SpringPackageScanClassResolver.class);
83+
return field.get(instance);
5884
}
5985

6086
@Configuration
6187
public static class Conf {
6288

6389
}
6490

91+
private final class ClassHidingClassLoader extends URLClassLoader {
92+
93+
private final List<Class<?>> hiddenClasses;
94+
95+
private ClassHidingClassLoader(Class<?>... hiddenClasses) {
96+
super(new URL[0], LiquibaseServiceLocatorApplicationListenerTests.class.getClassLoader());
97+
this.hiddenClasses = Arrays.asList(hiddenClasses);
98+
}
99+
100+
@Override
101+
public Class<?> loadClass(String name) throws ClassNotFoundException {
102+
if (isHidden(name)) {
103+
throw new ClassNotFoundException();
104+
}
105+
return super.loadClass(name);
106+
}
107+
108+
private boolean isHidden(String name) {
109+
for (Class<?> hiddenClass : this.hiddenClasses) {
110+
if (hiddenClass.getName().equals(name)) {
111+
return true;
112+
}
113+
}
114+
return false;
115+
}
116+
117+
}
118+
65119
}

0 commit comments

Comments
 (0)