Vaadin Flow 14,Jetty 嵌入式和静态文件
Vaadin Flow 14, Jetty embedded and static files
我正在尝试基于 Jetty 9.4.20(嵌入式)和 Vaadin Flow 14.0.12 创建应用程序。
它基于非常好的项目 vaadin14-embedded-jetty。
我想用一个 main-jar
打包应用程序,所有依赖库必须在 main-jar
附近的文件夹 'libs' 中。
我删除了 maven-assembly-plugin
,而是使用 maven-dependency-plugin
和 maven-jar-plugin
。在 maven-dependency-plugin
中,我添加了部分 <execution>get-dependencies</execution>
,其中我将目录 META-INF/resources/,META-INF/services/
从 Vaadin Flow 库解压缩到结果 JAR。
在这种情况下,应用程序工作正常。但是,如果我评论 <execution>get-dependencies</execution>
部分,则结果包不包含该目录,并且应用程序无法运行。
它只是不能从 Vaadin Flow 库中提供一些静态文件。
仅当我使用...启动打包的应用程序时才会出现此错误
$ java -jar vaadin14-embedded-jetty-1.0-SNAPSHOT.jar
...但是从 Intellij Idea 中它可以正确启动。
有人认为 Jetty 盯着错误的 ClassLoader,无法维护对 Jar-libs 中静态文件的请求。
必须从 Jetty 库维护 META-INF/services/
文件。
使用 Jetty 很重要java.util.ServiceLoader
。
如果您将 JAR 文件的内容合并到一个 JAR 文件中,则称为 "uber jar"。
有很多技术可以做到这一点,但是如果您使用 maven-assembly-plugin
或 maven-dependency-plugin
来构建这个 "uber jar" 那么您将不会合并具有相同名称的关键文件跨多个 JAR 文件。
考虑使用 maven-shade-plugin
及其关联的资源转换器来正确合并这些文件。
- http://maven.apache.org/plugins/maven-shade-plugin/
- http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html
ServicesResourceTransformer
是合并META-INF/services/
个文件的那个,用吧
至于静态内容,效果很好,但您必须正确设置基础资源。
查看您的来源,您执行以下操作...
final URI webRootUri = ManualJetty.class.getResource("/webapp/").toURI();
final WebAppContext context = new WebAppContext();
context.setBaseResource(Resource.newResource(webRootUri));
在 100% 的情况下,这不会可靠地工作(正如您在 IDE vs 命令行中注意到 运行 时所注意到的那样)。
Class.getResource(String)
只有在查找文件(而不是目录)时才可靠。
请考虑 Jetty Project Embedded Cookbook 食谱中的技巧。
参见:
- WebAppContextFromClasspath.java
- ResourceHandlerFromClasspath.java
- DefaultServletFileServer.java
- DefaultServletMultipleBases.java
- XmlEnhancedServer.java
- MultipartMimeUploadExample.java
示例:
// Figure out what path to serve content from
ClassLoader cl = ManualJetty.class.getClassLoader();
// We look for a file, as ClassLoader.getResource() is not
// designed to look for directories (we resolve the directory later)
URL f = cl.getResource("webapp/index.html");
if (f == null)
{
throw new RuntimeException("Unable to find resource directory");
}
// Resolve file to directory
URI webRootUri = f.toURI().resolve("./").normalize();
System.err.println("WebRoot is " + webRootUri);
WebAppContext context = new WebAppContext();
context.setBaseResource(Resource.newResource(webRootUri));
我正在尝试基于 Jetty 9.4.20(嵌入式)和 Vaadin Flow 14.0.12 创建应用程序。
它基于非常好的项目 vaadin14-embedded-jetty。
我想用一个 main-jar
打包应用程序,所有依赖库必须在 main-jar
附近的文件夹 'libs' 中。
我删除了 maven-assembly-plugin
,而是使用 maven-dependency-plugin
和 maven-jar-plugin
。在 maven-dependency-plugin
中,我添加了部分 <execution>get-dependencies</execution>
,其中我将目录 META-INF/resources/,META-INF/services/
从 Vaadin Flow 库解压缩到结果 JAR。
在这种情况下,应用程序工作正常。但是,如果我评论 <execution>get-dependencies</execution>
部分,则结果包不包含该目录,并且应用程序无法运行。
它只是不能从 Vaadin Flow 库中提供一些静态文件。
仅当我使用...启动打包的应用程序时才会出现此错误
$ java -jar vaadin14-embedded-jetty-1.0-SNAPSHOT.jar
...但是从 Intellij Idea 中它可以正确启动。
有人认为 Jetty 盯着错误的 ClassLoader,无法维护对 Jar-libs 中静态文件的请求。
必须从 Jetty 库维护 META-INF/services/
文件。
使用 Jetty 很重要java.util.ServiceLoader
。
如果您将 JAR 文件的内容合并到一个 JAR 文件中,则称为 "uber jar"。
有很多技术可以做到这一点,但是如果您使用 maven-assembly-plugin
或 maven-dependency-plugin
来构建这个 "uber jar" 那么您将不会合并具有相同名称的关键文件跨多个 JAR 文件。
考虑使用 maven-shade-plugin
及其关联的资源转换器来正确合并这些文件。
- http://maven.apache.org/plugins/maven-shade-plugin/
- http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html
ServicesResourceTransformer
是合并META-INF/services/
个文件的那个,用吧
至于静态内容,效果很好,但您必须正确设置基础资源。
查看您的来源,您执行以下操作...
final URI webRootUri = ManualJetty.class.getResource("/webapp/").toURI();
final WebAppContext context = new WebAppContext();
context.setBaseResource(Resource.newResource(webRootUri));
在 100% 的情况下,这不会可靠地工作(正如您在 IDE vs 命令行中注意到 运行 时所注意到的那样)。
Class.getResource(String)
只有在查找文件(而不是目录)时才可靠。
请考虑 Jetty Project Embedded Cookbook 食谱中的技巧。
参见:
- WebAppContextFromClasspath.java
- ResourceHandlerFromClasspath.java
- DefaultServletFileServer.java
- DefaultServletMultipleBases.java
- XmlEnhancedServer.java
- MultipartMimeUploadExample.java
示例:
// Figure out what path to serve content from
ClassLoader cl = ManualJetty.class.getClassLoader();
// We look for a file, as ClassLoader.getResource() is not
// designed to look for directories (we resolve the directory later)
URL f = cl.getResource("webapp/index.html");
if (f == null)
{
throw new RuntimeException("Unable to find resource directory");
}
// Resolve file to directory
URI webRootUri = f.toURI().resolve("./").normalize();
System.err.println("WebRoot is " + webRootUri);
WebAppContext context = new WebAppContext();
context.setBaseResource(Resource.newResource(webRootUri));