Skip to content

Commit

Permalink
Command mode support
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Mar 13, 2020
1 parent e90c41f commit fb75cc5
Show file tree
Hide file tree
Showing 71 changed files with 1,629 additions and 293 deletions.
6 changes: 0 additions & 6 deletions bom/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -617,12 +617,6 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-development-mode</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scala-deployment</artifactId>
Expand Down
12 changes: 12 additions & 0 deletions bom/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,18 @@
<artifactId>quarkus-development-mode-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-ide-launcher</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<!-- This has shaded dependencies -->
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.LiveReloadBuildItem;
import io.quarkus.deployment.builditem.RawCommandLineArgumentsBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
import io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
Expand Down Expand Up @@ -107,6 +108,7 @@ public BuildResult run() throws Exception {
.addInitial(DeploymentClassLoaderBuildItem.class)
.addInitial(ArchiveRootBuildItem.class)
.addInitial(ShutdownContextBuildItem.class)
.addInitial(RawCommandLineArgumentsBuildItem.class)
.addInitial(LaunchModeBuildItem.class)
.addInitial(LiveReloadBuildItem.class)
.addInitial(AdditionalApplicationArchiveBuildItem.class)
Expand All @@ -132,6 +134,7 @@ public BuildResult run() throws Exception {
.produce(liveReloadBuildItem)
.produce(new ArchiveRootBuildItem(root, rootFs == null ? root : rootFs.getPath("/"), excludedFromIndexing))
.produce(new ShutdownContextBuildItem())
.produce(new RawCommandLineArgumentsBuildItem())
.produce(new LaunchModeBuildItem(launchMode))
.produce(new BuildSystemTargetBuildItem(targetDir, baseName))
.produce(new DeploymentClassLoaderBuildItem(deploymentClassLoader))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.quarkus.deployment.builditem;

import java.util.function.Supplier;

import io.quarkus.builder.item.SimpleBuildItem;
import io.quarkus.deployment.recording.BytecodeRecorderImpl;
import io.quarkus.runtime.StartupContext;

/**
* A build item that represents the raw command line arguments as they were passed to the application.
*
* No filtering is done on these parameters.
*/
public final class RawCommandLineArgumentsBuildItem extends SimpleBuildItem
implements BytecodeRecorderImpl.ReturnedProxy, Supplier<String[]> {

@Override
public String __returned$proxy$key() {
return StartupContext.RAW_COMMAND_LINE_ARGS;
}

@Override
public boolean __static$$init() {
return true;
}

@Override
public String[] get() {
throw new IllegalStateException("Can only be called at runtime");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.dev;
package io.quarkus.deployment.dev;

import java.io.File;
import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.dev;
package io.quarkus.deployment.dev;

import java.io.File;
import java.nio.charset.Charset;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.dev;
package io.quarkus.deployment.dev;

import java.util.ArrayList;
import java.util.Collection;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.dev;
package io.quarkus.deployment.dev;

import java.io.File;
import java.io.Serializable;
Expand Down Expand Up @@ -27,6 +27,7 @@ public class DevModeContext implements Serializable {
private String sourceEncoding;

private final List<File> classesRoots = new ArrayList<>();
private final List<URL> additionalClassPathElements = new ArrayList<>();
private File frameworkClassesDir;
private File cacheDir;
private File projectDir;
Expand Down Expand Up @@ -80,6 +81,10 @@ public List<File> getClassesRoots() {
return classesRoots;
}

public List<URL> getAdditionalClassPathElements() {
return additionalClassPathElements;
}

public File getFrameworkClassesDir() {
return frameworkClassesDir;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package io.quarkus.dev;

package io.quarkus.deployment.dev;

import java.io.Closeable;
import java.io.DataInputStream;
Expand All @@ -21,6 +22,7 @@
import io.quarkus.bootstrap.app.AdditionalDependency;
import io.quarkus.bootstrap.app.CuratedApplication;
import io.quarkus.bootstrap.app.QuarkusBootstrap;
import io.quarkus.dev.appstate.ApplicationStateNotification;

/**
* The main entry point for the dev mojo execution
Expand Down Expand Up @@ -149,5 +151,6 @@ public void close() throws IOException {
if (realCloseable != null) {
realCloseable.close();
}
ApplicationStateNotification.waitForApplicationStop();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.dev;
package io.quarkus.deployment.dev;

import java.util.List;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.dev;
package io.quarkus.deployment.dev;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -29,8 +29,10 @@
import io.quarkus.builder.BuildContext;
import io.quarkus.builder.BuildStep;
import io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem;
import io.quarkus.dev.appstate.ApplicationStateNotification;
import io.quarkus.dev.spi.HotReplacementSetup;
import io.quarkus.runner.bootstrap.AugmentActionImpl;
import io.quarkus.runtime.ApplicationLifecycleManager;
import io.quarkus.runtime.Timing;
import io.quarkus.runtime.configuration.QuarkusConfigFactory;
import io.quarkus.runtime.logging.InitialConfigurator;
Expand All @@ -49,6 +51,7 @@ public class IsolatedDevModeMain implements BiConsumer<CuratedApplication, Map<S
static volatile RuntimeUpdatesProcessor runtimeUpdatesProcessor;
private static volatile CuratedApplication curatedApplication;
private static volatile AugmentAction augmentAction;
private static volatile boolean restarting;

private synchronized void firstStart() {
ClassLoader old = Thread.currentThread().getContextClassLoader();
Expand All @@ -57,7 +60,31 @@ private synchronized void firstStart() {
//ok, we have resolved all the deps
try {
StartupAction start = augmentAction.createInitialRuntimeApplication();
runner = start.run();
//this is a bit yuck, but we need replace the default
//exit handler in the runtime class loader
//TODO: look at implementing a common core classloader, that removes the need for this sort of crappy hack
curatedApplication.getBaseRuntimeClassLoader().loadClass(ApplicationLifecycleManager.class.getName())
.getMethod("setDefaultExitCodeHandler", Consumer.class)
.invoke(null, new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
if (restarting || ApplicationLifecycleManager.isVmShuttingDown()
|| context.isAbortOnFailedStart()) {
return;
}
System.out.println("Quarkus application exited with code " + integer);
System.out.println("Press Enter to restart");
try {
while (System.in.read() != '\n') {
}
runtimeUpdatesProcessor.checkForChangedClasses();
restartApp(runtimeUpdatesProcessor.checkForFileChange());
} catch (Exception e) {
e.printStackTrace();
}
}
});
runner = start.runMainClass();
} catch (Throwable t) {
deploymentProblem = t;
if (context.isAbortOnFailedStart()) {
Expand Down Expand Up @@ -91,7 +118,12 @@ private synchronized void firstStart() {
}

public synchronized void restartApp(Set<String> changedResources) {
restarting = true;
stop();

//this clears any old state
ApplicationStateNotification.notifyApplicationStopped();
restarting = false;
Timing.restart(curatedApplication.getAugmentClassLoader());
deploymentProblem = null;
ClassLoader old = Thread.currentThread().getContextClassLoader();
Expand All @@ -100,11 +132,11 @@ public synchronized void restartApp(Set<String> changedResources) {
//ok, we have resolved all the deps
try {
StartupAction start = augmentAction.reloadExistingApplication(changedResources);
runner = start.run();
runner = start.runMainClass();
ApplicationStateNotification.waitForApplicationStart();
} catch (Throwable t) {
deploymentProblem = t;
log.error("Failed to start quarkus", t);

}
} finally {
Thread.currentThread().setContextClassLoader(old);
Expand Down Expand Up @@ -169,6 +201,8 @@ public void stop() {
}

public void close() {
//don't attempt to restart in the exit code handler
restarting = true;
try {
stop();
} finally {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.dev;
package io.quarkus.deployment.dev;

import java.io.File;
import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.quarkus.deployment.dev;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;

import org.eclipse.microprofile.config.spi.ConfigProviderResolver;

import io.smallrye.config.SmallRyeConfigProviderResolver;

/**
* The entry point when launched from an IDE
*/
public class LauncherMain {

public static void main(Path appClasses, Path wiring, URL[] classPath, String... args) throws Exception {
DevModeContext context = new DevModeContext();
context.setAbortOnFailedStart(true);
context.setTest(false);
context.setCacheDir(Files.createTempDirectory("quarkus-cache").toFile());
context.setSourceEncoding("UTF-8");
File appClassesFile = appClasses.toFile();
context.getClassesRoots().add(appClassesFile);

//TODO: huge hacks
File src = new File(appClassesFile, "../../src/main/java");
File res = new File(appClassesFile, "../../src/main/resources");

context.getModules().add(new DevModeContext.ModuleInfo("main", new File("").getAbsolutePath(),
Collections.singleton(src.getAbsolutePath()), appClassesFile.getAbsolutePath(), res.getAbsolutePath()));
//the loading of this is super wierd, and does its own class loader delegation for some reason
ConfigProviderResolver.setInstance(new SmallRyeConfigProviderResolver());
DevModeMain main = new DevModeMain(context);
main.start();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.dev;
package io.quarkus.deployment.dev;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public class PackageConfig {
/**
* The entry point of the application. In most cases this should not be modified.
*/
@ConfigItem(defaultValue = "io.quarkus.runner.GeneratedMain")
public String mainClass;
@ConfigItem
public Optional<String> mainClass;

/**
* Files that should not be copied to the output artifact
Expand Down
Loading

0 comments on commit fb75cc5

Please sign in to comment.