Vaadin 10 + Jetty embedded.

I am also desperate looking for a working example of how to get Vaadin 12 to work with embedded Jetty. It used to work with Vaadin 7 and 8, but I can not get it right with Vaadin 12.

Forget the ServletContext configuration and see my post: https://vaadin.com/forum/thread/17483200/vaadin-12-with-jetty-embedded-within-an-osgi-bundle-missing-vaadin-sta

Most important part is the custom RouteRegistry. In addition you need to add the following static resource lookup (HTTP → classpath):

/frontend/ → /META-INF/resources/frontend/

/frontend/bower_components/ → /META-INF/resources/webjars/

/VAADIN/ → /META-INF/resources/VAADIN/

…maybe more, I just got it basically working!

I am using a JAX-RS component for the resources. That’s why I don’t have the full example just now.

“asyncSupported = true” needs to be set in the ServletContext configuration!

Hi Martin,

Once you get yours working, would you be so kind to post the full example including the relative locations of the resources/jars that are needed?

I think the Vaadin docs (book of Vaadin, etc) should have a section explaining how to get Vaadin Flow working with embedded Jetty. It seems like it is an important topic for enough people.

Thank you so much for your help.

Are you guys using this embedded Jetty in production environments or only in development/testing?

i am using it in both test and production as a lightweight web server

I just uploaded an example that creates an executable uber-jar using Vaadin 12+: https://github.com/alejandro-du/embedded-jetty-demo

Basically, you have to configure the server as follows:

public class Application {

    public static void main(String... args) throws Exception {
        new Application().run(8080, "/");
    }

    public void run(int port, String contextPath) throws Exception {
        URL webRootLocation = this.getClass().getResource("/META-INF/resources/");
        URI webRootUri = webRootLocation.toURI();

        WebAppContext context = new WebAppContext();
        context.setBaseResource(Resource.newResource(webRootUri));
        context.setContextPath(contextPath);
        context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*");
        context.setConfigurationDiscovered(true);
        context.setConfigurations(new Configuration[]{
                new AnnotationConfiguration(),
                new WebInfConfiguration(),
                new WebXmlConfiguration(),
                new MetaInfConfiguration(),
                new FragmentConfiguration(),
                new EnvConfiguration(),
                new PlusConfiguration(),
                new JettyWebXmlConfiguration()
        });
        context.getServletContext().setExtendedListenerTypes(true);
        context.addEventListener(new ServletContextListeners());

        Server server = new Server(port);
        server.setHandler(context);

        server.start();
        server.join();
    }

}

Also, you need to use the maven-shade-plugin to package the artifact in an uber-jar.

How can it be done without WebAppContext?

Here is an up to date step by step tutorial on how to get embedded Jetty into your Vaadin Flow app: https://vaadin.com/tutorials/embedded-jetty-server-in-vaadin-flow

@Martin: maybe ServletContextHandler? What is the limitation with WebAppContext?

Alejandro Duarte:
Also, you need to use the maven-shade-plugin to package the artifact in an uber-jar.

How can i exclude ‘shade’ plugin and use ‘maven-jar-plugin’ ‘maven-dependency-plugin’ instead?

It works with Vaadin 8, for example:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <classpathLayoutType>simple</classpathLayoutType>
                            <mainClass>our.Application</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.10</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <includeScope>compile</includeScope>
                            <outputDirectory>${project.build.directory}/libs</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Alexander Cherepanov:

Alejandro Duarte:
Also, you need to use the maven-shade-plugin to package the artifact in an uber-jar.

How can i exclude ‘shade’ plugin and use ‘maven-jar-plugin’ ‘maven-dependency-plugin’ instead?

Take a look at this: https://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html

Alejandro Duarte:
Take a look at this: https://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html

Thanks, it work.

           <!--
             1. Unpack folders META-INF/resources/ from all dependencies (It needs for next plugin)
             2. Copy all dependencies to folder libs/
            -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.1</version>
                <executions>
                    <execution>
                        <id>get-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>unpack-dependencies</goal>
                        </goals>
                        <configuration>
                            <includes>META-INF/resources/**/*</includes>
                            <outputDirectory>target/classes/</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>

                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <includeScope>compile</includeScope>
                            <outputDirectory>${project.build.directory}/libs</outputDirectory>
                        </configuration>
                    </execution>

                </executions>
            </plugin>

            <!--
            Build JAR
            -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <classpathLayoutType>simple</classpathLayoutType>
                            <mainClass>own.Application</mainClass>
                        </manifest>
                    </archive>
                    <includes>
                        <include>**/*.class</include>
                        <include>META-INF/resources/**/*</include>
                    </includes>
                </configuration>
            </plugin>


Alexander Cherepanov:

Alejandro Duarte:
Take a look at this: https://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html

Thanks, it work.

Cool! Thanks for sharing the solution.

Hmm. I play with annotations @Push, @Theme and @Route. I create some classes with that annotations, all works fine. Then i wanted to disable some classes from routing and simply comment @Route annotation. After that all app restarts brought me to “HTTP ERROR 503. Service Unavailable” message. All other views become unavailable too. I tried to play with some variants with comment/uncomment annotations and understand that i should not use @Push or @Theme annotations with commented out @Route.
This post helps me: [https://stackoverflow.com/a/52270242/1059104]
(https://stackoverflow.com/a/52270242/1059104)

Vaadin 14 brings new pain… Is there anybody know wehere to get working Jetty-embedded demo project?

It’s actually less pain! You should use npm-based frontend build. For this you need to remove all jars related to webjar content from the classpath. Then you need to have the following Servlet and set the following init configuration:

asyncSupported=true
compatibilityMode=false

However, there is some serious build trouble with Vaadin 14 RC3, you should use RC2 for now!

SERVLET:

public class VaadinJettyEmbeddedServlet extends VaadinServlet {
	
	private static final long serialVersionUID = -8665721849295105766L;

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		super.init(servletConfig);
		
		this.getService().setClassLoader(VaadinJettyEmbeddedServlet.class.getClassLoader());
	}
	
	@Override
	public boolean serveStaticOrWebJarRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
		if(request.getRequestURI().startsWith("/VAADIN/static")) {
			URL resource = this.getClass().getClassLoader().getResource("/META-INF/resources" + request.getRequestURI());
			if(resource != null) {
				String mimetype = request.getServletContext().getMimeType(request.getRequestURI());
				if(mimetype != null) response.setContentType(mimetype);
				
				InputStream inputStream = resource.openStream();
				try {
					return IOUtils.copy(inputStream, response.getOutputStream()) > 0;
				} finally {
					IOUtils.closeQuietly(inputStream);
				}
			}
		}
		return super.serveStaticOrWebJarRequest(request, response);
	}
}

MAVEN POM:

<repositories>
	<repository>
		<id>vaadin-prereleases</id>
		<url>https://maven.vaadin.com/vaadin-prereleases</url>
		<snapshots><enabled>false</enabled></snapshots>
	</repository>
</repositories>
<pluginRepositories>
	<pluginRepository>
		<id>vaadin-prereleases</id>
		<url>https://maven.vaadin.com/vaadin-prereleases</url>
		<snapshots><enabled>false</enabled></snapshots>
	</pluginRepository>
</pluginRepositories>

<dependencies>
	<dependency>
		<groupId>com.vaadin</groupId>
		<artifactId>vaadin-core</artifactId>
		<version>14.0.0.rc2</version>
	</dependency>
</dependencies>

<build>
	<plugins>
		<plugin>
			<groupId>com.vaadin</groupId>
			<artifactId>vaadin-maven-plugin</artifactId>
			<version>14.0.0.rc2</version>
			<executions>
				<execution>
					<goals>
						<goal>prepare-frontend</goal>
						<goal>build-frontend</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

Thanks, i made changes as you say. But there is the same no-style output as it was before…

Add the following jars to the classpath of your project:

atmosphere-runtime-2.4.30.slf4jvaadin1.jar
byte-buddy-1.9.13.jar
commons-fileupload-1.3.3.jar
commons-io-2.5.jar
commons-lang3-3.0.jar
flow-client-2.0-SNAPSHOT.jar
flow-data-2.0-SNAPSHOT.jar
flow-html-components-2.0-SNAPSHOT.jar
flow-push-2.0-SNAPSHOT.jar
flow-server-2.0-SNAPSHOT.jar
gentyref-1.2.0.vaadin1.jar
gwt-elemental-2.8.2.vaadin2.jar
javax.servlet-api-3.1.0.jar
jsoup-1.11.3.jar
ph-commons-9.1.2.jar
ph-css-6.1.1.jar
slf4j-api-1.7.25.jar
vaadin-accordion-flow-2.0-SNAPSHOT.jar
vaadin-app-layout-flow-2.0-SNAPSHOT.jar
vaadin-button-flow-2.0-SNAPSHOT.jar
vaadin-checkbox-flow-2.0-SNAPSHOT.jar
vaadin-combo-box-flow-3.0-SNAPSHOT.jar
vaadin-context-menu-flow-3.0-SNAPSHOT.jar
vaadin-core-14.0-SNAPSHOT.jar
vaadin-custom-field-flow-3.0-SNAPSHOT.jar
vaadin-date-picker-flow-2.0-SNAPSHOT.jar
vaadin-details-flow-2.0-SNAPSHOT.jar
vaadin-dialog-flow-2.0-SNAPSHOT.jar
vaadin-form-layout-flow-2.0-SNAPSHOT.jar
vaadin-grid-flow-4.0-SNAPSHOT.jar
vaadin-icons-flow-2.0-SNAPSHOT.jar
vaadin-iron-list-flow-2.0-SNAPSHOT.jar
vaadin-list-box-flow-2.0-SNAPSHOT.jar
vaadin-login-flow-2.0-SNAPSHOT.jar
vaadin-lumo-theme-2.0-SNAPSHOT.jar
vaadin-material-theme-2.0-SNAPSHOT.jar
vaadin-menu-bar-flow-1.0-SNAPSHOT.jar
vaadin-notification-flow-2.0-SNAPSHOT.jar
vaadin-ordered-layout-flow-2.0-SNAPSHOT.jar
vaadin-progress-bar-flow-2.0-SNAPSHOT.jar
vaadin-radio-button-flow-2.0-SNAPSHOT.jar
vaadin-select-flow-2.0-SNAPSHOT.jar
vaadin-split-layout-flow-2.0-SNAPSHOT.jar
vaadin-tabs-flow-2.0-SNAPSHOT.jar
vaadin-text-field-flow-2.0-SNAPSHOT.jar
vaadin-time-picker-flow-2.0-SNAPSHOT.jar
vaadin-upload-flow-2.0-SNAPSHOT.jar
validation-api-2.0.0.Final.jar

How can i do it with Maven?

Hi, I’ve created an example project which runs embedded Jetty on Vaadin 14.1: https://github.com/mvysny/vaadin14-embedded-jetty