Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code improvements. #881

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
Expand Down Expand Up @@ -150,7 +151,7 @@ public void store(Writer writer, String comments) throws IOException {

@Override
public void store(OutputStream out, String comments) throws IOException {
this.store(new OutputStreamWriter(out, "8859_1"), comments);
this.store(new OutputStreamWriter(out, StandardCharsets.ISO_8859_1), comments);
}

static class SkipFirstLineBufferedWriter extends BufferedWriter {
Expand Down
114 changes: 63 additions & 51 deletions client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
Expand All @@ -34,13 +33,18 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.mvndaemon.mvnd.common.DaemonCompatibilitySpec;
import org.mvndaemon.mvnd.common.DaemonCompatibilitySpec.Result;
Expand Down Expand Up @@ -69,6 +73,11 @@
public class DaemonConnector {

private static final Logger LOGGER = LoggerFactory.getLogger(DaemonConnector.class);
private static final Function<DaemonInfo, Boolean> daemonIsIdle = di -> di.getState() == DaemonState.Idle;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not using method if we don't want to inline those methods ?

private static final Predicate<DaemonInfo> daemonIsCanceled = di -> di.getState() == Canceled;
private static final Predicate<Path> isJarFile =
s -> s.getFileName().toString().endsWith(".jar");
private static final Predicate<String> nonEmpty = s -> !s.isEmpty();

private final DaemonRegistry registry;
private final DaemonParameters parameters;
Expand Down Expand Up @@ -100,7 +109,7 @@ public DaemonClientConnection connect(ClientOutput output) {
new DaemonCompatibilitySpec(parameters.javaHome(), parameters.getDaemonOpts());
output.accept(Message.buildStatus("Looking up daemon..."));
Map<Boolean, List<DaemonInfo>> idleBusy =
registry.getAll().stream().collect(Collectors.groupingBy(di -> di.getState() == DaemonState.Idle));
registry.getAll().stream().collect(Collectors.groupingBy(daemonIsIdle));
final Collection<DaemonInfo> idleDaemons = idleBusy.getOrDefault(true, Collections.emptyList());
final Collection<DaemonInfo> busyDaemons = idleBusy.getOrDefault(false, Collections.emptyList());

Expand Down Expand Up @@ -194,6 +203,7 @@ private String handleStopEvents(
.collect(Collectors.groupingBy(DaemonStopEvent::getDaemonId, Collectors.minBy(this::compare)))
.values()
.stream()
.filter(Optional::isPresent)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know IntelliJ prints a warning 'Optional::get' without 'isPresent()' check, but I think this is not a possible case : the groupingBy would not create a key if there's no value, so minBy will always return a non empty Optional.

.map(Optional::get)
.collect(Collectors.toList());
for (DaemonStopEvent stopEvent : recentStopEvents) {
Expand Down Expand Up @@ -251,7 +261,7 @@ private DaemonClientConnection connectToCanceledDaemon(
Collection<DaemonInfo> busyDaemons, DaemonCompatibilitySpec constraint) {
DaemonClientConnection connection = null;
List<DaemonInfo> canceledBusy =
busyDaemons.stream().filter(di -> di.getState() == Canceled).collect(Collectors.toList());
busyDaemons.stream().filter(daemonIsCanceled).collect(Collectors.toList());
final List<DaemonInfo> compatibleCanceledDaemons = getCompatibleDaemons(canceledBusy, constraint);
LOGGER.debug(
"Found {} busy daemons, {} cancelled, {} compatibles",
Expand Down Expand Up @@ -334,46 +344,57 @@ static String newId() {
return String.format("%08x", new Random().nextInt());
}

private String findLocation(
Path startPath, Predicate<Path> searchedJarFile, Supplier<IllegalStateException> exception)
throws IOException, IllegalStateException {
try (Stream<Path> jarPaths = Files.list(startPath)) {
return jarPaths.filter(isJarFile)
.filter(searchedJarFile)
.findFirst()
.map(Path::toString)
.orElseThrow(exception);
}
}

private String findPlexusClassworldsJarLocation(Path mavenDaemonHomeBoot)
throws IOException, IllegalStateException {
return findLocation(
mavenDaemonHomeBoot,
s -> s.getFileName().toString().startsWith("plexus-classworlds-"),
() -> new IllegalStateException("Could not find plexus-classworlds jar in boot/"));
}

private String findMavenDaemonAgentLocation(Path mavenDaemonAgent) throws IOException, IllegalStateException {
return findLocation(
mavenDaemonAgent,
s -> s.getFileName().toString().startsWith("mvnd-agent-"),
() -> new IllegalStateException("Could not find mvnd-agent jar in mvn/lib/mvnd/"));
}

private int findPort() {
try (ServerSocketChannel channel = SocketFamily.inet.openServerSocket()) {
return ((InetSocketAddress) channel.getLocalAddress()).getPort();
} catch (IOException e) {
throw new IllegalStateException("Unable to find a free debug port", e);
}
}

private Process startDaemonProcess(String daemonId, ClientOutput output) {
final Path mvndHome = parameters.mvndHome();
final Path workingDir = parameters.userDir();
String command = "";
try {
List<String> args = new ArrayList<>();
// executable
final String java = Os.current().isUnixLike() ? "bin/java" : "bin\\java.exe";

List<String> args = new ArrayList<>();
args.add(parameters.javaHome().resolve(java).toString());
// classpath
String mvndAgentPath = null;
String plexusClassworldsPath = null;
try (DirectoryStream<Path> jarPaths = Files.newDirectoryStream(
mvndHome.resolve("mvn").resolve("lib").resolve("mvnd"))) {
for (Path jar : jarPaths) {
String s = jar.getFileName().toString();
if (s.endsWith(".jar")) {
if (s.startsWith("mvnd-agent-")) {
mvndAgentPath = jar.toString();
}
}
}
}
try (DirectoryStream<Path> jarPaths =
Files.newDirectoryStream(mvndHome.resolve("mvn").resolve("boot"))) {
for (Path jar : jarPaths) {
String s = jar.getFileName().toString();
if (s.endsWith(".jar")) {
if (s.startsWith("plexus-classworlds-")) {
plexusClassworldsPath = jar.toString();
}
}
}
}
if (mvndAgentPath == null) {
throw new IllegalStateException("Could not find mvnd-agent jar in mvn/lib/mvnd/");
}
if (plexusClassworldsPath == null) {
throw new IllegalStateException("Could not find plexus-classworlds jar in boot/");
}

String plexusClassworldsPath =
findPlexusClassworldsJarLocation(mvndHome.resolve("mvn").resolve("boot"));
String mvndAgentPath = findMavenDaemonAgentLocation(
mvndHome.resolve("mvn").resolve("lib").resolve("mvnd"));

args.add("-classpath");
args.add(plexusClassworldsPath);
args.add("-javaagent:" + mvndAgentPath);
Expand All @@ -391,30 +412,21 @@ private Process startDaemonProcess(String daemonId, ClientOutput output) {
host = "localhost";
port = address;
}
if (!port.matches("[0-9]+")) {
if (!port.matches("\\d+")) {
throw new IllegalArgumentException("Wrong debug address syntax: " + address);
}
int iPort = Integer.parseInt(port);
if (iPort == 0) {
try (ServerSocketChannel channel = SocketFamily.inet.openServerSocket()) {
iPort = ((InetSocketAddress) channel.getLocalAddress()).getPort();
} catch (IOException e) {
throw new IllegalStateException("Unable to find a free debug port", e);
}
iPort = findPort();
}

address = host + ":" + iPort;
output.accept(Message.buildStatus("Daemon listening for debugger on address: " + address));
args.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + address);
}
// jvm args
String jvmArgs = parameters.jvmArgs();
if (jvmArgs != null) {
for (String arg : jvmArgs.split(" ")) {
if (!arg.isEmpty()) {
args.add(arg);
}
}
}
String jvmArgs = Objects.toString(parameters.jvmArgs(), "");
args.addAll(Stream.of(jvmArgs.split(" ")).filter(nonEmpty).collect(Collectors.toList()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stream.of(jvmArgs.split(" ")).filter(nonEmpty).forEach(args::add) ? to avoid the toList step

// memory
String minHeapSize = parameters.minHeapSize();
if (minHeapSize != null) {
Expand Down Expand Up @@ -468,13 +480,13 @@ private Process startDaemonProcess(String daemonId, ClientOutput output) {
processBuilder
.environment()
.put(Environment.JDK_JAVA_OPTIONS.getEnvironmentVariable(), parameters.jdkJavaOpts());
Process process = processBuilder

return processBuilder
.directory(workingDir.toFile())
.command(args)
.redirectOutput(redirect)
.redirectError(redirect)
.start();
return process;
} catch (Exception e) {
throw new DaemonException.StartException(
String.format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ void verify() throws IOException, InterruptedException {
}

private void assertDaemonRegistrySize(int size) {
Assertions.assertThat(registry.getAll().size())
.as("Daemon registry size should be " + size)
.isEqualTo(size);
Assertions.assertThat(registry.getAll())
.as("Daemon registry size should be %d actually containing:(%s)", size, registry.getAll())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what "actually containing" means here. It's a tad awkward phrasing. Is this a UI message somewhere or just a test failure message?

.hasSize(size);
}
}
Loading