Improve environment defaults

This commit is contained in:
Peter Palaga
2020-06-21 20:04:29 +02:00
parent 87c71ceadd
commit 3107f08b87
6 changed files with 125 additions and 99 deletions

View File

@@ -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;
}
}

View File

@@ -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<Message> serializer;
private final BuildProperties buildProperties;
public DaemonConnector(Layout layout, DaemonRegistry registry, DaemonStarter daemonStarter, Serializer<Message> serializer) {
public DaemonConnector(ClientLayout layout, DaemonRegistry registry, BuildProperties buildProperties, Serializer<Message> 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<String> 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);

View File

@@ -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<ClientLayout> lazyLayout;
private final BuildProperties buildProperties;
public static void main(String[] argv) throws Exception {
final List<String> 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<ClientLayout> 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<String> 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<String> 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<String> 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<Path> 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;

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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) {
}