Do you know GraalVM? It is a tool that natively compiles Java and, in some cases, reduces memory consumption to 1/16 (https://qiita.com/ukiuni@github/items/2999acf26fdc0c3f8353). However, there are restrictions on the applications that GraalVM can compile, and not all Java applications can be compiled natively.
This time, in order to create a native web application, I tried to verify whether a Java application with a built-in web server can be compiled and executed with GraalVM.
Create Fat Jar using gradle shadow and compile with Fat Jar specified by -jar option in GraalVM's native-image command.
$ native-image --version
GraalVM Version 1.0.0-rc13
$ java -version
openjdk version "1.8.0_202"
OpenJDK Runtime Environment (build 1.8.0_202-20190206132754.buildslave.jdk8u-src-tar--b08)
OpenJDK GraalVM CE 1.0.0-rc13 (build 25.202-b08-jvmci-0.55, mixed mode)
Tomcat(tomcat-embed-core v9.0.17) It was no good.
Source
Source excerpt
public static void main(String[] args) throws Exception {
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.getConnector();
File base = new File("src/main/static/");
Context context = tomcat.addContext("/app", base.getAbsolutePath());
Tomcat.addServlet(context, "default", new DefaultServlet()).addMapping("/");
Tomcat.addServlet(context, "hello", new HttpServlet() {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Writer w = resp.getWriter();
w.write("Hello, World!");
w.flush();
}
}).addMapping("/hello");
tomcat.start();
tomcat.getServer().await();
}
Compilation failed.
$ native-image -jar build/libs/app-all.jar
Build on Server(pid: 2099, port: 50704)
[app-all:2099] classlist: 1,259.46 ms
[app-all:2099] (cap): 1,512.61 ms
[app-all:2099] setup: 7,054.04 ms
[app-all:2099] analysis: 10,298.20 ms
Error: unsupported features in 2 methods
Detailed message:
Error: Class initialization failed: com.sun.naming.internal.ResourceManager$AppletParameter
Original exception that caused the problem: java.lang.ExceptionInInitializerError
...(abridgement)
Sorry.
Jetty(jetty-server v9.4.15.v20190215) I was able to go!
Source excerpt
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
server.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter out = response.getWriter();
out.println("Hello World!");
baseRequest.setHandled(true);
}
});
server.start();
server.join();
}
Compile & Run
$ native-image -jar build/libs/app-all.jar
Build on Server(pid: 2523, port: 51183)*
[app-all:2523] classlist: 3,325.81 ms
[app-all:2523] (cap): 1,309.95 ms
[app-all:2523] setup: 8,400.08 ms
2019-04-04 22:16:54.214:INFO::ForkJoinPool-2-worker-3: Logging initialized @22713ms to org.eclipse.jetty.util.log.StdErrLog
[app-all:2523] (typeflow): 11,805.43 ms
[app-all:2523] (objects): 9,466.98 ms
[app-all:2523] (features): 354.09 ms
[app-all:2523] analysis: 37,080.95 ms
[app-all:2523] universe: 650.05 ms
[app-all:2523] (parse): 3,276.85 ms
[app-all:2523] (inline): 6,226.93 ms
[app-all:2523] (compile): 31,668.53 ms
[app-all:2523] compile: 57,307.38 ms
[app-all:2523] image: 2,385.43 ms
[app-all:2523] write: 859.86 ms
[app-all:2523] [total]: 145,307.12 ms
$ ./app-all
2019-04-04 22:19:55.501:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2019-02-15T16:53:49.381Z; git: eb70b240169fcf1abbd86af36482d1c49826fa0b; jvm 1.8.0_202
2019-04-04 22:19:55.502:INFO:oejs.AbstractConnector:main: Started ServerConnector@6b64b5db{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2019-04-04 22:19:55.502:INFO:oejs.Server:main: Started @2ms
Start up safely! I was able to access it with a browser! great.
Undertow(undertow-core v2.0.19.Final) It was no good. .. ..
Source excerpt
public static void helloWorldHandler(HttpServerExchange exchange) {
exchange.getResponseHeaders().add(Headers.CONTENT_TYPE, "text/plain");
exchange.getResponseSender().send("Hello World!");
}
public static void main(String[] args) {
Undertow server = Undertow.builder().addHttpListener(8080, "0.0.0.0", App::helloWorldHandler).build();
server.start();
}
compile.
$ native-image -jar build/libs/app-all.jar
Build on Server(pid: 2523, port: 51183)
[app-all:2523] classlist: 2,361.03 ms
[app-all:2523] (cap): 1,720.81 ms
[app-all:2523] setup: 7,458.13 ms
[app-all:2523] analysis: 6,485.28 ms
Error: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: org.osgi.framework.FrameworkUtil. To diagnose the issue you can use the --allow-incomplete-classpath option. The missing type is then reported at run time when it is accessed the first time.
After that, I added the --allow-incomplete-classpath option or something, but I couldn't compile it. Sorry.
There was a result that even one could be compiled. The light of Web application operation with 1/16 memory resources has come into view! After that, if JPA works, it seems that you can make a simple Web application. JPA seems to be running on Quarkus, so I'm hoping that it can be compiled.
Recommended Posts