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

Command mode support #7681

Merged
merged 3 commits into from
Apr 6, 2020
Merged
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
6 changes: 0 additions & 6 deletions bom/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -674,12 +674,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 @@ -272,6 +272,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>
Copy link
Member

Choose a reason for hiding this comment

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

Have you checked it works properly? We had a couple of bad surprises with wildcard exclusions.

Copy link
Member Author

Choose a reason for hiding this comment

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

It appears to, none of the bootstrap deps ended up in the final application.

</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,38 @@
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.
*
* This can be passed directly to bytecode recorders that take a {@code Supplier<String[]>}.
*
* No filtering is done on these parameters.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe you could add a comment about this proxy magic? It's not the typical build item.

*/
public final class RawCommandLineArgumentsBuildItem extends SimpleBuildItem
implements BytecodeRecorderImpl.ReturnedProxy, Supplier<String[]> {

/**
* As this object directly implements ReturnedProxy it can be
* passed into bytecode recorders. The runtime value of the command line parameters
* in places directly into the startup context under this key.
*/
@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 @@ -29,6 +29,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 @@ -82,6 +83,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 @@ -154,5 +156,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 @@ -31,6 +31,7 @@
import io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem;
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 +50,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 +59,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) {
log.error("Failed to restart", e);
}
}
});
runner = start.runMainClass();
} catch (Throwable t) {
deploymentProblem = t;
if (context.isAbortOnFailedStart()) {
Expand Down Expand Up @@ -91,7 +117,9 @@ private synchronized void firstStart() {
}

public synchronized void restartApp(Set<String> changedResources) {
restarting = true;
stop();
restarting = false;
Timing.restart(curatedApplication.getAugmentClassLoader());
deploymentProblem = null;
ClassLoader old = Thread.currentThread().getContextClassLoader();
Expand All @@ -100,11 +128,10 @@ 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();
} catch (Throwable t) {
deploymentProblem = t;
log.error("Failed to start quarkus", t);

}
} finally {
Thread.currentThread().setContextClassLoader(old);
Expand Down Expand Up @@ -169,6 +196,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");
Copy link
Member

Choose a reason for hiding this comment

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

good enough to start, but I reckon just doing a recursive search for nearest pom.xml/build.gradle and resolve source paths from there (still just via filesystem not parsing the build files) could make this a bit less hacky.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also this would fail on windows because of the delimiters, or?

Copy link
Member Author

Choose a reason for hiding this comment

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

Forward slash is also a delimiter on windows.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's good to know, I always thought it's only \ on windows... ;-)

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 weird, 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 @@ -33,10 +33,15 @@ public class PackageConfig {
public ManifestConfig manifest;

/**
* The entry point of the application. In most cases this should not be modified.
* The entry point of the application. This can either be a a fully qualified name of a standard Java
* class with a main method, or {@link io.quarkus.runtime.QuarkusApplication}.
*
* If your application has main classes annotated with {@link io.quarkus.runtime.annotations.QuarkusMain}
* then this can also reference the name given in the annotation, to avoid the need to specify fully qualified
* names in the config.
*/
@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