Skip to content

Commit 2eb4839

Browse files
authored
Merge pull request #31645 from FroMage/31013
RuntimeUpdatesProcessor now supports hot replacement problems
2 parents 110fc5f + 25bc923 commit 2eb4839

File tree

7 files changed

+142
-5
lines changed

7 files changed

+142
-5
lines changed

core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public class RuntimeUpdatesProcessor implements HotReplacementContext, Closeable
8888
private final DevModeType devModeType;
8989
volatile Throwable compileProblem;
9090
volatile Throwable testCompileProblem;
91+
volatile Throwable hotReloadProblem;
9192

9293
private volatile Predicate<ClassInfo> disableInstrumentationForClassPredicate = new AlwaysFalsePredicate<>();
9394
private volatile Predicate<Index> disableInstrumentationForIndexPredicate = new AlwaysFalsePredicate<>();
@@ -388,7 +389,8 @@ public List<Path> getResourcesDir() {
388389
public Throwable getDeploymentProblem() {
389390
//we differentiate between these internally, however for the error reporting they are the same
390391
return compileProblem != null ? compileProblem
391-
: IsolatedDevModeMain.deploymentProblem;
392+
: IsolatedDevModeMain.deploymentProblem != null ? IsolatedDevModeMain.deploymentProblem
393+
: hotReloadProblem;
392394
}
393395

394396
@Override
@@ -551,13 +553,17 @@ public boolean doScan(boolean userInitiated, boolean forceRestart) {
551553

552554
return true;
553555
} else if (!filesChanged.isEmpty()) {
554-
for (Consumer<Set<String>> consumer : noRestartChangesConsumers) {
555-
try {
556+
try {
557+
for (Consumer<Set<String>> consumer : noRestartChangesConsumers) {
556558
consumer.accept(filesChanged);
557-
} catch (Throwable t) {
558-
log.error("Changed files consumer failed", t);
559559
}
560+
hotReloadProblem = null;
561+
getCompileOutput().setMessage(null);
562+
} catch (Throwable t) {
563+
hotReloadProblem = t;
564+
getCompileOutput().setMessage(t.getMessage());
560565
}
566+
561567
log.infof("Files changed but restart not needed - notified extensions in: %ss ",
562568
Timing.convertToBigDecimalSeconds(System.nanoTime() - startNanoseconds));
563569
} else if (instrumentationChange) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.quarkus.extest.deployment;
2+
3+
import io.quarkus.deployment.annotations.BuildStep;
4+
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
5+
import io.quarkus.extest.runtime.TestHotReplacementSetup;
6+
7+
public class HotReplacementProcessor {
8+
@BuildStep
9+
public HotDeploymentWatchedFileBuildItem registerHotReplacementFile() {
10+
return new HotDeploymentWatchedFileBuildItem(TestHotReplacementSetup.HOT_REPLACEMENT_FILE, false);
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.quarkus.extest.runtime;
2+
3+
public class HotReplacementException extends Exception {
4+
5+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.quarkus.extest.runtime;
2+
3+
import java.io.IOException;
4+
import java.io.UncheckedIOException;
5+
import java.nio.file.Files;
6+
import java.nio.file.Path;
7+
import java.util.Set;
8+
9+
import io.quarkus.dev.ErrorPageGenerators;
10+
import io.quarkus.dev.spi.HotReplacementContext;
11+
import io.quarkus.dev.spi.HotReplacementSetup;
12+
13+
public class TestHotReplacementSetup implements HotReplacementSetup {
14+
15+
public final static String HOT_REPLACEMENT_FILE = "hot.replacement";
16+
17+
private static final String HOT_REPLACEMENT_EXCEPTION = HotReplacementException.class.getName();
18+
19+
private HotReplacementContext context;
20+
21+
@Override
22+
public void setupHotDeployment(HotReplacementContext context) {
23+
context.consumeNoRestartChanges(this::noRestartChanges);
24+
this.context = context;
25+
ErrorPageGenerators.register(HOT_REPLACEMENT_EXCEPTION, this::generatePage);
26+
}
27+
28+
public void noRestartChanges(Set<String> changedFiles) {
29+
if (changedFiles.contains(HOT_REPLACEMENT_FILE)) {
30+
for (Path resourcePath : context.getResourcesDir()) {
31+
Path myFile = resourcePath.resolve(HOT_REPLACEMENT_FILE);
32+
if (Files.exists(myFile)) {
33+
try {
34+
String contents = Files.readString(myFile);
35+
if ("throw".equals(contents))
36+
throw new RuntimeException(new HotReplacementException());
37+
return;
38+
} catch (IOException e) {
39+
throw new UncheckedIOException(e);
40+
}
41+
}
42+
}
43+
}
44+
}
45+
46+
private String generatePage(Throwable x) {
47+
return "Generated page for exception " + x;
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.quarkus.extest.runtime.TestHotReplacementSetup

integration-tests/test-extension/tests/pom.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
<artifactId>quarkus-junit5</artifactId>
3030
<scope>test</scope>
3131
</dependency>
32+
<dependency>
33+
<groupId>io.quarkus</groupId>
34+
<artifactId>quarkus-junit5-internal</artifactId>
35+
<scope>test</scope>
36+
</dependency>
3237
<dependency>
3338
<groupId>io.rest-assured</groupId>
3439
<artifactId>rest-assured</artifactId>
@@ -96,6 +101,30 @@
96101
</plugin>
97102
<plugin>
98103
<artifactId>maven-surefire-plugin</artifactId>
104+
<executions>
105+
<execution>
106+
<id>default-test</id>
107+
<goals>
108+
<goal>test</goal>
109+
</goals>
110+
<configuration>
111+
<excludes>
112+
<exclude>io/quarkus/it/extension/HotReplacementSetupDevModeTest.java</exclude>
113+
</excludes>
114+
</configuration>
115+
</execution>
116+
<execution>
117+
<id>quarkus-test</id>
118+
<goals>
119+
<goal>test</goal>
120+
</goals>
121+
<configuration>
122+
<includes>
123+
<include>io/quarkus/it/extension/HotReplacementSetupDevModeTest.java</include>
124+
</includes>
125+
</configuration>
126+
</execution>
127+
</executions>
99128
<configuration>
100129
<systemPropertyVariables>
101130
<!-- See io.quarkus.extest.runtime.classpath.RecordedClasspathEntries -->
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.quarkus.it.extension;
2+
3+
import org.hamcrest.Matchers;
4+
import org.jboss.shrinkwrap.api.asset.StringAsset;
5+
import org.junit.jupiter.api.Test;
6+
import org.junit.jupiter.api.extension.RegisterExtension;
7+
8+
import io.quarkus.extest.runtime.TestHotReplacementSetup;
9+
import io.quarkus.test.QuarkusDevModeTest;
10+
import io.restassured.RestAssured;
11+
12+
public class HotReplacementSetupDevModeTest {
13+
14+
@RegisterExtension
15+
static final QuarkusDevModeTest TEST = new QuarkusDevModeTest()
16+
.withApplicationRoot((jar) -> jar
17+
.addClasses(SystemPropertyTestEndpoint.class)
18+
.addAsResource(new StringAsset("nothing"), TestHotReplacementSetup.HOT_REPLACEMENT_FILE));
19+
20+
@Test
21+
public void watched() {
22+
RestAssured.get("/core/sysprop")
23+
.then()
24+
.statusCode(200);
25+
TEST.modifyResourceFile(TestHotReplacementSetup.HOT_REPLACEMENT_FILE, text -> "throw");
26+
RestAssured.get("/core/sysprop")
27+
.then()
28+
.statusCode(500)
29+
.body(Matchers.containsString("Generated page for exception"));
30+
TEST.modifyResourceFile(TestHotReplacementSetup.HOT_REPLACEMENT_FILE, text -> "nothing");
31+
RestAssured.get("/core/sysprop")
32+
.then()
33+
.statusCode(200);
34+
}
35+
}

0 commit comments

Comments
 (0)