mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Refactor PropertiesLauncher so jars can be closed
Refactor the internals of `PropertiesLauncher` so that opened jar files are tracked and can be closed after a test completes. See gh-21575
This commit is contained in:
parent
29f5468ada
commit
8a249daf1a
@ -29,9 +29,11 @@ import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Manifest;
|
||||
@ -144,7 +146,9 @@ public class PropertiesLauncher extends Launcher {
|
||||
|
||||
private final Properties properties = new Properties();
|
||||
|
||||
private Archive parent;
|
||||
private final Archive parent;
|
||||
|
||||
private volatile ClassPathArchives classPathArchives;
|
||||
|
||||
public PropertiesLauncher() {
|
||||
try {
|
||||
@ -346,18 +350,19 @@ public class PropertiesLauncher extends Launcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassLoader createClassLoader(List<Archive> archives) throws Exception {
|
||||
Set<URL> urls = new LinkedHashSet<>(archives.size());
|
||||
for (Archive archive : archives) {
|
||||
urls.add(archive.getUrl());
|
||||
protected ClassLoader createClassLoader(Iterator<Archive> archives) throws Exception {
|
||||
String customLoaderClassName = getProperty("loader.classLoader");
|
||||
if (customLoaderClassName == null) {
|
||||
return super.createClassLoader(archives);
|
||||
}
|
||||
Set<URL> urls = new LinkedHashSet<>();
|
||||
while (archives.hasNext()) {
|
||||
urls.add(archives.next().getUrl());
|
||||
}
|
||||
ClassLoader loader = new LaunchedURLClassLoader(urls.toArray(NO_URLS), getClass().getClassLoader());
|
||||
debug("Classpath: " + urls);
|
||||
String customLoaderClassName = getProperty("loader.classLoader");
|
||||
if (customLoaderClassName != null) {
|
||||
loader = wrapWithCustomClassLoader(loader, customLoaderClassName);
|
||||
debug("Using custom class loader: " + customLoaderClassName);
|
||||
}
|
||||
debug("Classpath for custom loader: " + urls);
|
||||
loader = wrapWithCustomClassLoader(loader, customLoaderClassName);
|
||||
debug("Using custom class loader: " + customLoaderClassName);
|
||||
return loader;
|
||||
}
|
||||
|
||||
@ -449,153 +454,12 @@ public class PropertiesLauncher extends Launcher {
|
||||
|
||||
@Override
|
||||
protected Iterator<Archive> getClassPathArchivesIterator() throws Exception {
|
||||
List<Archive> lib = new ArrayList<>();
|
||||
for (String path : this.paths) {
|
||||
for (Archive archive : getClassPathArchives(path)) {
|
||||
if (archive instanceof ExplodedArchive) {
|
||||
List<Archive> nested = asList(archive.getNestedArchives(null, new ArchiveEntryFilter()));
|
||||
nested.add(0, archive);
|
||||
lib.addAll(nested);
|
||||
}
|
||||
else {
|
||||
lib.add(archive);
|
||||
}
|
||||
}
|
||||
ClassPathArchives classPathArchives = this.classPathArchives;
|
||||
if (classPathArchives == null) {
|
||||
classPathArchives = new ClassPathArchives();
|
||||
this.classPathArchives = classPathArchives;
|
||||
}
|
||||
addNestedEntries(lib);
|
||||
return lib.iterator();
|
||||
}
|
||||
|
||||
private List<Archive> getClassPathArchives(String path) throws Exception {
|
||||
String root = cleanupPath(handleUrl(path));
|
||||
List<Archive> lib = new ArrayList<>();
|
||||
File file = new File(root);
|
||||
if (!"/".equals(root)) {
|
||||
if (!isAbsolutePath(root)) {
|
||||
file = new File(this.home, root);
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
debug("Adding classpath entries from " + file);
|
||||
Archive archive = new ExplodedArchive(file, false);
|
||||
lib.add(archive);
|
||||
}
|
||||
}
|
||||
Archive archive = getArchive(file);
|
||||
if (archive != null) {
|
||||
debug("Adding classpath entries from archive " + archive.getUrl() + root);
|
||||
lib.add(archive);
|
||||
}
|
||||
List<Archive> nestedArchives = getNestedArchives(root);
|
||||
if (nestedArchives != null) {
|
||||
debug("Adding classpath entries from nested " + root);
|
||||
lib.addAll(nestedArchives);
|
||||
}
|
||||
return lib;
|
||||
}
|
||||
|
||||
private boolean isAbsolutePath(String root) {
|
||||
// Windows contains ":" others start with "/"
|
||||
return root.contains(":") || root.startsWith("/");
|
||||
}
|
||||
|
||||
private Archive getArchive(File file) throws IOException {
|
||||
if (isNestedArchivePath(file)) {
|
||||
return null;
|
||||
}
|
||||
String name = file.getName().toLowerCase(Locale.ENGLISH);
|
||||
if (name.endsWith(".jar") || name.endsWith(".zip")) {
|
||||
return new JarFileArchive(file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isNestedArchivePath(File file) {
|
||||
return file.getPath().contains(NESTED_ARCHIVE_SEPARATOR);
|
||||
}
|
||||
|
||||
private List<Archive> getNestedArchives(String path) throws Exception {
|
||||
Archive parent = this.parent;
|
||||
String root = path;
|
||||
if (!root.equals("/") && root.startsWith("/") || parent.getUrl().toURI().equals(this.home.toURI())) {
|
||||
// If home dir is same as parent archive, no need to add it twice.
|
||||
return null;
|
||||
}
|
||||
int index = root.indexOf('!');
|
||||
if (index != -1) {
|
||||
File file = new File(this.home, root.substring(0, index));
|
||||
if (root.startsWith("jar:file:")) {
|
||||
file = new File(root.substring("jar:file:".length(), index));
|
||||
}
|
||||
parent = new JarFileArchive(file);
|
||||
root = root.substring(index + 1);
|
||||
while (root.startsWith("/")) {
|
||||
root = root.substring(1);
|
||||
}
|
||||
}
|
||||
if (root.endsWith(".jar")) {
|
||||
File file = new File(this.home, root);
|
||||
if (file.exists()) {
|
||||
parent = new JarFileArchive(file);
|
||||
root = "";
|
||||
}
|
||||
}
|
||||
if (root.equals("/") || root.equals("./") || root.equals(".")) {
|
||||
// The prefix for nested jars is actually empty if it's at the root
|
||||
root = "";
|
||||
}
|
||||
EntryFilter filter = new PrefixMatchingArchiveFilter(root);
|
||||
List<Archive> archives = asList(parent.getNestedArchives(null, filter));
|
||||
if (("".equals(root) || ".".equals(root)) && !path.endsWith(".jar") && parent != this.parent) {
|
||||
// You can't find the root with an entry filter so it has to be added
|
||||
// explicitly. But don't add the root of the parent archive.
|
||||
archives.add(parent);
|
||||
}
|
||||
return archives;
|
||||
}
|
||||
|
||||
private void addNestedEntries(List<Archive> lib) {
|
||||
// The parent archive might have "BOOT-INF/lib/" and "BOOT-INF/classes/"
|
||||
// directories, meaning we are running from an executable JAR. We add nested
|
||||
// entries from there with low priority (i.e. at end).
|
||||
try {
|
||||
Iterator<Archive> archives = this.parent.getNestedArchives(null, JarLauncher.NESTED_ARCHIVE_ENTRY_FILTER);
|
||||
while (archives.hasNext()) {
|
||||
lib.add(archives.next());
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
private String cleanupPath(String path) {
|
||||
path = path.trim();
|
||||
// No need for current dir path
|
||||
if (path.startsWith("./")) {
|
||||
path = path.substring(2);
|
||||
}
|
||||
String lowerCasePath = path.toLowerCase(Locale.ENGLISH);
|
||||
if (lowerCasePath.endsWith(".jar") || lowerCasePath.endsWith(".zip")) {
|
||||
return path;
|
||||
}
|
||||
if (path.endsWith("/*")) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
else {
|
||||
// It's a directory
|
||||
if (!path.endsWith("/") && !path.equals(".")) {
|
||||
path = path + "/";
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
private List<Archive> asList(Iterator<Archive> iterator) {
|
||||
List<Archive> list = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
list.add(iterator.next());
|
||||
}
|
||||
return list;
|
||||
return classPathArchives.iterator();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -629,6 +493,200 @@ public class PropertiesLauncher extends Launcher {
|
||||
}
|
||||
}
|
||||
|
||||
private String cleanupPath(String path) {
|
||||
path = path.trim();
|
||||
// No need for current dir path
|
||||
if (path.startsWith("./")) {
|
||||
path = path.substring(2);
|
||||
}
|
||||
String lowerCasePath = path.toLowerCase(Locale.ENGLISH);
|
||||
if (lowerCasePath.endsWith(".jar") || lowerCasePath.endsWith(".zip")) {
|
||||
return path;
|
||||
}
|
||||
if (path.endsWith("/*")) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
else {
|
||||
// It's a directory
|
||||
if (!path.endsWith("/") && !path.equals(".")) {
|
||||
path = path + "/";
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
void close() throws Exception {
|
||||
if (this.classPathArchives != null) {
|
||||
this.classPathArchives.close();
|
||||
}
|
||||
if (this.parent != null) {
|
||||
this.parent.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An iterable collection of the classpath archives.
|
||||
*/
|
||||
private class ClassPathArchives implements Iterable<Archive> {
|
||||
|
||||
private final List<Archive> classPathArchives;
|
||||
|
||||
private final Map<File, JarFileArchive> jarFileArchives = new LinkedHashMap<>();
|
||||
|
||||
ClassPathArchives() throws Exception {
|
||||
this.classPathArchives = new ArrayList<>();
|
||||
for (String path : PropertiesLauncher.this.paths) {
|
||||
for (Archive archive : getClassPathArchives(path)) {
|
||||
addClassPathArchive(archive);
|
||||
}
|
||||
}
|
||||
addNestedEntries();
|
||||
}
|
||||
|
||||
private void addClassPathArchive(Archive archive) throws IOException {
|
||||
if (!(archive instanceof ExplodedArchive)) {
|
||||
this.classPathArchives.add(archive);
|
||||
return;
|
||||
}
|
||||
this.classPathArchives.add(archive);
|
||||
this.classPathArchives.addAll(asList(archive.getNestedArchives(null, new ArchiveEntryFilter())));
|
||||
}
|
||||
|
||||
private List<Archive> getClassPathArchives(String path) throws Exception {
|
||||
String root = cleanupPath(handleUrl(path));
|
||||
List<Archive> lib = new ArrayList<>();
|
||||
File file = new File(root);
|
||||
if (!"/".equals(root)) {
|
||||
if (!isAbsolutePath(root)) {
|
||||
file = new File(PropertiesLauncher.this.home, root);
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
debug("Adding classpath entries from " + file);
|
||||
Archive archive = new ExplodedArchive(file, false);
|
||||
lib.add(archive);
|
||||
}
|
||||
}
|
||||
Archive archive = getArchive(file);
|
||||
if (archive != null) {
|
||||
debug("Adding classpath entries from archive " + archive.getUrl() + root);
|
||||
lib.add(archive);
|
||||
}
|
||||
List<Archive> nestedArchives = getNestedArchives(root);
|
||||
if (nestedArchives != null) {
|
||||
debug("Adding classpath entries from nested " + root);
|
||||
lib.addAll(nestedArchives);
|
||||
}
|
||||
return lib;
|
||||
}
|
||||
|
||||
private boolean isAbsolutePath(String root) {
|
||||
// Windows contains ":" others start with "/"
|
||||
return root.contains(":") || root.startsWith("/");
|
||||
}
|
||||
|
||||
private Archive getArchive(File file) throws IOException {
|
||||
if (isNestedArchivePath(file)) {
|
||||
return null;
|
||||
}
|
||||
String name = file.getName().toLowerCase(Locale.ENGLISH);
|
||||
if (name.endsWith(".jar") || name.endsWith(".zip")) {
|
||||
return getJarFileArchive(file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isNestedArchivePath(File file) {
|
||||
return file.getPath().contains(NESTED_ARCHIVE_SEPARATOR);
|
||||
}
|
||||
|
||||
private List<Archive> getNestedArchives(String path) throws Exception {
|
||||
Archive parent = PropertiesLauncher.this.parent;
|
||||
String root = path;
|
||||
if (!root.equals("/") && root.startsWith("/")
|
||||
|| parent.getUrl().toURI().equals(PropertiesLauncher.this.home.toURI())) {
|
||||
// If home dir is same as parent archive, no need to add it twice.
|
||||
return null;
|
||||
}
|
||||
int index = root.indexOf('!');
|
||||
if (index != -1) {
|
||||
File file = new File(PropertiesLauncher.this.home, root.substring(0, index));
|
||||
if (root.startsWith("jar:file:")) {
|
||||
file = new File(root.substring("jar:file:".length(), index));
|
||||
}
|
||||
parent = getJarFileArchive(file);
|
||||
root = root.substring(index + 1);
|
||||
while (root.startsWith("/")) {
|
||||
root = root.substring(1);
|
||||
}
|
||||
}
|
||||
if (root.endsWith(".jar")) {
|
||||
File file = new File(PropertiesLauncher.this.home, root);
|
||||
if (file.exists()) {
|
||||
parent = getJarFileArchive(file);
|
||||
root = "";
|
||||
}
|
||||
}
|
||||
if (root.equals("/") || root.equals("./") || root.equals(".")) {
|
||||
// The prefix for nested jars is actually empty if it's at the root
|
||||
root = "";
|
||||
}
|
||||
EntryFilter filter = new PrefixMatchingArchiveFilter(root);
|
||||
List<Archive> archives = asList(parent.getNestedArchives(null, filter));
|
||||
if (("".equals(root) || ".".equals(root)) && !path.endsWith(".jar")
|
||||
&& parent != PropertiesLauncher.this.parent) {
|
||||
// You can't find the root with an entry filter so it has to be added
|
||||
// explicitly. But don't add the root of the parent archive.
|
||||
archives.add(parent);
|
||||
}
|
||||
return archives;
|
||||
}
|
||||
|
||||
private void addNestedEntries() {
|
||||
// The parent archive might have "BOOT-INF/lib/" and "BOOT-INF/classes/"
|
||||
// directories, meaning we are running from an executable JAR. We add nested
|
||||
// entries from there with low priority (i.e. at end).
|
||||
try {
|
||||
Iterator<Archive> archives = PropertiesLauncher.this.parent.getNestedArchives(null,
|
||||
JarLauncher.NESTED_ARCHIVE_ENTRY_FILTER);
|
||||
while (archives.hasNext()) {
|
||||
this.classPathArchives.add(archives.next());
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
private List<Archive> asList(Iterator<Archive> iterator) {
|
||||
List<Archive> list = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
list.add(iterator.next());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private JarFileArchive getJarFileArchive(File file) throws IOException {
|
||||
JarFileArchive archive = this.jarFileArchives.get(file);
|
||||
if (archive == null) {
|
||||
archive = new JarFileArchive(file);
|
||||
this.jarFileArchives.put(file, archive);
|
||||
}
|
||||
return archive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Archive> iterator() {
|
||||
return this.classPathArchives.iterator();
|
||||
}
|
||||
|
||||
void close() throws IOException {
|
||||
for (JarFileArchive archive : this.jarFileArchives.values()) {
|
||||
archive.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience class for finding nested archives that have a prefix in their file path
|
||||
* (e.g. "lib/").
|
||||
|
@ -65,6 +65,8 @@ class PropertiesLauncherTests {
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
private PropertiesLauncher launcher;
|
||||
|
||||
private ClassLoader contextClassLoader;
|
||||
|
||||
private CapturedOutput output;
|
||||
@ -88,6 +90,9 @@ class PropertiesLauncherTests {
|
||||
System.clearProperty("loader.system");
|
||||
System.clearProperty("loader.classLoader");
|
||||
clearHandlerCache();
|
||||
if (this.launcher != null) {
|
||||
this.launcher.close();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -105,16 +110,16 @@ class PropertiesLauncherTests {
|
||||
@Test
|
||||
void testDefaultHome() {
|
||||
System.clearProperty("loader.home");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(launcher.getHomeDirectory()).isEqualTo(new File(System.getProperty("user.dir")));
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(this.launcher.getHomeDirectory()).isEqualTo(new File(System.getProperty("user.dir")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAlternateHome() throws Exception {
|
||||
System.setProperty("loader.home", "src/test/resources/home");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(launcher.getHomeDirectory()).isEqualTo(new File(System.getProperty("loader.home")));
|
||||
assertThat(launcher.getMainClass()).isEqualTo("demo.HomeApplication");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(this.launcher.getHomeDirectory()).isEqualTo(new File(System.getProperty("loader.home")));
|
||||
assertThat(this.launcher.getMainClass()).isEqualTo("demo.HomeApplication");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -126,40 +131,40 @@ class PropertiesLauncherTests {
|
||||
|
||||
@Test
|
||||
void testUserSpecifiedMain() throws Exception {
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(launcher.getMainClass()).isEqualTo("demo.Application");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(this.launcher.getMainClass()).isEqualTo("demo.Application");
|
||||
assertThat(System.getProperty("loader.main")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUserSpecifiedConfigName() throws Exception {
|
||||
System.setProperty("loader.config.name", "foo");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(launcher.getMainClass()).isEqualTo("my.Application");
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString()).isEqualTo("[etc/]");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(this.launcher.getMainClass()).isEqualTo("my.Application");
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString()).isEqualTo("[etc/]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRootOfClasspathFirst() throws Exception {
|
||||
System.setProperty("loader.config.name", "bar");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(launcher.getMainClass()).isEqualTo("my.BarApplication");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(this.launcher.getMainClass()).isEqualTo("my.BarApplication");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUserSpecifiedDotPath() {
|
||||
System.setProperty("loader.path", ".");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString()).isEqualTo("[.]");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString()).isEqualTo("[.]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUserSpecifiedSlashPath() throws Exception {
|
||||
System.setProperty("loader.path", "jars/");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString()).isEqualTo("[jars/]");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString()).isEqualTo("[jars/]");
|
||||
List<Archive> archives = new ArrayList<>();
|
||||
launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
this.launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
assertThat(archives).areExactly(1, endingWith("app.jar"));
|
||||
}
|
||||
|
||||
@ -167,9 +172,9 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedWildcardPath() throws Exception {
|
||||
System.setProperty("loader.path", "jars/*");
|
||||
System.setProperty("loader.main", "demo.Application");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString()).isEqualTo("[jars/]");
|
||||
launcher.launch(new String[0]);
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString()).isEqualTo("[jars/]");
|
||||
this.launcher.launch(new String[0]);
|
||||
waitFor("Hello World");
|
||||
}
|
||||
|
||||
@ -177,20 +182,20 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedJarPath() throws Exception {
|
||||
System.setProperty("loader.path", "jars/app.jar");
|
||||
System.setProperty("loader.main", "demo.Application");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString()).isEqualTo("[jars/app.jar]");
|
||||
launcher.launch(new String[0]);
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString()).isEqualTo("[jars/app.jar]");
|
||||
this.launcher.launch(new String[0]);
|
||||
waitFor("Hello World");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUserSpecifiedRootOfJarPath() throws Exception {
|
||||
System.setProperty("loader.path", "jar:file:./src/test/resources/nested-jars/app.jar!/");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString())
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString())
|
||||
.isEqualTo("[jar:file:./src/test/resources/nested-jars/app.jar!/]");
|
||||
List<Archive> archives = new ArrayList<>();
|
||||
launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
this.launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
assertThat(archives).areExactly(1, endingWith("foo.jar!/"));
|
||||
assertThat(archives).areExactly(1, endingWith("app.jar"));
|
||||
}
|
||||
@ -198,9 +203,9 @@ class PropertiesLauncherTests {
|
||||
@Test
|
||||
void testUserSpecifiedRootOfJarPathWithDot() throws Exception {
|
||||
System.setProperty("loader.path", "nested-jars/app.jar!/./");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
this.launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = new ArrayList<>();
|
||||
launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
this.launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
assertThat(archives).areExactly(1, endingWith("foo.jar!/"));
|
||||
assertThat(archives).areExactly(1, endingWith("app.jar"));
|
||||
}
|
||||
@ -208,9 +213,9 @@ class PropertiesLauncherTests {
|
||||
@Test
|
||||
void testUserSpecifiedRootOfJarPathWithDotAndJarPrefix() throws Exception {
|
||||
System.setProperty("loader.path", "jar:file:./src/test/resources/nested-jars/app.jar!/./");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
this.launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = new ArrayList<>();
|
||||
launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
this.launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
assertThat(archives).areExactly(1, endingWith("foo.jar!/"));
|
||||
}
|
||||
|
||||
@ -218,9 +223,9 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedJarFileWithNestedArchives() throws Exception {
|
||||
System.setProperty("loader.path", "nested-jars/app.jar");
|
||||
System.setProperty("loader.main", "demo.Application");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
this.launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = new ArrayList<>();
|
||||
launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
this.launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
assertThat(archives).areExactly(1, endingWith("foo.jar!/"));
|
||||
assertThat(archives).areExactly(1, endingWith("app.jar"));
|
||||
}
|
||||
@ -229,9 +234,9 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedNestedJarPath() throws Exception {
|
||||
System.setProperty("loader.path", "nested-jars/app.jar!/foo.jar");
|
||||
System.setProperty("loader.main", "demo.Application");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
this.launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = new ArrayList<>();
|
||||
launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
this.launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
assertThat(archives).hasSize(1).areExactly(1, endingWith("foo.jar!/"));
|
||||
}
|
||||
|
||||
@ -239,8 +244,8 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedDirectoryContainingJarFileWithNestedArchives() throws Exception {
|
||||
System.setProperty("loader.path", "nested-jars");
|
||||
System.setProperty("loader.main", "demo.Application");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
launcher.launch(new String[0]);
|
||||
this.launcher = new PropertiesLauncher();
|
||||
this.launcher.launch(new String[0]);
|
||||
waitFor("Hello World");
|
||||
}
|
||||
|
||||
@ -248,9 +253,9 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedJarPathWithDot() throws Exception {
|
||||
System.setProperty("loader.path", "./jars/app.jar");
|
||||
System.setProperty("loader.main", "demo.Application");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString()).isEqualTo("[jars/app.jar]");
|
||||
launcher.launch(new String[0]);
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString()).isEqualTo("[jars/app.jar]");
|
||||
this.launcher.launch(new String[0]);
|
||||
waitFor("Hello World");
|
||||
}
|
||||
|
||||
@ -258,9 +263,9 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedClassLoader() throws Exception {
|
||||
System.setProperty("loader.path", "jars/app.jar");
|
||||
System.setProperty("loader.classLoader", URLClassLoader.class.getName());
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString()).isEqualTo("[jars/app.jar]");
|
||||
launcher.launch(new String[0]);
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString()).isEqualTo("[jars/app.jar]");
|
||||
this.launcher.launch(new String[0]);
|
||||
waitFor("Hello World");
|
||||
}
|
||||
|
||||
@ -268,18 +273,18 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedClassPathOrder() throws Exception {
|
||||
System.setProperty("loader.path", "more-jars/app.jar,jars/app.jar");
|
||||
System.setProperty("loader.classLoader", URLClassLoader.class.getName());
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(launcher, "paths").toString())
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(ReflectionTestUtils.getField(this.launcher, "paths").toString())
|
||||
.isEqualTo("[more-jars/app.jar, jars/app.jar]");
|
||||
launcher.launch(new String[0]);
|
||||
this.launcher.launch(new String[0]);
|
||||
waitFor("Hello Other World");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCustomClassLoaderCreation() throws Exception {
|
||||
System.setProperty("loader.classLoader", TestLoader.class.getName());
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
ClassLoader loader = launcher.createClassLoader(archives());
|
||||
this.launcher = new PropertiesLauncher();
|
||||
ClassLoader loader = this.launcher.createClassLoader(archives());
|
||||
assertThat(loader).isNotNull();
|
||||
assertThat(loader.getClass().getName()).isEqualTo(TestLoader.class.getName());
|
||||
}
|
||||
@ -311,15 +316,15 @@ class PropertiesLauncherTests {
|
||||
void testUserSpecifiedConfigPathWins() throws Exception {
|
||||
System.setProperty("loader.config.name", "foo");
|
||||
System.setProperty("loader.config.location", "classpath:bar.properties");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(launcher.getMainClass()).isEqualTo("my.BarApplication");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(this.launcher.getMainClass()).isEqualTo("my.BarApplication");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSystemPropertySpecifiedMain() throws Exception {
|
||||
System.setProperty("loader.main", "foo.Bar");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(launcher.getMainClass()).isEqualTo("foo.Bar");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(this.launcher.getMainClass()).isEqualTo("foo.Bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -332,8 +337,8 @@ class PropertiesLauncherTests {
|
||||
@Test
|
||||
void testArgsEnhanced() throws Exception {
|
||||
System.setProperty("loader.args", "foo");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(Arrays.asList(launcher.getArgs("bar")).toString()).isEqualTo("[foo, bar]");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(Arrays.asList(this.launcher.getArgs("bar")).toString()).isEqualTo("[foo, bar]");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -348,15 +353,16 @@ class PropertiesLauncherTests {
|
||||
try (FileOutputStream manifestStream = new FileOutputStream(manifestFile)) {
|
||||
manifest.write(manifestStream);
|
||||
}
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat((List<String>) ReflectionTestUtils.getField(launcher, "paths")).containsExactly("/foo.jar", "/bar/");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat((List<String>) ReflectionTestUtils.getField(this.launcher, "paths")).containsExactly("/foo.jar",
|
||||
"/bar/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testManifestWithPlaceholders() throws Exception {
|
||||
System.setProperty("loader.home", "src/test/resources/placeholders");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
assertThat(launcher.getMainClass()).isEqualTo("demo.FooApplication");
|
||||
this.launcher = new PropertiesLauncher();
|
||||
assertThat(this.launcher.getMainClass()).isEqualTo("demo.FooApplication");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -364,9 +370,9 @@ class PropertiesLauncherTests {
|
||||
File loaderPath = new File(this.tempDir, "loader path");
|
||||
loaderPath.mkdir();
|
||||
System.setProperty("loader.path", loaderPath.toURI().toURL().toString());
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
this.launcher = new PropertiesLauncher();
|
||||
List<Archive> archives = new ArrayList<>();
|
||||
launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
this.launcher.getClassPathArchivesIterator().forEachRemaining(archives::add);
|
||||
assertThat(archives.size()).isEqualTo(1);
|
||||
File archiveRoot = (File) ReflectionTestUtils.getField(archives.get(0), "root");
|
||||
assertThat(archiveRoot).isEqualTo(loaderPath);
|
||||
@ -378,9 +384,9 @@ class PropertiesLauncherTests {
|
||||
TestJarCreator.createTestJar(jarFile);
|
||||
System.setProperty("loader.home", this.tempDir.getAbsolutePath());
|
||||
System.setProperty("loader.path", "app.jar");
|
||||
PropertiesLauncher launcher = new PropertiesLauncher();
|
||||
this.launcher = new PropertiesLauncher();
|
||||
try {
|
||||
launcher.launch(new String[0]);
|
||||
this.launcher.launch(new String[0]);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user