diff --git a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc index 960ead82..a33dfc86 100644 --- a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc @@ -22,9 +22,34 @@ https://en.wikipedia.org/wiki/Fortune_(Unix)[fortune Unix program]. The data for the fortune phrases is provided by https://github.com/your-fortune[YourFortune]. ==== -. Create a new Java project with *Maven* in your favorite IDE, called "Fortune", in the _demo_ package. -Make sure to choose JUnit Jupiter as the test engine. -The application should contain a sole Java file with the following content: +. Create a new Java project with *Maven* in your favorite IDE, called _Fortune_ and make sure to choose +https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter[JUnit Jupiter] as the test engine. The _pom.xml_ file +should look similar to the following. ++ +[source,xml] +---- + + + 4.0.0 + + demo + fortune + 1.0.0 + Fortune Teller GraalVM Demo + + + + org.junit.jupiter + junit-jupiter + 5.10.1 + test + + + +---- + +. Create a package, named _demo_, and add the _Fortune.java_ (_src/main/java/demo/Fortune.java_) class. + [source,java] ---- @@ -59,9 +84,9 @@ public class Fortune { while (elements.hasNext()) { JsonNode quote = elements.next().get("quote"); fortunes.add(quote.asText()); - } + } } - + private String readInputStream(InputStream is) { StringBuilder out = new StringBuilder(); try (InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8); @@ -76,20 +101,25 @@ public class Fortune { } return out.toString(); } - + private void printRandomFortune() throws InterruptedException { - //Pick a random number - int r = RANDOM.nextInt(fortunes.size()); - //Use the random number to pick a random fortune - String f = fortunes.get(r); + //Pick a random fortune + String f = randomFortune(); // Print out the fortune s.l.o.w.l.y - for (char c: f.toCharArray()) { + for (char c : f.toCharArray()) { System.out.print(c); - Thread.sleep(100); + Thread.sleep(100); } System.out.println(); } + public String randomFortune() { + //Pick a random number + int r = RANDOM.nextInt(fortunes.size()); + //Use the random number to pick a random fortune + return fortunes.get(r); + } + /** * @param args the command line arguments * @throws java.lang.InterruptedException @@ -102,8 +132,8 @@ public class Fortune { } ---- . Copy and paste the following file, -https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under _resources/_. -Your project tree should be: +https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] +under the _resources_ directory (_src/main/resources/fortunes.json_). Your project tree should be: + [source,shell] ---- @@ -117,209 +147,229 @@ Your project tree should be: └── resources └── fortunes.json ---- -. Add explicit FasterXML Jackson dependencies that provide functionality to read and write JSON, data bindings (used in the demo application). Open the _pom.xml_ file (a Maven configuration file), and insert the following in the `` section: +. Add explicit https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind[FasterXML Jackson] +dependency that provide functionality to read and write JSON, data bindings (used in the demo application). Open the +_pom.xml_ file (a Maven configuration file), and insert the following in the `` section: + [source,xml] ---- - - - com.fasterxml.jackson.core - jackson-databind - 2.12.6.1 - - + + com.fasterxml.jackson.core + jackson-databind + 2.16.0 + +---- +There should be two dependencies, the FasterXML Jackson dependency and the JUnit 5 dependency as shown below. ++ +[source,xml] +---- + + + com.fasterxml.jackson.core + jackson-databind + 2.16.0 + + + org.junit.jupiter + junit-jupiter + 5.10.1 + test + + ---- . Add regular Maven plugins for building and assembling a Maven project into an executable JAR. Insert the following into the `build` section in the _pom.xml_ file: + [source,xml] ---- - - - - org.codehaus.mojo - exec-maven-plugin - 3.0.0 - - - java - - java - - - ${mainClass} - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - ${maven.compiler.source} - ${maven.compiler.source} - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.2.2 - - - - true - ${mainClass} - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - - - - - true - ${mainClass} - - - - jar-with-dependencies - - - - - - + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.1 + + + java + + java + + + ${mainClass} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${maven.compiler.source} + ${maven.compiler.source} + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + + true + ${mainClass} + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.6.0 + + + package + + single + + + + + + + true + ${mainClass} + + + + jar-with-dependencies + + + + + ---- . Replace the default `` section in the _pom.xml_ file with this content: + [source,xml,subs="verbatim,attributes"] ---- - - {maven-plugin-version} - 5.8.1 - ${java.specification.version} - ${java.specification.version} - fortune - demo.Fortune - + + {maven-plugin-version} + ${java.specification.version} + ${java.specification.version} + fortune + demo.Fortune + ---- + The statements "hardcoded" plugin versions and the entry point class to your application. The next steps demonstrate what you should do to enable the https://graalvm.github.io/native-build-tools/latest/maven-plugin.html[Maven plugin for GraalVM Native Image]. -. Register the Maven plugin for GraalVM Native Image, `native-maven-plugin`, in the profile called `native` by adding the following to the _pom.xml_ file: +. Register the Maven plugin for GraalVM Native Image, `native-maven-plugin`, in the profile called `native` by adding +the following to the _pom.xml_ file: + [source,xml] ---- - - - native - - - - org.graalvm.buildtools - native-maven-plugin - ${native.maven.plugin.version} - true - - - build-native - - build - - package - - - test-native - - test - - test - - - - false - - - - - - + + + native + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + + + build-native + + compile-no-fork + + package + + + test-native + + test + + test + + + + false + + + + + + ---- + It pulls the latest plugin version. Replace `${native.maven.plugin.version}` with a specific version if you prefer. -The plugin discovers which JAR files it needs to pass to the -`native-image` builder and what the executable main class should be. -With this plugin you can already build a native executable directly with Maven by running `mvn -Pnative package` (if your application does not call any methods reflectively at run time). +The plugin discovers which JAR files it needs to pass to the `native-image` builder and what the executable main class +should be. With this plugin you can already build a native executable directly with Maven by running +`mvn -Pnative package` (if your application does not call any methods reflectively at run time). + -This demo application is a little more complicated than `HelloWorld`, and requires metadata before building a native executable. You do not have to configure anything manually: the plugin can generate the required metadata for you by injecting the https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#agent-support[tracing -agent] at package time. -The agent is disabled by default, and can be enabled in project's _pom.xml_ file or via the command line. +This demo application is a little more complicated than `HelloWorld`, and requires metadata before building a native +executable. You do not have to configure anything manually as the plugin can generate the required metadata for you by +injecting the https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#agent-support[tracing agent] at +package time. The agent is disabled by default, and can be enabled in project's _pom.xml_ file or via the command line. -- To enable the agent via the _pom.xml_ file, specify `true` in the `native-maven-plugin` plugin configuration: +- To enable the agent via the _pom.xml_ file, specify `true` in the `native-maven-plugin` plugin +configuration: + [source,xml] ---- - - - true - - + + false + + true + + ---- -- To enable the agent via the command line, pass the `-Dagent=true` option when running Maven. -+ +- To enable the agent via the command line, pass the `-Dagent=true` option when running Maven. ++ So your next step is to run with the agent. -. Before running with the agent, register a separate Mojo execution in the `native` profile which allows forking the Java process. -It is required to run your application with the agent. +. Before running with the agent, register a separate Mojo execution in the `native` profile which allows forking the +Java process. It is required to run your application with the agent. + [source,xml] ---- - - org.codehaus.mojo - exec-maven-plugin - 3.0.0 - - - java-agent - - exec - - - java - ${project.build.directory} - - -classpath - - ${mainClass} - - - - - native - - exec - - - ${project.build.directory}/${imageName} - ${project.build.directory} - - - - + + org.codehaus.mojo + exec-maven-plugin + 3.1.1 + + + java-agent + + exec + + + java + ${project.build.directory} + + -classpath + + ${mainClass} + + + + + native + + exec + + + ${project.build.directory}/${imageName} + ${project.build.directory} + + + + ---- + Now you are all set to to build a native executable from a Java application the plugin. @@ -340,7 +390,7 @@ mvn clean package mvn -Pnative -Dagent exec:exec@java-agent ---- + -The agent collects the metadata and generates the configuration files in a subdirectory of `target/native/agent-output`. +The agent collects the metadata and generates the configuration files in a subdirectory of _target/native/agent-output_. Those files will be automatically used by the `native-image` tool if you pass the appropriate options. . Now build a native executable with the Maven profile: + @@ -349,16 +399,21 @@ Those files will be automatically used by the `native-image` tool if you pass th mvn -DskipTests=true -Pnative -Dagent package ---- + -When the command completes a native executable, _fortune_, is created in the _/target_ directory of the project and ready for use. +When the command completes a native executable, _fortune_, is created in the _target_ directory of the project and +ready for use. + -The executable's name is derived from the artifact ID, but you can specify any custom name in `native-maven-plugin` within a -`` node: +The executable's name is derived from the artifact ID, but you can specify any custom name in `native-maven-plugin` +by providing the `fortuneteller` within a `` node: + [source,xml] ---- - - fortuneteller - + + false + fortuneteller + + true + + ---- . Run the demo directly or with the Maven profile: + @@ -372,8 +427,8 @@ The executable's name is derived from the artifact ID, but you can specify any c mvn -Pnative exec:exec@native ---- -To see the benefits of running your application as a native executable, `time` how long it takes and compare the results with running on the -JVM. +To see the benefits of running your application as a native executable, `time` how long it takes and compare the results +with running on the JVM. == Add JUnit Testing @@ -381,36 +436,38 @@ The Maven plugin for GraalVM Native Image can run https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] tests on a native executable. This means that tests will be compiled and executed as native code. -This plugin requires JUnit Platform 1.8 or higher and Maven Surefire 2.22.0 or higher to run tests on a native executable. +This plugin requires JUnit Platform 1.10 or higher and Maven Surefire 2.22.0 or higher to run tests on a native +executable. . Enable extensions in the plugin's configuration, `true`: + [source,xml] ---- - - org.graalvm.buildtools - native-maven-plugin - ${native.maven.plugin.version} - true + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true ---- -. Add an explicit dependency on the `junit-platform-launcher` artifact to the dependencies section of your native profile configuration as in -the following example: +. Add an explicit dependency on the `junit-platform-launcher` artifact to the dependencies section of your native +profile configuration as in the following example: + [source,xml] ---- - - - org.junit.platform - junit-platform-launcher - 1.8.2 - test - - ----- -. Create the following test in the `src/test/java/demo/FortuneTest.java` file: + + native + + + org.junit.platform + junit-platform-launcher + 1.10.0 + test + + +---- +. Create the following test in the _src/test/java/demo/FortuneTest.java_ file: + -.src/test/java/demo/FortuneTest.java [source,java] ---- package demo; @@ -419,14 +476,14 @@ import com.fasterxml.jackson.core.JsonProcessingException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; class FortuneTest { @Test @DisplayName("Returns a fortune") void testItWorks() throws JsonProcessingException { Fortune fortune = new Fortune(); - assertTrue(fortune.randomFortune().length()>0); + assertFalse(fortune.randomFortune().isEmpty()); } } ---- @@ -435,10 +492,11 @@ class FortuneTest { + [source,shell] ---- -mvn -Pnative test +mvn -Pnative -Dagent test ---- + -Run `-Pnative` profile will then build and run native tests. +Run `-Pnative` profile will then build and run native tests. Include the `-Dagent` is this is not enabled in the +_pom.xml_ file. === Summary