From 3107f08b8730626159deb4392cdd6dbca37bfe41 Mon Sep 17 00:00:00 2001 From: Peter Palaga Date: Sun, 21 Jun 2020 20:04:29 +0200 Subject: [PATCH] Improve environment defaults --- .../fuse/mvnd/client/BuildProperties.java | 49 +++++++++ .../fuse/mvnd/client/DaemonConnector.java | 64 ++++++++++- .../jboss/fuse/mvnd/client/DefaultClient.java | 103 ++---------------- .../jboss/fuse/mvnd/client/Environment.java | 2 +- .../fuse/mvnd/it/InstallDaemonNativeIT.java | 3 +- .../fuse/mvnd/junit/MvndTestExtension.java | 3 +- 6 files changed, 125 insertions(+), 99 deletions(-) create mode 100644 client/src/main/java/org/jboss/fuse/mvnd/client/BuildProperties.java diff --git a/client/src/main/java/org/jboss/fuse/mvnd/client/BuildProperties.java b/client/src/main/java/org/jboss/fuse/mvnd/client/BuildProperties.java new file mode 100644 index 00000000..7044dec8 --- /dev/null +++ b/client/src/main/java/org/jboss/fuse/mvnd/client/BuildProperties.java @@ -0,0 +1,49 @@ +/* + * Copyright 2018 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 + * + * http://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.jboss.fuse.mvnd.client; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class BuildProperties { + + private static final BuildProperties INSTANCE = load(); + + public static BuildProperties getInstance() { + return INSTANCE; + } + + public static BuildProperties load() { + final Properties buildProperties = new Properties(); + try (InputStream is = BuildProperties.class.getResourceAsStream("build.properties")) { + buildProperties.load(is); + } catch (IOException e) { + throw new RuntimeException("Could not read build.properties"); + } + return new BuildProperties(buildProperties.getProperty("version")); + } + + private final String version; + + public BuildProperties(String version) { + this.version = version; + } + + public String getVersion() { + return version; + } +} diff --git a/client/src/main/java/org/jboss/fuse/mvnd/client/DaemonConnector.java b/client/src/main/java/org/jboss/fuse/mvnd/client/DaemonConnector.java index 29d75c52..ef0eb6f5 100644 --- a/client/src/main/java/org/jboss/fuse/mvnd/client/DaemonConnector.java +++ b/client/src/main/java/org/jboss/fuse/mvnd/client/DaemonConnector.java @@ -18,6 +18,8 @@ package org.jboss.fuse.mvnd.client; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.channels.SocketChannel; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -25,10 +27,13 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import org.jboss.fuse.mvnd.client.DaemonCompatibilitySpec.Result; +import org.jboss.fuse.mvnd.jpm.Process; +import org.jboss.fuse.mvnd.jpm.ScriptUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,14 +49,14 @@ public class DaemonConnector { private static final Logger LOGGER = LoggerFactory.getLogger(DaemonConnector.class); private final DaemonRegistry registry; - private final Layout layout; - private final DaemonStarter daemonStarter; + private final ClientLayout layout; private final Serializer serializer; + private final BuildProperties buildProperties; - public DaemonConnector(Layout layout, DaemonRegistry registry, DaemonStarter daemonStarter, Serializer serializer) { + public DaemonConnector(ClientLayout layout, DaemonRegistry registry, BuildProperties buildProperties, Serializer serializer) { this.layout = layout; this.registry = registry; - this.daemonStarter = daemonStarter; + this.buildProperties = buildProperties; this.serializer = serializer; } @@ -203,7 +208,7 @@ public class DaemonConnector { } public DaemonClientConnection startDaemon(DaemonCompatibilitySpec constraint) { - final String daemon = daemonStarter.startDaemon(); + final String daemon = startDaemon(); LOGGER.debug("Started Maven daemon {}", daemon); long start = System.currentTimeMillis(); do { @@ -221,6 +226,55 @@ public class DaemonConnector { throw new DaemonException.ConnectException("Timeout waiting to connect to the Maven daemon.\n" + diag.describe()); } + private String startDaemon() { + + final String uid = UUID.randomUUID().toString(); + final Path mavenHome = layout.mavenHome(); + final Path workingDir = layout.userDir(); + String command = ""; + try { + String classpath = findClientJar(mavenHome).toString(); + final String java = ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java"; + List args = new ArrayList<>(); + args.add("\"" + layout.javaHome().resolve(java) + "\""); + args.add("-classpath"); + args.add("\"" + classpath + "\""); + if (Environment.DAEMON_DEBUG.systemProperty().orDefault(() -> "false").asBoolean()) { + args.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"); + } + args.add("-Dmaven.home=\"" + mavenHome + "\""); + args.add("-Dlogback.configurationFile=logback.xml"); + args.add("-Ddaemon.uid=" + uid); + args.add("-Xmx4g"); + final String timeout = Environment.DAEMON_IDLE_TIMEOUT.systemProperty().asString(); + if (timeout != null) { + args.add(Environment.DAEMON_IDLE_TIMEOUT.asCommandLineProperty(timeout)); + } + args.add("\"-Dmaven.multiModuleProjectDirectory=" + layout.multiModuleProjectDirectory().toString() + "\""); + + args.add(ServerMain.class.getName()); + command = String.join(" ", args); + + LOGGER.debug("Starting daemon process: uid = {}, workingDir = {}, daemonArgs: {}", uid, workingDir, command); + Process.create(workingDir.toFile(), command); + return uid; + } catch (Exception e) { + throw new DaemonException.StartException( + String.format("Error starting daemon: uid = %s, workingDir = %s, daemonArgs: %s", + uid, workingDir, command), + e); + } + } + + private Path findClientJar(Path mavenHome) { + final Path result = mavenHome.resolve("lib/ext/mvnd-client-" + buildProperties.getVersion() + ".jar"); + if (!Files.isRegularFile(result)) { + throw new RuntimeException("File must exist and must be a regular file: " + result); + } + return result; + } + + private DaemonClientConnection connectToDaemonWithId(String daemon) throws DaemonException.ConnectException { // Look for 'our' daemon among the busy daemons - a daemon will start in busy state so that nobody else will grab it. DaemonInfo daemonInfo = registry.get(daemon); diff --git a/client/src/main/java/org/jboss/fuse/mvnd/client/DefaultClient.java b/client/src/main/java/org/jboss/fuse/mvnd/client/DefaultClient.java index e92fd232..fe1d2f56 100644 --- a/client/src/main/java/org/jboss/fuse/mvnd/client/DefaultClient.java +++ b/client/src/main/java/org/jboss/fuse/mvnd/client/DefaultClient.java @@ -16,9 +16,7 @@ package org.jboss.fuse.mvnd.client; import java.io.IOException; -import java.io.InputStream; import java.net.URI; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.Instant; @@ -27,9 +25,8 @@ import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.Properties; -import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.stream.Stream; +import java.util.function.Supplier; import org.fusesource.jansi.Ansi; import org.jboss.fuse.mvnd.client.ClientOutput.TerminalOutput; @@ -37,9 +34,7 @@ import org.jboss.fuse.mvnd.client.Message.BuildEvent; import org.jboss.fuse.mvnd.client.Message.BuildException; import org.jboss.fuse.mvnd.client.Message.BuildMessage; import org.jboss.fuse.mvnd.client.Message.MessageSerializer; -import org.jboss.fuse.mvnd.jpm.Process; import org.jboss.fuse.mvnd.jpm.ProcessImpl; -import org.jboss.fuse.mvnd.jpm.ScriptUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,8 +44,8 @@ public class DefaultClient implements Client { public static final int DEFAULT_IDLE_TIMEOUT = (int) TimeUnit.HOURS.toMillis(3); public static final int DEFAULT_PERIODIC_CHECK_INTERVAL_MILLIS = 10 * 1000; public static final int CANCEL_TIMEOUT = 10 * 1000; - private final ClientLayout layout; - private final Properties buildProperties; + private final Supplier lazyLayout; + private final BuildProperties buildProperties; public static void main(String[] argv) throws Exception { final List args = new ArrayList<>(argv.length); @@ -71,13 +66,11 @@ public class DefaultClient implements Client { } try (TerminalOutput output = new TerminalOutput(logFile)) { - new DefaultClient(ClientLayout.getEnvInstance()).execute(output, args); + new DefaultClient(() -> ClientLayout.getEnvInstance(), BuildProperties.getInstance()).execute(output, args); } } - private static void install(boolean overwrite, final Properties commandLineProperties) { - final Properties buildProps = loadBuildProperties(); - final String version = buildProps.getProperty("version"); + private static void install(boolean overwrite, final Properties commandLineProperties, String version) { final String rawZipUri = Environment.MVND_DIST_URI .commandLineProperty(() -> commandLineProperties) .orEnvironmentVariable() @@ -106,19 +99,9 @@ public class DefaultClient implements Client { Installer.installServer(zipUri, mvndPropertiesPath, mvndHome, javaHome, overwrite); } - public DefaultClient(ClientLayout layout) { - this.layout = layout; - this.buildProperties = loadBuildProperties(); - } - - public static Properties loadBuildProperties() { - final Properties result = new Properties(); - try (InputStream is = DefaultClient.class.getResourceAsStream("build.properties")) { - result.load(is); - } catch (IOException e) { - throw new RuntimeException("Could not read build.properties"); - } - return result; + public DefaultClient(Supplier layout, BuildProperties buildProperties) { + this.lazyLayout = layout; + this.buildProperties = buildProperties; } @Override @@ -167,7 +150,7 @@ public class DefaultClient implements Client { } if (install) { - install(false, commandLineProperties); + install(false, commandLineProperties, buildProperties.getVersion()); return new DefaultResult(argv, null); } @@ -175,7 +158,7 @@ public class DefaultClient implements Client { // Print version if needed if (version || showVersion || debug) { final String nativeSuffix = Environment.isNative() ? " (native)" : ""; - final String v = Ansi.ansi().bold().a("Maven Daemon " + buildProperties.getProperty("version") + nativeSuffix) + final String v = Ansi.ansi().bold().a("Maven Daemon " + buildProperties.getVersion() + nativeSuffix) .reset().toString(); output.accept(v); /* @@ -184,6 +167,7 @@ public class DefaultClient implements Client { */ } + final ClientLayout layout = lazyLayout.get(); final Path javaHome = layout.javaHome(); try (DaemonRegistry registry = new DaemonRegistry(layout.registry())) { boolean status = args.remove("--status"); @@ -229,7 +213,7 @@ public class DefaultClient implements Client { args.add("-Dmaven.repo.local=" + localMavenRepository.toString()); } - DaemonConnector connector = new DaemonConnector(layout, registry, this::startDaemon, new MessageSerializer()); + final DaemonConnector connector = new DaemonConnector(layout, registry, buildProperties, new MessageSerializer()); List opts = new ArrayList<>(); DaemonClientConnection daemon = connector.connect(new DaemonCompatibilitySpec(javaHome, opts)); @@ -277,69 +261,6 @@ public class DefaultClient implements Client { } } - String startDaemon() { -// DaemonParameters parms = new DaemonParameters(); -// for (String arg : ManagementFactory.getRuntimeMXBean().getInputArguments()) { -// -// } -// List args = new ArrayList<>(); -// args.add(javaHome.resolve(java).toString()); -// args.addAll(parms.getEffectiveJvmArgs()); -// args.add("-cp"); -// args.add(classpath); - - final String uid = UUID.randomUUID().toString(); - final Path mavenHome = layout.mavenHome(); - final Path workingDir = layout.userDir(); - String command = ""; - try { - String classpath = findClientJar(mavenHome).toString(); - final String java = ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java"; - List args = new ArrayList<>(); - args.add("\"" + layout.javaHome().resolve(java) + "\""); - args.add("-classpath"); - args.add("\"" + classpath + "\""); - if (Environment.DAEMON_DEBUG.systemProperty().orDefault(() -> "false").asBoolean()) { - args.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"); - } - args.add("-Dmaven.home=\"" + mavenHome + "\""); - args.add("-Dlogback.configurationFile=logback.xml"); - args.add("-Ddaemon.uid=" + uid); - args.add("-Xmx4g"); - final String timeout = Environment.DAEMON_IDLE_TIMEOUT.systemProperty().asString(); - if (timeout != null) { - args.add(Environment.DAEMON_IDLE_TIMEOUT.asCommandLineProperty(timeout)); - } - args.add("\"-Dmaven.multiModuleProjectDirectory=" + layout.multiModuleProjectDirectory().toString() + "\""); - - args.add(ServerMain.class.getName()); - command = String.join(" ", args); - - LOGGER.debug("Starting daemon process: uid = {}, workingDir = {}, daemonArgs: {}", uid, workingDir, command); - Process.create(workingDir.toFile(), command); - return uid; - } catch (Exception e) { - throw new DaemonException.StartException( - String.format("Error starting daemon: uid = %s, workingDir = %s, daemonArgs: %s", - uid, workingDir, command), - e); - } - } - - Path findClientJar(Path mavenHome) { - final Path ext = mavenHome.resolve("lib/ext"); - final String clientJarName = "mvnd-client-" + buildProperties.getProperty("version") + ".jar"; - try (Stream files = Files.list(ext)) { - return files - .filter(f -> f.getFileName().toString().equals(clientJarName)) - .findFirst() - .orElseThrow(() -> new IllegalStateException("Could not find " + clientJarName + " in " + ext)); - - } catch (IOException e) { - throw new RuntimeException("Could not find " + clientJarName + " in " + ext, e); - } - } - private class DefaultResult implements ExecutionResult { private final Exception exception; diff --git a/client/src/main/java/org/jboss/fuse/mvnd/client/Environment.java b/client/src/main/java/org/jboss/fuse/mvnd/client/Environment.java index 63096db1..641000e0 100644 --- a/client/src/main/java/org/jboss/fuse/mvnd/client/Environment.java +++ b/client/src/main/java/org/jboss/fuse/mvnd/client/Environment.java @@ -94,7 +94,7 @@ public enum Environment { return MVND_PROPERTIES_PATH .environmentVariable() .orSystemProperty() - .orDefault(() -> Paths.get(System.getProperty("user.home")).resolve(".m2/mvnd.properties").toString()) + .orDefault(() -> System.getProperty("user.home") + "/.m2/mvnd.properties") .asPath() .toAbsolutePath().normalize(); } diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/InstallDaemonNativeIT.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/InstallDaemonNativeIT.java index b98f7a10..7a8dd184 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/InstallDaemonNativeIT.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/it/InstallDaemonNativeIT.java @@ -27,6 +27,7 @@ import java.util.Set; import javax.inject.Inject; import org.assertj.core.api.Assertions; +import org.jboss.fuse.mvnd.client.BuildProperties; import org.jboss.fuse.mvnd.client.Client; import org.jboss.fuse.mvnd.client.ClientOutput; import org.jboss.fuse.mvnd.client.DefaultClient; @@ -83,7 +84,7 @@ public class InstallDaemonNativeIT { PosixFilePermission.OTHERS_EXECUTE); } - final String version = DefaultClient.loadBuildProperties().getProperty("version"); + final String version = BuildProperties.getInstance().getVersion(); Assertions.assertThat(mavenHome.resolve("lib/ext/mvnd-client-" + version + ".jar")).exists(); Assertions.assertThat(mavenHome.resolve("lib/ext/mvnd-daemon-" + version + ".jar")).exists(); } diff --git a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/MvndTestExtension.java b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/MvndTestExtension.java index ff1c5981..eafb625d 100644 --- a/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/MvndTestExtension.java +++ b/integration-tests/src/test/java/org/jboss/fuse/mvnd/junit/MvndTestExtension.java @@ -27,6 +27,7 @@ import java.util.Objects; import java.util.stream.Stream; import org.jboss.fuse.mvnd.client.DefaultClient; +import org.jboss.fuse.mvnd.client.BuildProperties; import org.jboss.fuse.mvnd.client.Client; import org.jboss.fuse.mvnd.client.DaemonInfo; import org.jboss.fuse.mvnd.client.DaemonRegistry; @@ -92,7 +93,7 @@ public class MvndTestExtension implements BeforeAllCallback, BeforeEachCallback, } f.set(testInstance, new NativeTestClient(resource.layout, mvndNativeExecutablePath, resource.timeoutMs)); } else { - f.set(testInstance, new DefaultClient(resource.layout)); + f.set(testInstance, new DefaultClient(() -> resource.layout, BuildProperties.getInstance())); } } else if (f.getType() == NativeTestClient.class) { }