Skip to content

Commit

Permalink
#11 Remove direct support for QuickStart and document it in README.md…
Browse files Browse the repository at this point in the history
… instead. Fixes #11
  • Loading branch information
mvysny committed Mar 15, 2023
1 parent 3bc4a23 commit f7d0f0f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 119 deletions.
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,62 @@ Many more example projects:
If you like [Kotlin](https://kotlinlang.org/) and you like the simplicity of the ideas above,
please use the [Vaadin-on-Kotlin](https://www.vaadinonkotlin.eu/) framework which is based on the ideas above.

## Advanced Use-Cases

### Jetty QuickStart

Jetty can optionally start faster if we don't classpath-scan for resources, and instead pass in a QuickStart XML file with all resources listed.
This is mandatory for native mode, since classpath scanning doesn't work in native mode.

See [Jetty QuickStart Documentation](https://www.eclipse.org/jetty/documentation/jetty-12/operations-guide/index.html#og-quickstart)
for more details; see [Jetty Maven plugin](https://www.eclipse.org/jetty/documentation/jetty-12/programming-guide/index.html#jetty-effective-web-xml-goal)
documentation as well on how to generate the QuickStart configuration file.
Also see [Issue #11](https://github.com/mvysny/vaadin-boot/issues/11).

To enable QuickStart mode, add a dependency on Jetty QuickStart: `org.eclipse.jetty:jetty-quickstart:11.0.14`.

The quickstart configuration lists e.g. a list of Vaadin Routes, and therefore
it's good to generate it during compile time. Unfortunately, at the moment, Maven Jetty plugin can't
do that, see&vote for [Jetty #9497](https://github.com/eclipse/jetty.project/issues/9497).

Workaround is to generate the config file manually. You need to start your app in order for Jetty to
perform the classpath scanning. Don't forget to run the app in production mode, otherwise
the quickstart config file will contain Vaadin dev mode stuff like `DevModeStartupListener`.

```java
public class Main {
public static void main(String[] args) throws Exception {
new VaadinBoot() {
protected void onStarted(@NotNull WebAppContext context) {
context.setAttribute(ExtraXmlDescriptorProcessor.class.getName(), new ExtraXmlDescriptorProcessor());
final String xml = new File("quickstart-web.xml").getAbsolutePath();
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(xml))) {
new QuickStartGeneratorConfiguration().generateQuickStartWebXml(context, out);
}
}
}.withArgs(args).run();
}
}
```

Place the file here: `src/main/resources/webapp/WEB-INF/quickstart-web.xml`. From now on,
Jetty should read the QuickStart config and skip the classpath scanning automatically; however
you can still enforce the QuickStart mode:

```java
public class Main {
public static void main(String[] args) throws Exception {
new VaadinBoot() {
protected WebAppContext createWebAppContext() throws MalformedURLException {
WebAppContext ctx = super.createWebAppContext();
context.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART);
return ctx;
}
}.withArgs(args).disableClasspathScanning().run();
}
}
```

## Native

Building a native app with GraalVM is unsupported at the moment. Please see [Issue #10](https://github.com/mvysny/vaadin-boot/issues/10)
Expand Down
1 change: 0 additions & 1 deletion vaadin-boot/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ dependencies {

// Embedded Jetty dependencies
api("org.eclipse.jetty:jetty-webapp:${properties["jetty_version"]}")
api("org.eclipse.jetty:jetty-quickstart:${properties["jetty_version"]}")
api("org.eclipse.jetty.websocket:websocket-jakarta-server:${properties["jetty_version"]}")

// opens url in a browser; Vaadin dependency
Expand Down

This file was deleted.

107 changes: 30 additions & 77 deletions vaadin-boot/src/main/java/com/github/mvysny/vaadinboot/VaadinBoot.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.vaadin.open.Open;
import jakarta.servlet.Servlet;
import org.eclipse.jetty.quickstart.QuickStartConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
Expand Down Expand Up @@ -65,6 +64,14 @@ public class VaadinBoot {
*/
private boolean openBrowserInDevMode = true;

/**
* If true, no classpath scanning is performed - no servlets nor weblisteners are detected.
* <p></p>
* This will most probably cause Vaadin to not work and throw NullPointerException at <code>VaadinServlet.serveStaticOrWebJarRequest</code>.
* However, it's a good thing to disable this when starting your app with a QuickStart configuration.
*/
private boolean disableClasspathScanning = false;

/**
* Creates the new instance of the Boot launcher.
*/
Expand Down Expand Up @@ -167,6 +174,18 @@ public String getServerURL() {
return "http://" + (hostName != null ? hostName : "localhost") + ":" + port + contextRoot;
}

/**
* If true, no classpath scanning is performed - no servlets nor weblisteners are detected.
* <p></p>
* This will most probably cause Vaadin to not work and throw NullPointerException at <code>VaadinServlet.serveStaticOrWebJarRequest</code>.
* However, it's a good thing to disable this when starting your app with a QuickStart configuration.
*/
@NotNull
public VaadinBoot disableClasspathScanning() {
disableClasspathScanning = true;
return this;
}

// mark volatile: might be accessed by the shutdown hook from a different thread.
private volatile Server server;

Expand Down Expand Up @@ -235,9 +254,7 @@ public void start() throws Exception {
server.start();
log.debug("Jetty Server started");

if (createQuickStartXml) {
JettyQuickStart.generateQuickStartXml(context);
}
onStarted(context);

final Duration startupDuration = Duration.ofMillis(System.currentTimeMillis() - startupMeasurementSince);
System.out.println("\n\n=================================================\n" +
Expand All @@ -249,6 +266,14 @@ public void start() throws Exception {
System.out.println("=================================================\n");
}

/**
* Invoked when the Jetty server has been started. By default, does nothing. You can
* for example dump the quickstart configuration here.
* @param context the web app context.
*/
protected void onStarted(@NotNull WebAppContext context) {
}

/**
* Creates the Jetty {@link WebAppContext}.
* @return the {@link WebAppContext}
Expand All @@ -260,10 +285,7 @@ protected WebAppContext createWebAppContext() throws MalformedURLException {
context.setBaseResource(webRoot);
context.setContextPath(contextRoot);
context.addServlet(servlet, "/*");
if (JettyQuickStart.quickstartXmlExists(webRoot)) {
context.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART);
context.addConfiguration(new QuickStartConfiguration());
} else {
if (!disableClasspathScanning) {
// this will properly scan the classpath for all @WebListeners, including the most important
// com.vaadin.flow.server.startup.ServletContextListeners.
// See also https://mvysny.github.io/vaadin-lookup-vs-instantiator/
Expand Down Expand Up @@ -300,73 +322,4 @@ public void stop(@NotNull String reason) {

@NotNull
private static final Logger log = LoggerFactory.getLogger(VaadinBoot.class);

@NotNull
private QuickStartMode quickStartMode = QuickStartMode.Off;

/**
* Jetty can optionally start faster if we don't classpath-scan for resources,
* and instead pass in a QuickStart XML file with all resources listed.
* <p></p>
* This is mandatory for native mode.
* <p></p>
* See
* <a href="https://www.eclipse.org/jetty/documentation/jetty-12/operations-guide/index.html#og-quickstart">Jetty QuickStart documentation</a>
* for more details; see
* <a href="https://www.eclipse.org/jetty/documentation/jetty-12/programming-guide/index.html#jetty-effective-web-xml-goal">Jetty Maven plugin</a>
* documentation as well. Also see <a href="https://github.com/mvysny/vaadin-boot/issues/11">Issue #11</a>.
* @param quickStartMode the new quick start mode, defaults to {@link QuickStartMode#Off}.
* @return this
*/
@NotNull
public VaadinBoot withQuickStartMode(@NotNull QuickStartMode quickStartMode) {
this.quickStartMode = quickStartMode;
return this;
}

private boolean createQuickStartXml = false;

/**
* Defaults to false. If true, a <code>quickstart-web.xml</code> file for your app is created in the
* current working directory when Jetty starts.
* <p></p>
* Workaround until we are able to generate the XML file during the compile time, via a Maven/Gradle plugin.
* @return this
*/
@NotNull
public VaadinBoot generateQuickStartXml() {
createQuickStartXml = true;
return this;
}

public enum QuickStartMode {
/**
* Never use Jetty Quick Start - always use classpath scanning.
*/
Off {
@Override
public boolean isQuickstartEnabled() {
return false;
}
},
/**
* Use Jetty Quick Start only when running in Vaadin production mode.
*/
Production {
@Override
public boolean isQuickstartEnabled() {
return Env.isVaadinProductionMode;
}
},
/**
* Use Jetty Quick Start, both in dev and in production mode.
*/
Always {
@Override
public boolean isQuickstartEnabled() {
return true;
}
};
public abstract boolean isQuickstartEnabled();
}
}

0 comments on commit f7d0f0f

Please sign in to comment.