Skip to content

Commit c4e1257

Browse files
committed
Use production dependency model for remote-dev
1 parent a0659db commit c4e1257

File tree

5 files changed

+72
-27
lines changed

5 files changed

+72
-27
lines changed

core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,10 @@ private void copyDependency(Set<ArtifactKey> parentFirstArtifacts, OutputTargetB
920920
return;
921921
}
922922
for (Path resolvedDep : appDep.getResolvedPaths()) {
923-
final String fileName = appDep.getGroupId() + "." + resolvedDep.getFileName();
923+
final boolean isDirectory = Files.isDirectory(resolvedDep);
924+
// we don't use getFileName() for directories, since directories would often be "classes" ending up merging content from multiple dependencies in the same package
925+
final String fileName = appDep.getGroupId() + "."
926+
+ (isDirectory ? appDep.getArtifactId() : resolvedDep.getFileName());
924927
final Path targetPath;
925928

926929
if (allowParentFirst && parentFirstArtifacts.contains(appDep.getKey())) {
@@ -932,7 +935,7 @@ private void copyDependency(Set<ArtifactKey> parentFirstArtifacts, OutputTargetB
932935
}
933936
runtimeArtifacts.computeIfAbsent(appDep.getKey(), (s) -> new ArrayList<>(1)).add(targetPath);
934937

935-
if (Files.isDirectory(resolvedDep)) {
938+
if (isDirectory) {
936939
// This case can happen when we are building a jar from inside the Quarkus repository
937940
// and Quarkus Bootstrap's localProjectDiscovery has been set to true. In such a case
938941
// the non-jar dependencies are the Quarkus dependencies picked up on the file system

devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -826,9 +826,9 @@ private String handleAutoCompile(List<String> reloadPoms) throws MojoExecutionEx
826826
* @param reloadPoms POM files to be reloaded from disk instead of taken from the reactor
827827
* @return map of parameters for the Quarkus plugin goals
828828
*/
829-
private static Map<String, String> getQuarkusGoalParams(String bootstrapId, List<String> reloadPoms) {
829+
private Map<String, String> getQuarkusGoalParams(String bootstrapId, List<String> reloadPoms) {
830830
final Map<String, String> result = new HashMap<>(4);
831-
result.put(QuarkusBootstrapMojo.MODE_PARAM, LaunchMode.DEVELOPMENT.name());
831+
result.put(QuarkusBootstrapMojo.MODE_PARAM, getLaunchModeClasspath().name());
832832
result.put(QuarkusBootstrapMojo.CLOSE_BOOTSTRAPPED_APP_PARAM, "false");
833833
result.put(QuarkusBootstrapMojo.BOOTSTRAP_ID_PARAM, bootstrapId);
834834
if (reloadPoms != null && !reloadPoms.isEmpty()) {
@@ -1525,7 +1525,7 @@ private DevModeCommandLine newLauncher(String actualDebugPort, String bootstrapI
15251525
// the Maven resolver will be checking for newer snapshots in the remote repository and might end up resolving the artifact from there.
15261526
final BootstrapMavenContext mvnCtx = workspaceProvider.createMavenContext(mvnConfig);
15271527
appModel = new BootstrapAppModelResolver(new MavenArtifactResolver(mvnCtx))
1528-
.setDevMode(true)
1528+
.setDevMode(getLaunchModeClasspath().isDevOrTest())
15291529
.setTest(LaunchMode.TEST.equals(getLaunchModeClasspath()))
15301530
.setCollectReloadableDependencies(!noDeps)
15311531
.setLegacyModelResolver(BootstrapAppModelResolver.isLegacyModelResolver(project.getProperties()))

devtools/maven/src/main/java/io/quarkus/maven/RemoteDevMojo.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import org.apache.maven.plugins.annotations.Mojo;
55
import org.apache.maven.plugins.annotations.ResolutionScope;
66

7+
import io.quarkus.bootstrap.BootstrapConstants;
78
import io.quarkus.deployment.dev.DevModeCommandLineBuilder;
9+
import io.quarkus.runtime.LaunchMode;
810

911
/**
1012
* The dev mojo, that connects to a remote host.
@@ -15,4 +17,12 @@ public class RemoteDevMojo extends DevMojo {
1517
protected void modifyDevModeContext(DevModeCommandLineBuilder builder) {
1618
builder.remoteDev(true);
1719
}
20+
21+
@Override
22+
protected LaunchMode getLaunchModeClasspath() {
23+
// For remote-dev we should match the dependency model on the service side, which is a production mutable-jar,
24+
// so we return LaunchMode.NORMAL, but we need to enable workspace discovery to be able to watch for source code changes
25+
project.getProperties().putIfAbsent(BootstrapConstants.QUARKUS_BOOTSTRAP_WORKSPACE_DISCOVERY, "true");
26+
return LaunchMode.NORMAL;
27+
}
1828
}

integration-tests/maven/src/test/java/io/quarkus/maven/it/RemoteDevMojoIT.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,28 @@
2525
@DisableForNative
2626
public class RemoteDevMojoIT extends RunAndCheckWithAgentMojoTestBase {
2727

28+
@Test
29+
public void testThatTheApplicationIsReloadedMultiModule() throws IOException {
30+
testDir = initProject("projects/multimodule", "projects/multimodule-remote-dev/remote");
31+
agentDir = initProject("projects/multimodule", "projects/multimodule-remote-dev/local");
32+
runAndCheckModule("runner");
33+
34+
assertThat(devModeClient.getHttpResponse("/app/hello")).isEqualTo("hello");
35+
36+
// Edit the "Hello" message.
37+
File source = new File(agentDir, "rest/src/main/java/org/acme/HelloResource.java");
38+
String uuid = UUID.randomUUID().toString();
39+
filter(source, Collections.singletonMap("return \"hello\";", "return \"" + uuid + "\";"));
40+
41+
await()
42+
.pollDelay(1, TimeUnit.SECONDS)
43+
.atMost(TestUtils.getDefaultTimeout(), TimeUnit.MINUTES)
44+
.until(() -> devModeClient.getHttpResponse("/app/hello").contains(uuid));
45+
}
46+
2847
@Test
2948
public void testThatTheApplicationIsReloadedOnJavaChange()
30-
throws MavenInvocationException, IOException, InterruptedException {
49+
throws MavenInvocationException, IOException {
3150
testDir = initProject("projects/classic-remote-dev", "projects/project-classic-run-java-change-remote");
3251
agentDir = initProject("projects/classic-remote-dev", "projects/project-classic-run-java-change-local");
3352
runAndCheck();

test-framework/maven/src/main/java/io/quarkus/maven/it/RunAndCheckWithAgentMojoTestBase.java

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,13 @@
66
import java.io.File;
77
import java.io.FileNotFoundException;
88
import java.io.IOException;
9-
import java.nio.file.Files;
109
import java.nio.file.Path;
11-
import java.nio.file.Paths;
12-
import java.util.ArrayList;
13-
import java.util.Arrays;
14-
import java.util.Collections;
1510
import java.util.List;
11+
import java.util.Map;
1612
import java.util.concurrent.TimeUnit;
1713

1814
import org.apache.maven.shared.invoker.MavenInvocationException;
1915
import org.junit.jupiter.api.AfterEach;
20-
import org.junit.jupiter.api.Assertions;
2116

2217
import io.quarkus.maven.it.verifier.MavenProcessInvocationResult;
2318
import io.quarkus.maven.it.verifier.RunningInvoker;
@@ -26,6 +21,11 @@
2621

2722
public class RunAndCheckWithAgentMojoTestBase extends MojoTestBase {
2823

24+
private static final String MUTABLE_JAR_TYPE_ARG = "-Dquarkus.package.jar.type=mutable-jar";
25+
private static final String LIVE_RELOAD_PWD_ARG = "-Dquarkus.live-reload.password=qe";
26+
private static final String LIVE_RELOAD_URL_ARG = "-Dquarkus.live-reload.url=http://localhost:8080";
27+
private static final String DQUARKUS_ANALYTICS_DISABLED_TRUE = "-Dquarkus.analytics.disabled=true";
28+
2929
protected RunningInvoker runningAgent;
3030
private Process runningRemote;
3131
protected File agentDir;
@@ -49,22 +49,32 @@ public void cleanup() throws IOException {
4949
}
5050
}
5151

52-
protected void runAndCheck(String... options) throws FileNotFoundException, MavenInvocationException {
52+
protected void runAndCheck() throws FileNotFoundException, MavenInvocationException {
53+
runAndCheckModule(null);
54+
}
55+
56+
protected void runAndCheckModule(String module) {
5357
try {
5458
RunningInvoker running = new RunningInvoker(testDir, false);
5559

5660
MavenProcessInvocationResult result = running
57-
.execute(Arrays.asList("package", "-DskipTests", "-Dquarkus.analytics.disabled=true"),
58-
Collections.emptyMap());
61+
.execute(
62+
List.of("package", "-DskipTests", MUTABLE_JAR_TYPE_ARG, DQUARKUS_ANALYTICS_DISABLED_TRUE),
63+
Map.of());
5964

6065
await().atMost(1, TimeUnit.MINUTES).until(() -> result.getProcess() != null && !result.getProcess().isAlive());
6166
assertThat(running.log()).containsIgnoringCase("BUILD SUCCESS");
6267
running.stop();
6368

64-
Path jar = testDir.toPath().toAbsolutePath()
65-
.resolve(Paths.get("target/quarkus-app/quarkus-run.jar"));
66-
Assertions.assertTrue(Files.exists(jar));
67-
File output = new File(testDir, "target/output.log");
69+
Path runnerTargetDir = testDir.toPath().toAbsolutePath();
70+
if (module != null) {
71+
runnerTargetDir = runnerTargetDir.resolve(module);
72+
}
73+
runnerTargetDir = runnerTargetDir.resolve("target");
74+
75+
Path jar = runnerTargetDir.resolve("quarkus-app/quarkus-run.jar");
76+
assertThat(jar).exists();
77+
File output = runnerTargetDir.resolve("output.log").toFile();
6878
output.createNewFile();
6979

7080
runningRemote = doLaunch(jar, output);
@@ -75,8 +85,10 @@ protected void runAndCheck(String... options) throws FileNotFoundException, Mave
7585
.atMost(1, TimeUnit.MINUTES).until(() -> devModeClient.getHttpResponse("/", 200));
7686

7787
runningAgent = new RunningInvoker(agentDir, false);
78-
runningAgent.execute(Arrays.asList("compile", "quarkus:remote-dev", "-Dquarkus.analytics.disabled=true"),
79-
Collections.emptyMap());
88+
runningAgent.execute(
89+
List.of("compile", "quarkus:remote-dev", MUTABLE_JAR_TYPE_ARG, LIVE_RELOAD_PWD_ARG,
90+
LIVE_RELOAD_URL_ARG, DQUARKUS_ANALYTICS_DISABLED_TRUE),
91+
Map.of());
8092

8193
Thread.sleep(1000);
8294
await().pollDelay(100, TimeUnit.MILLISECONDS)
@@ -86,15 +98,16 @@ protected void runAndCheck(String... options) throws FileNotFoundException, Mave
8698
} catch (Exception e) {
8799
throw new RuntimeException(e);
88100
}
89-
90101
}
91102

92103
private Process doLaunch(Path jar, File output) throws IOException {
93-
List<String> commands = new ArrayList<>();
94-
commands.add(JavaBinFinder.findBin());
95-
commands.add("-jar");
96-
commands.add(jar.toString());
97-
ProcessBuilder processBuilder = new ProcessBuilder(commands.toArray(new String[0]));
104+
final String[] commands = {
105+
JavaBinFinder.findBin(),
106+
LIVE_RELOAD_PWD_ARG,
107+
"-jar",
108+
jar.toString()
109+
};
110+
ProcessBuilder processBuilder = new ProcessBuilder(commands);
98111
processBuilder.redirectOutput(output);
99112
processBuilder.redirectError(output);
100113
processBuilder.environment().put("QUARKUS_LAUNCH_DEVMODE", "true");

0 commit comments

Comments
 (0)