ããã¯ããªã«ãããããŠæžãããã®ïŒ
QuarkusãšãããRed HatãéçºããŠãããã¬ãŒã ã¯ãŒã¯ããã¡ãã£ãšè©ŠããŠã¿ãããšã
Javaフレームワーク「Quarkus」登場。Javaコードからネイティブバイナリを生成し瞬時にJavaアプリが起動、コンテナへの最適化を実現。Red Hatがリリース - Publickey
ãã€ãã£ããã«ããå¯èœãªãã¬ãŒã ã¯ãŒã¯ãšããŠããã£ãã話é¡ã«ãªã£ãã€ã¡ãŒãžããããŸãã
ãããããè©ŠããŠã¿ãããªããšã
Quarkus
Quarkusã«ã€ããŠã
Quarkus - Supersonic Subatomic Java
ãªãã£ã·ã£ã«ãµã€ããèŠããšã
- ã³ã³ãããã¡ãŒã¹ã ⊠ã¡ã¢ãªãããããªã³ãã軜ããKubernetesã®ãããªã³ã³ãããªãŒã±ã¹ãã¬ãŒã·ã§ã³ç°å¢ã«é©ããŠãã
- åœä»€åœ¢ã®ã¹ã¿ã€ã«ãããªã¢ã¯ãã£ããäž¡æ¹äœ¿ãã
- ãããã€ãç°¡å
ãšãã£ãããšãç¹åŸŽãšããŠæããããŠããŸãã
ãšãããããGetting StartedãèŠãªããè©ŠããŠããããšæããŸãã
ç°å¢
ä»åã®ç°å¢ã¯ããã¡ãã§ãã
$ java -version openjdk version "1.8.0_191" OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.18.04.1-b12) OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode) $ mvn -version Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-05T04:00:29+09:00) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 1.8.0_191, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-8-openjdk-amd64/jre Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "4.15.0-48-generic", arch: "amd64", family: "unix"
å©çšããQuarkusã®ããŒãžã§ã³ã¯ã0.14ãšããŸãã
ã¯ãããŠã®Quakusã¢ããªã±ãŒã·ã§ã³
ãšããããã察象ã®ãã£ã¬ã¯ããªãäœæã
$ mkdir getting-started $ cd getting-started
äœæãããã£ã¬ã¯ããªå ã§ãMavenãããžã§ã¯ããäœæããŸãã
$ mvn io.quarkus:quarkus-maven-plugin:0.14.0:create \ -DprojectGroupId=org.littlewings.quarkus \ -DprojectArtifactId=getting-started
ãããªæãã®ã¡ãã»ãŒãžãåºãŸãã
[INFO] ======================================================================================== [INFO] Your new application has been created in /path/to/getting-started/. [INFO] Navigate into this directory and launch your application with mvn compile quarkus:dev [INFO] Your application will be accessible on http://localhost:8080 [INFO] ========================================================================================
ãããžã§ã¯ãäœææã«æå®ã§ãããªãã·ã§ã³ã¯ããããªæãã§ãã
ã¡ãªã¿ã«ãGettins Startedã ãšäœæããJAX-RSãªãœãŒã¹ã¯ã©ã¹ãšãã¹ãæå®ããŠããŸãããä»åã¯çç¥ããŸããã
æå®ããå Žåã¯ãJAX-RSãªãœãŒã¹ã¯ã©ã¹ãšãã¹ãã³ãŒããäœæãããŸãã
çæããããpom.xmlãèŠãŠã¿ãŸãã
pom.xml
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>org.littlewings.quarkus</groupId> <artifactId>getting-started</artifactId> <version>1.0-SNAPSHOT</version> <properties> <surefire-plugin.version>2.22.0</surefire-plugin.version> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <quarkus.version>0.14.0</quarkus.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-bom</artifactId> <version>${quarkus.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>io.quarkus</groupId> <artifactId>quarkus-maven-plugin</artifactId> <version>${quarkus.version}</version> <executions> <execution> <goals> <goal>build</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>${surefire-plugin.version}</version> <configuration> <systemProperties> <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> </systemProperties> </configuration> </plugin> </plugins> </build> <profiles> <profile> <id>native</id> <activation> <property> <name>native</name> </property> </activation> <build> <plugins> <plugin> <groupId>io.quarkus</groupId> <artifactId>quarkus-maven-plugin</artifactId> <version>${quarkus.version}</version> <executions> <execution> <goals> <goal>native-image</goal> </goals> <configuration> <enableHttpUrlHandler>true</enableHttpUrlHandler> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>${surefire-plugin.version}</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> <configuration> <systemProperties> <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path> </systemProperties> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>
RESTEasyãå©çšã§ãããã§ãããã€ãã£ãã€ã¡ãŒãžã®ãã«ããã§ããããªèšå®ãå ¥ã£ãŠããŸãã
ã¿ãŒã²ããã¯ãJava 8ã¿ããã§ããã
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source>
çæããããã¡ã€ã«äžèŠ§ã
$ find -type f ./.dockerignore ./.mvn/wrapper/MavenWrapperDownloader.java ./.mvn/wrapper/maven-wrapper.jar ./.mvn/wrapper/maven-wrapper.properties ./pom.xml ./mvnw ./mvnw.cmd ./src/main/docker/Dockerfile.jvm ./src/main/docker/Dockerfile.native ./src/main/resources/META-INF/resources/index.html ./src/main/resources/application.properties
ãšãããããJAX-RSãªãœãŒã¹ã¯ã©ã¹ãäœæããŠã¿ãŸãã
src/main/java/org/littlewings/quarkus/gettingstarted/HelloResource.java
package org.littlewings.quarkus.gettingstarted; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("hello") public class HelloResource { @GET @Path("message") @Produces(MediaType.TEXT_PLAIN) public String message() { return "Hello Quarkus!!"; } }
mainã¡ãœãããæã£ãã¯ã©ã¹ã¯ãããŸããã
ã¢ããªã±ãŒã·ã§ã³äœææã«æ瀺ããããMavenã®ã³ãã³ããå®è¡ããŠã¿ãŸãã
$ mvn compile quarkus:dev
èµ·åããã°ãèŠããšãCDIã䜿ãããã§ããã
Listening for transport dt_socket at address: 5005 2019-04-29 15:06:19,305 INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation 2019-04-29 15:06:19,862 INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 557ms 2019-04-29 15:06:20,048 INFO [io.quarkus] (main) Quarkus 0.14.0 started in 0.809s. Listening on: http://[::]:8080 2019-04-29 15:06:20,049 INFO [io.quarkus] (main) Installed features: [cdi, resteasy]
確èªã
$ curl localhost:8080/hello/message Hello Quarkus!!
åããŸããã
ã¢ããªã±ãŒã·ã§ã³ãåããããŸãŸã®ç¶æ ã§ãå°ããœãŒã¹ã³ãŒããå€æŽããŠã¿ãŸãã
@GET @Path("message") @Produces(MediaType.TEXT_PLAIN) public String message() { return "Hello Quarkus!!??"; }
curlã§ã¢ã¯ã»ã¹ãããšããœãŒã¹ã³ãŒãã®å€æŽãæ€ç¥ããŠåæ ããŠãããããã§ãã
2019-04-29 15:07:51,079 INFO [io.qua.dev] (executor-thread-1) Changed source files detected, recompiling [/path/to/getting-started/src/main/java/org/littlewings/quarkus/gettingstarted/HelloResource.java] 2019-04-29 15:07:51,399 INFO [io.quarkus] (executor-thread-1) Quarkus stopped in 0.002s 2019-04-29 15:07:51,399 INFO [io.qua.dep.QuarkusAugmentor] (executor-thread-1) Beginning quarkus augmentation 2019-04-29 15:07:51,506 INFO [io.qua.dep.QuarkusAugmentor] (executor-thread-1) Quarkus augmentation completed in 107ms 2019-04-29 15:07:51,520 INFO [io.quarkus] (executor-thread-1) Quarkus 0.14.0 started in 0.121s. Listening on: http://[::]:8080 2019-04-29 15:07:51,520 INFO [io.quarkus] (executor-thread-1) Installed features: [cdi, resteasy] 2019-04-29 15:07:51,520 INFO [io.qua.dev] (executor-thread-1) Hot replace total time: 0.442s
çµæã
$ curl localhost:8080/hello/message Hello Quarkus!!??
ãšãããããå ã«æ»ããŠãããŸãã
@GET @Path("message") @Produces(MediaType.TEXT_PLAIN) public String message() { return "Hello Quarkus!!"; }
ä»ã«çæããããã¡ã€ã«ãèŠãŠã¿ãŸãããã
èšå®ãã¡ã€ã«ããŸã äžèº«ã¯ç¡ãããã§ãã
src/main/resources/application.properties
# Configuration file # key = value
HTMLãå«ãŸããŠããŸãã
src/main/resources/META-INF/resources/index.html
ã©ãããããããããã£ãœãããŒãžã ãªããšæã£ãã®ã§
<div class="banner lead"> Your new Cloud-Native application is ready! </div> <div class="container"> <div class="left-column"> <p class="lead"> Congratulations, you have created a new Quarkus application.</p> <h2>Why do you see this?</h2> <p>This page is served by Quarkus. The source is in <code>src/main/resources/META-INF/resources/index.html</code>.</p> <h2>What can I do from here?</h2> <p>If not already done, run the application in <em>dev mode</em> using: <code>mvn compile quarkus:dev</code>. </p> <ul> <li>Add REST resources, Servlets, functions and other services in <code>src/main/java</code>.</li> <li>Your static assets are located in <code>src/main/resources/META-INF/resources</code>.</li> <li>Configure your application in <code>src/main/resources/application.properties</code>. </li> </ul> <h2>How do I get rid of this page?</h2> <p>Just delete the <code>src/main/resources/META-INF/resources/index.html</code> file.</p> </div>
ã¢ã¯ã»ã¹ããŠã¿ããšããã£ã±ããããªæãã®ããŒãžã衚瀺ãããŸãããäžèŠã«ãªã£ãããåé€ããããŒãžãšãªãã§ãããã
ãããã°ããŠã¿ã
Quarkusã§äœã£ãã¢ããªã±ãŒã·ã§ã³ããããã°ããã«ã¯ããmvn quarkus:devãã§èµ·åããã¢ããªã±ãŒã·ã§ã³ã«ã¢ã¿ããããããšã«
ãªãããã§ãã
ããããã°ãèµ·åæã«ãããªè¡šç€ºãåºãŠããŸããã
Listening for transport dt_socket at address: 5005
IntelliJã®å Žåãã¡ãã¥ãŒã®ãRunãâãAttach to Process...ãããã¢ã¿ããããããã»ã¹ãéžæããŸãã
ãããã°ã§ããŸããããšã
ããã±ãŒãžã³ã°ããŠã¿ã
ç¶ããŠãããã±ãŒãžã³ã°ããŠã¿ãŸãã
$ mvn package
ã-runnerããšã€ããJARãã¡ã€ã«ã䜿ã£ãŠèµ·åã§ããŸãã
â»ã¡ãªã¿ã«ããã®JARãã¡ã€ã«ã¯Uber JARã§ã¯ãããŸãã
$ java -jar target/getting-started-1.0-SNAPSHOT-runner.jar 2019-04-29 15:04:22,781 INFO [io.quarkus] (main) Quarkus 0.14.0 started in 0.583s. Listening on: http://[::]:8080 2019-04-29 15:04:22,799 INFO [io.quarkus] (main) Installed features: [cdi, resteasy]
確èªã
$ curl localhost:8080/hello/message Hello Quarkus!!
ç¶ããŠãDockerã€ã¡ãŒãžãäœæããŠã¿ãŸãã
ãããžã§ã¯ãäœææã«DockerfileãäœæãããŠããã®ã§ããã®äžèº«ãèŠãŠã¿ãŸãã
src/main/docker/Dockerfile.jvm
#### # This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode # # Before building the docker image run: # # mvn package # # Then, build the image with: # # docker build -f src/main/docker/Dockerfile.jvm -t quarkus/getting-started-jvm . # # Then run the container using: # # docker run -i --rm -p 8080:8080 quarkus/getting-started-jvm # ### FROM fabric8/java-alpine-openjdk8-jre ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" ENV AB_ENABLED=jmx_exporter COPY target/lib/* /deployments/lib/ COPY target/*-runner.jar /deployments/app.jar ENTRYPOINT [ "/deployments/run-java.sh" ]
Java 8ãããŒã¹ã€ã¡ãŒãžã®ããã§ãã
ããã±ãŒãžã³ã°ããïŒJARãã¡ã€ã«ãäœã£ãïŒç¶æ ã§
$ mvn package
Dockerã€ã¡ãŒãžããã«ãããŠã¿ãŸãã
$ docker image build -f src/main/docker/Dockerfile.jvm -t kazuhira/quarkus-getting-started:1.0 .
ã§ãããã£ãDockerã€ã¡ãŒãžãèµ·åã
$ docker container run -it --rm -p 8080:8080 kazuhira/quarkus-getting-started:1.0 exec java -Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager -javaagent:/opt/agent-bond/agent-bond.jar=jmx_exporter{{9779:/opt/agent-bond/jmx_exporter_config.yml}} -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:+ExitOnOutOfMemoryError -cp . -jar /deployments/app.jar 2019-04-29 06:14:40,736 INFO [io.quarkus] (main) Quarkus 0.14.0 started in 0.636s. Listening on: http://0.0.0.0:8080 2019-04-29 06:14:40,757 INFO [io.quarkus] (main) Installed features: [cdi, resteasy]
確èªã
$ curl localhost:8080/hello/message Hello Quarkus!!
ãã€ãã£ãã€ã¡ãŒãžãäœã£ãŠã¿ã
ç¶ããŠããã€ãã£ãã€ã¡ãŒãžãäœæããŠã¿ãŸãã
ããŒã«ã«ã«GraalVMãã€ã³ã¹ããŒã«ããŠããªãå Žå
ãã€ãã£ãã€ã¡ãŒãžã®ãã«ãã«ã¯GraalVMãå¿
èŠã«ãªããŸãããGraalVMèªäœã®ã€ã³ã¹ããŒã«ãããŠããªããŠããã€ãã£ãã€ã¡ãŒãžã®
ãã«ãã¯è¡ãããšã¯ã§ããŸãïŒãã®å Žåã¯ãDockerãå¿
èŠã«ãªããŸãïŒã
ãšãããããGraalVMã¯çœ®ããŠãããŠãã«ãããŠã¿ãŸããããProfileããnativeãã«ããŠããnative-image.docker-buildããtrueã«ããŸãã
$ mvn package -Pnative -Dnative-image.docker-build=true
ãããšãQuarkusã®ãã€ãã£ãã€ã¡ãŒãžãã«ãçšã®Dockerã€ã¡ãŒãžãããŠã³ããŒãããŠããŠ
Unable to find image 'quay.io/quarkus/centos-quarkus-native-image:graalvm-1.0.0-rc15' locally graalvm-1.0.0-rc15: Pulling from quarkus/centos-quarkus-native-image
ãã®ã³ã³ããå ã§ãã«ãå§ãŸããŸãã
Status: Downloaded newer image for quay.io/quarkus/centos-quarkus-native-image:graalvm-1.0.0-rc15 [getting-started-1.0-SNAPSHOT-runner:6] classlist: 4,070.13 ms [getting-started-1.0-SNAPSHOT-runner:6] (cap): 1,039.38 ms [getting-started-1.0-SNAPSHOT-runner:6] setup: 2,459.11 ms 06:18:42,745 INFO [org.jbo.threads] JBoss Threads version 3.0.0.Alpha4 06:18:43,382 INFO [org.xnio] XNIO version 3.7.0.Final 06:18:43,479 INFO [org.xni.nio] XNIO NIO Implementation Version 3.7.0.Final [getting-started-1.0-SNAPSHOT-runner:6] (typeflow): 12,833.82 ms [getting-started-1.0-SNAPSHOT-runner:6] (objects): 13,022.13 ms [getting-started-1.0-SNAPSHOT-runner:6] (features): 770.32 ms [getting-started-1.0-SNAPSHOT-runner:6] analysis: 27,357.96 ms Printing call tree to /project/reports/call_tree_getting-started-1.0-SNAPSHOT-runner_20190429_061911.txt Printing list of used classes to /project/reports/used_classes_getting-started-1.0-SNAPSHOT-runner_20190429_061913.txt Printing list of used packages to /project/reports/used_packages_getting-started-1.0-SNAPSHOT-runner_20190429_061913.txt [getting-started-1.0-SNAPSHOT-runner:6] universe: 670.15 ms [getting-started-1.0-SNAPSHOT-runner:6] (parse): 2,536.38 ms [getting-started-1.0-SNAPSHOT-runner:6] (inline): 4,012.46 ms [getting-started-1.0-SNAPSHOT-runner:6] (compile): 17,990.18 ms [getting-started-1.0-SNAPSHOT-runner:6] compile: 26,063.85 ms [getting-started-1.0-SNAPSHOT-runner:6] image: 2,574.95 ms [getting-started-1.0-SNAPSHOT-runner:6] write: 682.75 ms [getting-started-1.0-SNAPSHOT-runner:6] [total]: 68,396.51 ms [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 02:27 min [INFO] Finished at: 2019-04-29T15:19:45+09:00 [INFO] ------------------------------------------------------------------------
ãããããããã«æéãããããŸãããâŠã
ã§ããã€ãã£ãã€ã¡ãŒãžçšã®Dockerfileã䜿ã£ãŠãDockerã€ã¡ãŒãžããã«ãã
$ docker image build -f src/main/docker/Dockerfile.native -t kazuhira/quarkus-getting-started-native:1.0 .
èµ·åã
$ docker container run -it --rm -p 8080:8080 kazuhira/quarkus-getting-started-native:1.0 2019-04-29 06:22:32,735 INFO [io.quarkus] (main) Quarkus 0.14.0 started in 0.003s. Listening on: http://0.0.0.0:8080 2019-04-29 06:22:32,735 INFO [io.quarkus] (main) Installed features: [cdi, resteasy]
ãã¡ããOKããã§ãã
$ curl localhost:8080/hello/message Hello Quarkus!!
ãããã€ãã£ãã€ã¡ãŒãžèªäœãèŠãŠããŸããã§ããããtargetãã£ã¬ã¯ããªé
äžã«ãã-runnerããä»äžããããã¡ã€ã«ã
ãã€ãã£ãã€ã¡ãŒãžã§ãã
$ ./target/getting-started-1.0-SNAPSHOT-runner
ãã€ãã£ãã€ã¡ãŒãžãã«ãæã®ãªãã·ã§ã³ã¯ããããªæãã«åºåãããŸãã
[INFO] [io.quarkus.creator.phase.nativeimage.NativeImagePhase] docker run -v /path/to/getting-started/target:/project:z --rm --user 1000:1000 quay.io/quarkus/centos-quarkus-native-image:graalvm-1.0.0-rc15 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -jar getting-started-1.0-SNAPSHOT-runner.jar -J-Djava.util.concurrent.ForkJoinPool.common.parallelism=1 -H:FallbackThreshold=0 -H:+PrintAnalysisCallTree -H:-AddAllCharsets -H:EnableURLProtocols=http -H:-SpawnIsolates -H:-JNI --no-server -H:-UseServiceLoaderFeature -H:+StackTrace
ãã®ãªãã·ã§ã³ãçµã¿ç«ãŠãŠããã®ã¯ããã®ãããã§ããã
ããŒã¹ã€ã¡ãŒãžã®æå®ã
private String builderImage = "quay.io/quarkus/centos-quarkus-native-image:graalvm-1.0.0-rc15";
ã§ãããã»ã¹å®è¡ã§ãããšã
ããŒã«ã«ã«GraalVMãã€ã³ã¹ããŒã«ããŠããå Žå
ããŒã«ã«ã«ã€ã³ã¹ããŒã«ãããŠããGraalVMã䜿ãå Žåã¯ãç°å¢å€æ°ãGRAALVM_HOMEãã䜿ã£ãŠGraalVMã®ã€ã³ã¹ããŒã«å
ã
æå®ããŸãã
â»GraalVM CE 1.0.0 RC15ã䜿ãã¹ãã¿ããã§ãããä»åã¯RC16ã䜿ããŸããâŠã
$ export GRAALVM_HOME=/usr/local/graalvm-ce $GRAALVM_HOME/bin/native-image --version GraalVM Version 1.0.0-rc16 CE
GraalVMã®Native Image Maven Pluginã䜿ãããã§ã¯ãªãã®ã§ãJAVA_HOMEã«GraalVMãèšå®ããå¿ èŠã¯ãããŸããã
ãããã¯ãQuarkus Maven Pluginã®configurationã«ãgraalvmHomeãšããŠèšå®ããŠãè¯ãããã§ãã
ãã«ãã
$ mvn package -Pnative
ãããšãããŒã«ã«ã®GraalVMã䜿ãããã«ãªããŸããã
[INFO] [io.quarkus.creator.phase.nativeimage.NativeImagePhase] /usr/local/graalvm-ce/bin/native-image -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -jar getting-started-1.0-SNAPSHOT-runner.jar -J-Djava.util.concurrent.ForkJoinPool.common.parallelism=1 -H:FallbackThreshold=0 -H:+PrintAnalysisCallTree -H:-AddAllCharsets -H:EnableURLProtocols=http -H:NativeLinkerOption=-no-pie -H:-SpawnIsolates -H:-JNI --no-server -H:-UseServiceLoaderFeature -H:+StackTrace
ã§ãããã£ãJARãšãã€ãã£ãã€ã¡ãŒãžã®ãµã€ãºæ¯èŒã
$ ll -h ./target/getting-started-1.0-SNAPSHOT-runner* -rwxrwxr-x 1 xxxxx xxxxx 20M 4æ 29 15:36 ./target/getting-started-1.0-SNAPSHOT-runner* -rw-r--r-- 1 xxxxx xxxxx 43K 4æ 29 15:36 ./target/getting-started-1.0-SNAPSHOT-runner.jar
ã-runner.jarãã®æ¹ãããããµã€ãºãå°ããã§ãã
ããã«ã¯çç±ããã£ãŠãå®ã¯Uber JARã§ã¯ãªããäžç·ã«äŸåã©ã€ãã©ãªãå¿
èŠãªåœ¢æ
ã«ãªã£ãŠããŸãã
äŸåããJARãã¡ã€ã«ã¯ããtarget/libãé
äžã«ãããŸãã
$ ll target/lib åèš 10204 drwxrwxr-x 2 xxxxx xxxxx 4096 4æ 29 17:05 ./ drwxrwxr-x 10 xxxxx xxxxx 4096 4æ 29 17:05 ../ -rw-rw-r-- 1 xxxxx xxxxx 65690 4æ 29 17:05 com.sun.activation.jakarta.activation-1.2.1.jar -rw-rw-r-- 1 xxxxx xxxxx 335042 4æ 29 17:05 commons-codec.commons-codec-1.11.jar -rw-rw-r-- 1 xxxxx xxxxx 208700 4æ 29 17:05 commons-io.commons-io-2.5.jar -rw-rw-r-- 1 xxxxx xxxxx 61829 4æ 29 17:05 commons-logging.commons-logging-1.2.jar -rw-rw-r-- 1 xxxxx xxxxx 113572 4æ 29 17:05 io.quarkus.arc.arc-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 21874 4æ 29 17:05 io.quarkus.quarkus-arc-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 110492 4æ 29 17:05 io.quarkus.quarkus-core-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 16756 4æ 29 17:05 io.quarkus.quarkus-jaxb-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 2549 4æ 29 17:05 io.quarkus.quarkus-jsonb-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 2516 4æ 29 17:05 io.quarkus.quarkus-jsonp-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 17662 4æ 29 17:05 io.quarkus.quarkus-resteasy-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 6123 4æ 29 17:05 io.quarkus.quarkus-resteasy-common-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 2984 4æ 29 17:05 io.quarkus.quarkus-resteasy-jsonb-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 47118 4æ 29 17:05 io.quarkus.quarkus-undertow-0.14.0.jar -rw-rw-r-- 1 xxxxx xxxxx 48421 4æ 29 17:05 io.smallrye.smallrye-config-1.3.5.jar -rw-rw-r-- 1 xxxxx xxxxx 2263313 4æ 29 17:05 io.undertow.undertow-core-2.0.19.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 532073 4æ 29 17:05 io.undertow.undertow-servlet-2.0.19.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 26586 4æ 29 17:05 javax.annotation.javax.annotation-api-1.3.2.jar -rw-rw-r-- 1 xxxxx xxxxx 73063 4æ 29 17:05 javax.el.javax.el-api-3.0.0.jar -rw-rw-r-- 1 xxxxx xxxxx 107519 4æ 29 17:05 javax.enterprise.cdi-api-2.0.SP1.jar -rw-rw-r-- 1 xxxxx xxxxx 2497 4æ 29 17:05 javax.inject.javax.inject-1.jar -rw-rw-r-- 1 xxxxx xxxxx 24404 4æ 29 17:05 javax.interceptor.javax.interceptor-api-1.2.jar -rw-rw-r-- 1 xxxxx xxxxx 23665 4æ 29 17:05 javax.json.bind.javax.json.bind-api-1.0.jar -rw-rw-r-- 1 xxxxx xxxxx 93107 4æ 29 17:05 javax.validation.validation-api-2.0.1.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 128076 4æ 29 17:05 javax.xml.bind.jaxb-api-2.3.1.jar -rw-rw-r-- 1 xxxxx xxxxx 2254 4æ 29 17:05 net.jcip.jcip-annotations-1.0.jar -rw-rw-r-- 1 xxxxx xxxxx 767916 4æ 29 17:05 org.apache.httpcomponents.httpclient-4.5.7.jar -rw-rw-r-- 1 xxxxx xxxxx 326874 4æ 29 17:05 org.apache.httpcomponents.httpcore-4.4.11.jar -rw-rw-r-- 1 xxxxx xxxxx 16772 4æ 29 17:05 org.eclipse.microprofile.config.microprofile-config-api-1.3.jar -rw-rw-r-- 1 xxxxx xxxxx 313516 4æ 29 17:05 org.eclipse.yasson-1.0.3.jar -rw-rw-r-- 1 xxxxx xxxxx 128770 4æ 29 17:05 org.glassfish.javax.json-1.1.4.jar -rw-rw-r-- 1 xxxxx xxxxx 430053 4æ 29 17:05 org.graalvm.sdk.graal-sdk-1.0.0-rc15.jar -rw-rw-r-- 1 xxxxx xxxxx 66469 4æ 29 17:05 org.jboss.logging.jboss-logging-3.3.2.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 20593 4æ 29 17:05 org.jboss.logging.jboss-logging-annotations-2.1.0.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 257131 4æ 29 17:05 org.jboss.logmanager.jboss-logmanager-embedded-1.0.3.jar -rw-rw-r-- 1 xxxxx xxxxx 706440 4æ 29 17:05 org.jboss.resteasy.resteasy-core-4.0.0.CR2.jar -rw-rw-r-- 1 xxxxx xxxxx 171097 4æ 29 17:05 org.jboss.resteasy.resteasy-core-spi-4.0.0.CR2.jar -rw-rw-r-- 1 xxxxx xxxxx 15733 4æ 29 17:05 org.jboss.resteasy.resteasy-json-binding-provider-4.0.0.CR2.jar -rw-rw-r-- 1 xxxxx xxxxx 13019 4æ 29 17:05 org.jboss.resteasy.resteasy-json-p-provider-4.0.0.CR2.jar -rw-rw-r-- 1 xxxxx xxxxx 9977 4æ 29 17:05 org.jboss.slf4j.slf4j-jboss-logging-1.1.0.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 300862 4æ 29 17:05 org.jboss.spec.javax.servlet.jboss-servlet-api_4.0_spec-1.0.0.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 144090 4æ 29 17:05 org.jboss.spec.javax.ws.rs.jboss-jaxrs-api_2.1_spec-1.0.2.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 131532 4æ 29 17:05 org.jboss.spec.javax.xml.bind.jboss-jaxb-api_2.3_spec-1.0.1.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 94766 4æ 29 17:05 org.jboss.threads.jboss-threads-3.0.0.Alpha4.jar -rw-rw-r-- 1 xxxxx xxxxx 585290 4æ 29 17:05 org.jboss.xnio.xnio-api-3.7.0.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 121458 4æ 29 17:05 org.jboss.xnio.xnio-nio-3.7.0.Final.jar -rw-rw-r-- 1 xxxxx xxxxx 14769 4æ 29 17:05 org.osgi.org.osgi.annotation.versioning-1.0.0.jar -rw-rw-r-- 1 xxxxx xxxxx 2097 4æ 29 17:05 org.reactivestreams.reactive-streams-1.0.2.jar -rw-rw-r-- 1 xxxxx xxxxx 41203 4æ 29 17:05 org.slf4j.slf4j-api-1.7.25.jar -rw-rw-r-- 1 xxxxx xxxxx 306888 4æ 29 17:05 org.wildfly.common.wildfly-common-1.5.0.Final-format-001.jar -rw-rw-r-- 1 xxxxx xxxxx 37911 4æ 29 17:05 org.wildfly.security.wildfly-elytron-asn1-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 12632 4æ 29 17:05 org.wildfly.security.wildfly-elytron-auth-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 255834 4æ 29 17:05 org.wildfly.security.wildfly-elytron-auth-server-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 45306 4æ 29 17:05 org.wildfly.security.wildfly-elytron-base-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 259181 4æ 29 17:05 org.wildfly.security.wildfly-elytron-credential-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 63438 4æ 29 17:05 org.wildfly.security.wildfly-elytron-permission-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 160200 4æ 29 17:05 org.wildfly.security.wildfly-elytron-ssl-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 41636 4æ 29 17:05 org.wildfly.security.wildfly-elytron-util-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 36464 4æ 29 17:05 org.wildfly.security.wildfly-elytron-x500-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 72291 4æ 29 17:05 org.wildfly.security.wildfly-elytron-x500-cert-2.0.0.Alpha1.jar -rw-rw-r-- 1 xxxxx xxxxx 7998 4æ 29 17:05 org.wildfly.security.wildfly-elytron-x500-cert-util-2.0.0.Alpha1.jar
ãããUber JARã«ããã«ã¯ãQuarkus Maven Pluginã®èšå®ã§ããuberJarããtrueã«ããå¿ èŠããããŸãã
<build> <plugins> <plugin> <groupId>io.quarkus</groupId> <artifactId>quarkus-maven-plugin</artifactId> <version>${quarkus.version}</version> <executions> <execution> <goals> <goal>build</goal> </goals> </execution> </executions> <configuration> <uberJar>true</uberJar> </configuration> </plugin>
ããã±ãŒãžã³ã°ããªãããšã10Mè¿ãã«ãªããŸããã
-rw-r--r-- 1 xxxxx xxxxx 9.5M 4æ 29 17:07 getting-started-1.0-SNAPSHOT-runner.jar
åçŽãªæ¯èŒã ãšãã€ãã£ãã€ã¡ãŒãžã®æ¹ã倧ãããã§ããã©ãJavaèªäœã®ã©ã³ã¿ã€ã ã®ãµã€ãºãèãããšããã®å·®ã軜ãã²ã£ãã
è¿ããŸããâŠã
CDIã足ããŠã¿ã
ãã£ãããªã®ã§ãããå°ãåŠçã足ããŠã¿ãŸãããã
ãšãããããã¢ããªã±ãŒã·ã§ã³ã¯èµ·åãããŸãŸã«ããŸãã
$ mvn compile quarkus:dev
ãããªã¯ã©ã¹ãäœãã
src/main/java/org/littlewings/quarkus/gettingstarted/CalcService.java
package org.littlewings.quarkus.gettingstarted; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class CalcService { public int add(int a, int b) { return a + b; } }
JAX-RSãªãœãŒã¹ã¯ã©ã¹ã¯ããšã³ããã€ã³ããè¿œå ã
src/main/java/org/littlewings/quarkus/gettingstarted/HelloResource.java
package org.littlewings.quarkus.gettingstarted; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; @Path("hello") @ApplicationScoped public class HelloResource { @Inject CalcService calcService; @GET @Path("message") @Produces(MediaType.TEXT_PLAIN) public String message() { return "Hello Quarkus!!"; } @GET @Path("add") @Produces(MediaType.TEXT_PLAIN) public int add(@QueryParam("a") int a, @QueryParam("b") int b) { return calcService.add(a, b); } }
ç¹ã«åèµ·åãªã©ããªããŸãŸãå€æŽãåæ ãããŸããã
$ curl 'localhost:8080/hello/add?a=5&b=3' 8
ãããã§ããã
ãªã¯ãšã¹ããšã¬ã¹ãã³ã¹ã«JSONã䜿ã£ãŠã¿ã
pom.xmlã«ãRESTEasy JSON-B Extensionãè¿œå ããŸãã
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-jsonb</artifactId> </dependency>
èµ·åã
$ mvn compile quarkus:dev
JAX-RSã¯ã©ã¹ã«ã以äžã®ãããªã¡ãœãããè¿œå ããŠ
@POST @Path("add") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) public Map<String, ?> add(Map<String, Integer> request) { Map<String, Integer> result = new HashMap<>(); result.put("result", calcService.add(request.get("a"), request.get("b"))); return result; }
確èªã
$ curl -XPOST -H 'Content-Type: application/json' localhost:8080/hello/add -d '{"a": 5, "b": 3}' {result=8}
ãšãããããæåã¯ãããªæãã§ã
ãªãã±ïŒãããžã§ã¯ãäœææã«ãJAX-RSãªãœãŒã¹ã¯ã©ã¹ãæå®ããŠãããïŒ
$ mvn io.quarkus:quarkus-maven-plugin:0.14.0:create \ -DprojectGroupId=org.littlewings.quarkus \ -DprojectArtifactId=getting-started \ -DclassName="org.littlewings.quarkus.gettingstarted.HelloResource" \ -Dpath="/hello"
$ find -type f ./.dockerignore ./.mvn/wrapper/MavenWrapperDownloader.java ./.mvn/wrapper/maven-wrapper.jar ./.mvn/wrapper/maven-wrapper.properties ./pom.xml ./mvnw ./mvnw.cmd ./src/main/docker/Dockerfile.jvm ./src/main/docker/Dockerfile.native ./src/main/resources/META-INF/resources/index.html ./src/main/resources/application.properties ./src/main/java/org/littlewings/quarkus/gettingstarted/HelloResource.java ./src/test/java/org/littlewings/quarkus/gettingstarted/HelloResourceTest.java ./src/test/java/org/littlewings/quarkus/gettingstarted/NativeHelloResourceIT.java
äœæããããJAX-RSãªãœãŒã¹ã¯ã©ã¹ã
src/main/java/org/littlewings/quarkus/gettingstarted/HelloResource.java
package org.littlewings.quarkus.gettingstarted; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/hello") public class HelloResource { @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return "hello"; } }
ãã®å Žåããã¹ããåºåãããŸãã
src/test/java/org/littlewings/quarkus/gettingstarted/HelloResourceTest.java
package org.littlewings.quarkus.gettingstarted; import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.is; @QuarkusTest public class HelloResourceTest { @Test public void testHelloEndpoint() { given() .when().get("/hello") .then() .statusCode(200) .body(is("hello")); } }
ãã€ãã£ãã€ã¡ãŒãžçšã®ãã¹ããåºåãããŸããããã¡ãã¯éåžžã®ãã¹ããç¶æ¿ãããã®ã§ããã
src/test/java/org/littlewings/quarkus/gettingstarted/NativeHelloResourceIT.java
package org.littlewings.quarkus.gettingstarted; import io.quarkus.test.junit.SubstrateTest; @SubstrateTest public class NativeHelloResourceIT extends HelloResourceTest { // Execute the same tests but in native mode. }
ãã€ãã£ãã€ã¡ãŒãžçšã®ãã¹ãã¯ã€ã³ãã°ã¬ãŒã·ã§ã³ãã¹ããšããŠåäœããã®ã§ã以äžã®ããã«ããŠå®è¡ããŸãã
â»ç°å¢å€æ°GRAALVM_HOMEã䜿ãå Žå
$ mvn -Pnative integration-test $ mvn -Pnative verify
ãã«ãããã»ã¹ã«ãã€ãã£ãã€ã¡ãŒãžã®ãã«ããå ¥ãã®ã§ããããªãã«æéã¯ããããŸãâŠã