diff --git a/.travis.yml b/.travis.yml index 877c34b..0fa19e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,26 +5,7 @@ cache: language: java jdk: # TODO: should work with java 1.7 - oraclejdk8 -before_install: - - git config user.name "$GIT_NAME" - - git config user.email "$GIT_EMAIL" - - git config credential.helper "store --file=.git/credentials" - - echo "https://$GH_TOKEN:@github.com" > .git/credentials - - gem install asciidoctor install: - ./mvnw install -P docs -q -U -DskipTests=true -Dmaven.test.redirectTestOutputToFile=true -- '[ "${MVN_GOAL}" == "deploy" ] && ./docs/src/main/asciidoc/ghpages.sh || echo "Not updating docs"' script: -- './mvnw -s .settings.xml $MVN_GOAL $MVN_PROFILE -nsu -Dmaven.test.redirectTestOutputToFile=true' -env: - global: - - GIT_NAME="Dave Syer" - - GIT_EMAIL=dsyer@pivotal.io - - CI_DEPLOY_USERNAME=buildmaster - - FEATURE_BRANCH=$(echo ${TRAVIS_BRANCH} | grep -q "^.*/.*$" && echo true || echo false) - - SPRING_CLOUD_BUILD=$(echo ${TRAVIS_REPO_SLUG} | grep -q "^spring-cloud/.*$" && echo true || echo false) - - MVN_GOAL=$([ "${TRAVIS_PULL_REQUEST}" == "false" -a "${TRAVIS_TAG}" == "" -a "${FEATURE_BRANCH}" == "false" -a "${SPRING_CLOUD_BUILD}" == "true" ] && echo deploy || echo install) - - VERSION=$(mvn validate | grep Building | head -1 | sed -e 's/.* //') - - MILESTONE=$(echo ${VERSION} | egrep 'M|RC' && echo true || echo false) - - MVN_PROFILE=$([ "${MILESTONE}" == "true" ] && echo -P milestone) - - secure: "mGJnfRsxSdjAwedXAB8kvC3ckc1TGHS2ym+8dP7TSPhknpM9To+S6THwTmawOpJFq09A/1OlUWeanpGEIHCXB/Oz73ZQ9xqheqFf3mk83xOV0TjIP3AzT2boTNRVFGe+LXOIRgTwg7jULl9TIf6pBUK3s5iPvLYlZhCq1Q6QEIU=" +- './mvnw install -nsu -Dmaven.test.redirectTestOutputToFile=true' diff --git a/spring-cloud-launcher/spring-cloud-launcher-cli/src/main/java/org/springframework/cloud/launcher/cli/LauncherCommand.java b/spring-cloud-launcher/spring-cloud-launcher-cli/src/main/java/org/springframework/cloud/launcher/cli/LauncherCommand.java index a4a1baa..a8e4553 100644 --- a/spring-cloud-launcher/spring-cloud-launcher-cli/src/main/java/org/springframework/cloud/launcher/cli/LauncherCommand.java +++ b/spring-cloud-launcher/spring-cloud-launcher-cli/src/main/java/org/springframework/cloud/launcher/cli/LauncherCommand.java @@ -17,9 +17,9 @@ package org.springframework.cloud.launcher.cli; import java.io.File; -import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URI; +import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; @@ -29,7 +29,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.codehaus.groovy.control.CompilerConfiguration; + import org.springframework.boot.cli.command.HelpExample; import org.springframework.boot.cli.command.OptionParsingCommand; import org.springframework.boot.cli.command.options.OptionHandler; @@ -41,7 +41,6 @@ import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; import org.springframework.util.StringUtils; -import groovy.lang.GroovyClassLoader; import joptsimple.OptionSet; import joptsimple.OptionSpec; @@ -96,21 +95,17 @@ public class LauncherCommand extends OptionParsingCommand { @Override protected synchronized ExitStatus run(OptionSet options) throws Exception { if (options.has(this.versionOption)) { - System.out.println("Spring Cloud CLI v"+getVersion()); + System.out.println("Spring Cloud CLI v" + getVersion()); return ExitStatus.OK; } try { URLClassLoader classLoader = populateClassloader(options); - - String name = "org.springframework.cloud.launcher.deployer.DeployerThread"; + // This is the main class in the deployer archive: + String name = "org.springframework.boot.loader.wrapper.ThinJarWrapper"; Class threadClass = classLoader.loadClass(name); - - Constructor constructor = threadClass.getConstructor(ClassLoader.class, - String[].class); - Thread thread = (Thread) constructor.newInstance(classLoader, - getArgs(options)); - thread.start(); - thread.join(); + URL url = classLoader.getURLs()[0]; + threadClass.getMethod("main", String[].class).invoke(null, + new Object[] { getArgs(options, url) }); } catch (Exception e) { log.error("Error running spring cloud", e); @@ -120,9 +115,10 @@ public class LauncherCommand extends OptionParsingCommand { return ExitStatus.OK; } - private String[] getArgs(OptionSet options) { + private String[] getArgs(OptionSet options, URL url) { List args = new ArrayList<>(); List apps = new ArrayList<>(); + args.add("--thin.archive=" + url.toString()); int sourceArgCount = 0; for (Object option : options.nonOptionArguments()) { if (option instanceof String) { @@ -157,10 +153,6 @@ public class LauncherCommand extends OptionParsingCommand { throws MalformedURLException { DependencyResolutionContext resolutionContext = new DependencyResolutionContext(); - GroovyClassLoader loader = new GroovyClassLoader( - Thread.currentThread().getContextClassLoader(), - new CompilerConfiguration()); - List repositoryConfiguration = RepositoryConfigurationFactory .createDefaultRepositoryConfiguration(); repositoryConfiguration.add(0, new RepositoryConfiguration("local", @@ -170,7 +162,7 @@ public class LauncherCommand extends OptionParsingCommand { System.setProperty("groovy.grape.report.downloads", "true"); } - AetherGrapeEngine grapeEngine = AetherGrapeEngineFactory.create(loader, + AetherGrapeEngine grapeEngine = AetherGrapeEngineFactory.create(null, repositoryConfiguration, resolutionContext); HashMap dependency = new HashMap<>(); @@ -178,16 +170,16 @@ public class LauncherCommand extends OptionParsingCommand { dependency.put("module", "spring-cloud-launcher-deployer"); dependency.put("version", getVersion()); URI[] uris = grapeEngine.resolve(null, dependency); - for (URI uri : uris) { - loader.addURL(uri.toURL()); - } + URLClassLoader loader = new URLClassLoader(new URL[] { uris[0].toURL() }, + getClass().getClassLoader().getParent()); log.debug("resolved URIs " + Arrays.asList(loader.getURLs())); return loader; } private String getVersion() { Package pkg = LauncherCommand.class.getPackage(); - String version = (pkg != null ? pkg.getImplementationVersion() : DEFAULT_VERSION); + String version = (pkg != null ? pkg.getImplementationVersion() + : DEFAULT_VERSION); return version != null ? version : DEFAULT_VERSION; } diff --git a/spring-cloud-launcher/spring-cloud-launcher-cli/src/test/java/org/springframework/cloud/launcher/cli/LauncherCommandTests.java b/spring-cloud-launcher/spring-cloud-launcher-cli/src/test/java/org/springframework/cloud/launcher/cli/LauncherCommandTests.java index db51b78..296aac9 100644 --- a/spring-cloud-launcher/spring-cloud-launcher-cli/src/test/java/org/springframework/cloud/launcher/cli/LauncherCommandTests.java +++ b/spring-cloud-launcher/spring-cloud-launcher-cli/src/test/java/org/springframework/cloud/launcher/cli/LauncherCommandTests.java @@ -30,7 +30,7 @@ public class LauncherCommandTests { @Rule public OutputCapture output = new OutputCapture(); - + @Test public void testCreateClassLoaderAndListDeployables() throws Exception { new LauncherCommand().run("--list"); @@ -39,7 +39,8 @@ public class LauncherCommandTests { @Test public void testNonOptionArgsPassedDown() throws Exception { - new LauncherCommand().run("--list", "--", "--spring.profiles.active=test"); + new LauncherCommand().run("--list", "--", "--spring.profiles.active=test", + "--spring.config.location=file:./src/test/resources/"); assertThat(output.toString(), containsString("foo")); } diff --git a/spring-cloud-launcher/spring-cloud-launcher-deployer/pom.xml b/spring-cloud-launcher/spring-cloud-launcher-deployer/pom.xml index f40042b..fd0d004 100644 --- a/spring-cloud-launcher/spring-cloud-launcher-deployer/pom.xml +++ b/spring-cloud-launcher/spring-cloud-launcher-deployer/pom.xml @@ -18,6 +18,7 @@ 1.1.1.RELEASE + 0.0.1.BUILD-SNAPSHOT @@ -27,6 +28,11 @@ spring-cloud-deployer-local ${spring-cloud-deployer.version} + + org.springframework.cloud + spring-cloud-deployer-thin + ${spring-cloud-deployer-thin.version} + org.springframework.cloud spring-cloud-deployer-resource-support @@ -55,4 +61,12 @@ + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/Deployer.java b/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/Deployer.java index 9737402..625f720 100644 --- a/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/Deployer.java +++ b/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/Deployer.java @@ -16,8 +16,17 @@ package org.springframework.cloud.launcher.deployer; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.boot.env.YamlPropertySourceLoader; import org.springframework.cloud.deployer.spi.app.AppDeployer; import org.springframework.cloud.deployer.spi.app.AppStatus; @@ -37,14 +46,6 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.StringUtils; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - import static org.springframework.util.StringUtils.collectionToCommaDelimitedString; /** @@ -102,8 +103,7 @@ public class Deployer { logger.debug("Deployables {}", properties.getDeployables()); for (Deployable deployable : deployables) { - deployInternal(deployer, resourceLoader, deployable, - properties, environment); + deployInternal(deployer, resourceLoader, deployable, properties, environment); } for (Deployable deployable : deployables) { @@ -251,10 +251,11 @@ public class Deployer { private PropertySource extractPropertySource(String path) { PropertySource source = null; - Resource resource = new ClassPathResource("config" + path, DeployerThread.class); + Resource resource = new ClassPathResource("config" + path, + DeployerApplication.class); source = loadPropertySource(resource, path); if (source == null) { - resource = new ClassPathResource(path, DeployerThread.class); + resource = new ClassPathResource(path, DeployerApplication.class); source = loadPropertySource(resource, path); } if (source == null) { diff --git a/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerThread.java b/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerApplication.java similarity index 84% rename from spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerThread.java rename to spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerApplication.java index 23fea51..715c3fb 100644 --- a/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerThread.java +++ b/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerApplication.java @@ -16,8 +16,14 @@ package org.springframework.cloud.launcher.deployer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.boot.Banner.Mode; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -27,31 +33,27 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - /** * @author Spencer Gibb */ -public class DeployerThread extends Thread { +public class DeployerApplication { - private static final Logger logger = LoggerFactory.getLogger(DeployerThread.class); + private static final Logger logger = LoggerFactory + .getLogger(DeployerApplication.class); - private static final String DEFAULT_VERSION = "1.2.3.BUILD-SNAPSHOT"; + private static final String DEFAULT_VERSION = "1.3.0.BUILD-SNAPSHOT"; private String[] args; - public DeployerThread(ClassLoader classLoader, String... args) { - super("spring-cloud-launcher"); + public DeployerApplication(String... args) { this.args = args; - setContextClassLoader(classLoader); - setDaemon(true); } - @Override - public void run() { + public static void main(String[] args) { + new DeployerApplication(args).run(); + } + + void run() { List list = Arrays.asList(this.args); if (list.contains("--launcher.list=true")) { quiet(); @@ -64,9 +66,10 @@ public class DeployerThread extends Thread { private void quiet() { try { - LogbackLoggingSystem.get(ClassUtils.getDefaultClassLoader()).setLogLevel("ROOT", - LogLevel.OFF); - } catch (Exception e) { + LogbackLoggingSystem.get(ClassUtils.getDefaultClassLoader()) + .setLogLevel("ROOT", LogLevel.OFF); + } + catch (Exception e) { logger.error("Unable to turn of ROOT logger for quiet()", e); } } @@ -98,7 +101,7 @@ public class DeployerThread extends Thread { } private String getVersion() { - Package pkg = DeployerThread.class.getPackage(); + Package pkg = DeployerApplication.class.getPackage(); return (pkg != null ? pkg.getImplementationVersion() : DEFAULT_VERSION); } diff --git a/spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/java/org/springframework/cloud/launcher/deployer/DeployerThreadTests.java b/spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/java/org/springframework/cloud/launcher/deployer/DeployerApplicationTests.java similarity index 74% rename from spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/java/org/springframework/cloud/launcher/deployer/DeployerThreadTests.java rename to spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/java/org/springframework/cloud/launcher/deployer/DeployerApplicationTests.java index 7d25070..c04712d 100644 --- a/spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/java/org/springframework/cloud/launcher/deployer/DeployerThreadTests.java +++ b/spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/java/org/springframework/cloud/launcher/deployer/DeployerApplicationTests.java @@ -25,26 +25,28 @@ import static org.junit.Assert.assertThat; /** * @author Spencer Gibb */ -public class DeployerThreadTests { +public class DeployerApplicationTests { @Rule public OutputCapture output = new OutputCapture(); - + @Test public void testCreateClassLoaderAndListDeployables() throws Exception { - new DeployerThread(DeployerThread.class.getClassLoader(), "--launcher.list=true").run();; + new DeployerApplication("--launcher.list=true").run(); assertThat(output.toString(), containsString("configserver")); } @Test public void testNonOptionArgsPassedDown() throws Exception { - new DeployerThread(DeployerThread.class.getClassLoader(), "--launcher.list=true", "--spring.profiles.active=test").run(); + new DeployerApplication("--launcher.list=true", "--spring.profiles.active=test") + .run(); assertThat(output.toString(), containsString("foo")); } @Test public void testInvalidDeployableFails() throws Exception { - new DeployerThread(DeployerThread.class.getClassLoader(), "--launcher.deploy=foo,bar").run(); - assertThat(output.toString(), containsString("The following are not valid: 'foo,bar'")); + new DeployerApplication("--launcher.deploy=foo,bar").run(); + assertThat(output.toString(), + containsString("The following are not valid: 'foo,bar'")); } }