This is an automated email from the ASF dual-hosted git repository. ddekany pushed a commit to branch 2.3-gae in repository https://gitbox.apache.org/repos/asf/freemarker.git
commit 2cce3b5663d96a466904ef4c86cf9f2f19d1de83 Author: ddekany <[email protected]> AuthorDate: Thu Nov 13 18:25:44 2025 +0100 GraalVM native PR followup: Refactored example project: - Better practices in the Gradle build - Made java code more trivial, so it's easier to understand - README reworked to be more straightforward. Removed step to build FreeMarker itself (as Gradle will do that automatically anyway) - Use flth for HTML generation (more secure) --- freemarker-test-graalvm-native/README.md | 76 ++++++++++------------ freemarker-test-graalvm-native/build.gradle.kts | 19 ++++-- .../src/main/config/reflect-config.json | 9 --- .../main/graalvm-native-config/reflect-config.json | 6 ++ .../org/freemarker/core/graal/HelloFreeMarker.java | 30 +++++++-- .../org/freemarker/core/graal/HelloHandler.java | 68 ------------------- .../hello-world.ftl => templates/hello-world.ftlh} | 6 +- 7 files changed, 83 insertions(+), 131 deletions(-) diff --git a/freemarker-test-graalvm-native/README.md b/freemarker-test-graalvm-native/README.md index 269045cc..d1e9ce98 100644 --- a/freemarker-test-graalvm-native/README.md +++ b/freemarker-test-graalvm-native/README.md @@ -1,48 +1,44 @@ # freemarker-test-graalvm-natice -Test project for GraalVM support - -Requirements : - -- GraalVM 21+ +Test project for GraalVM support. This is not built by default. ## Quickstart -1. Build the main Apache FreeMarker proejct : - -```shell -./gradlew "-Pfreemarker.signMethod=none" "-Pfreemarker.allowUnsignedReleaseBuild=true" clean build -``` - -2. Build the test module native image with GraalVM : - -```shell -./gradlew :freemarker-test-graalvm-native:nativeCompile -``` - -3. Run the project : - -```shell -./freemarker-test-graalvm-native/build/native/nativeCompile/freemarker-test-graalvm-native -``` - -Output should be similar to : - -```txt -INFO: name : FreeMarker Native Demo, version : 2.3.35-nightly -Jan 15, 2025 4:28:19 PM freemarker.log._JULLoggerFactory$JULLogger info -INFO: result : -<html> - <head> - <title>Hello : FreeMarker GraalVM Native Demo</title> - </head> - <body> - <h1>Hello : FreeMarker GraalVM Native Demo</h1> - <p>Test template for Apache FreeMarker GraalVM native support (2.3.35-nightly)</p> - </body> -</html> -``` +1. Download and install GraalVM 21+, if you haven't already. If it's installed to a non-standard location, also set the + `GRAALVM_HOME` environment variable (or the `JAVA_HOME`, if you use GraalVM by default anyway), otherwise the build + will fail! + +2. Build the test project native image: + + ```shell + ./gradlew :freemarker-test-graalvm-native:nativeCompile + ``` + +3. Run the native executable it has created: + + ```shell + ./freemarker-test-graalvm-native/build/native/nativeCompile/freemarker-test-graalvm-native + ``` + + Note: On Windows, use `\`-s instead of `/`-s in the executable path! + + The executable should output should be similar to : + + ```txt + INFO: name : FreeMarker Native Demo, version : 2.3.35-nightly + Jan 15, 2025 4:28:19 PM freemarker.log._JULLoggerFactory$JULLogger info + INFO: result : + <html> + <head> + <title>Hello : FreeMarker GraalVM Native Demo</title> + </head> + <body> + <h1>Hello : FreeMarker GraalVM Native Demo</h1> + <p>Test template for Apache FreeMarker GraalVM native support (2.3.35-nightly)</p> + </body> + </html> + ``` ## CI (GitHub workflow) -GraalVM native test for this module is included in the GitHub [CI](../.github/workflows/ci.yml) worflow. \ No newline at end of file +GraalVM native test for this module is included in the GitHub [CI](../.github/workflows/ci.yml) workflow. diff --git a/freemarker-test-graalvm-native/build.gradle.kts b/freemarker-test-graalvm-native/build.gradle.kts index ab3624ed..0e80fdef 100644 --- a/freemarker-test-graalvm-native/build.gradle.kts +++ b/freemarker-test-graalvm-native/build.gradle.kts @@ -1,6 +1,3 @@ -import org.graalvm.buildtools.gradle.tasks.BuildNativeImageTask -import java.util.Arrays - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -43,12 +40,21 @@ dependencies { } java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } withSourcesJar() withJavadocJar() } +tasks { + javadoc { + options { + (this as CoreJavadocOptions).addBooleanOption("Xdoclint:none", true) + } + } +} + application { mainClass.set("org.freemarker.core.graal.HelloFreeMarker") } @@ -64,8 +70,7 @@ graalvmNative { binaries.all { fallback.set(false) verbose.set(true) + configurationFileDirectories.from(file("src/main/graalvm-native-config")) resources.autodetect() - buildArgs.add( "-H:ReflectionConfigurationFiles=$projectDir/src/main/config/reflect-config.json" ) - jvmArgs() } } diff --git a/freemarker-test-graalvm-native/src/main/config/reflect-config.json b/freemarker-test-graalvm-native/src/main/config/reflect-config.json deleted file mode 100644 index f3f50664..00000000 --- a/freemarker-test-graalvm-native/src/main/config/reflect-config.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "name": "org.freemarker.core.graal.HelloDataModel", - "methods": [ - { "name": "getName", "parameterTypes": [] }, - { "name": "getVersion", "parameterTypes": [] } - ] - } -] \ No newline at end of file diff --git a/freemarker-test-graalvm-native/src/main/graalvm-native-config/reflect-config.json b/freemarker-test-graalvm-native/src/main/graalvm-native-config/reflect-config.json new file mode 100644 index 00000000..80342dff --- /dev/null +++ b/freemarker-test-graalvm-native/src/main/graalvm-native-config/reflect-config.json @@ -0,0 +1,6 @@ +[ + { + "name": "org.freemarker.core.graal.HelloDataModel", + "allPublicMethods": true + } +] \ No newline at end of file diff --git a/freemarker-test-graalvm-native/src/main/java/org/freemarker/core/graal/HelloFreeMarker.java b/freemarker-test-graalvm-native/src/main/java/org/freemarker/core/graal/HelloFreeMarker.java index f35dc193..1d151a02 100644 --- a/freemarker-test-graalvm-native/src/main/java/org/freemarker/core/graal/HelloFreeMarker.java +++ b/freemarker-test-graalvm-native/src/main/java/org/freemarker/core/graal/HelloFreeMarker.java @@ -19,15 +19,37 @@ package org.freemarker.core.graal; +import java.io.StringWriter; + import freemarker.log.Logger; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.Version; public class HelloFreeMarker { - + // To test freemarker.log.Logger under GraalVM native private final static Logger log = Logger.getLogger(HelloFreeMarker.class.getName()); - public static void main( String[] args ) throws Exception { - HelloHandler helloHandler = new HelloHandler(); - helloHandler.sayHello(); + public static void main(String[] args) throws Exception { + // To test native configuration + Class.forName("freemarker.ext.jython.JythonModel"); + + try (StringWriter buffer = new StringWriter()) { + // Creates FreeMarker configuration + Version version = new Version(Configuration.getVersion().toString()); // using latest version + Configuration cfg = new Configuration(version); + cfg.setClassForTemplateLoading(HelloDataModel.class, "/templates"); + + // Creates dataModel model + HelloDataModel dataModel = new HelloDataModel(); + dataModel.setName("FreeMarker GraalVM Native Demo"); + dataModel.setVersion(version.toString()); + + // Process template + Template template = cfg.getTemplate("hello-world.ftlh"); + template.process(dataModel, buffer); + log.info(String.format("result :\n%s", buffer)); + } } } diff --git a/freemarker-test-graalvm-native/src/main/java/org/freemarker/core/graal/HelloHandler.java b/freemarker-test-graalvm-native/src/main/java/org/freemarker/core/graal/HelloHandler.java deleted file mode 100644 index 2cd7271c..00000000 --- a/freemarker-test-graalvm-native/src/main/java/org/freemarker/core/graal/HelloHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.freemarker.core.graal; - -import freemarker.log.Logger; -import freemarker.template.Configuration; -import freemarker.template.Template; -import freemarker.template.Version; - -import java.io.StringWriter; -import java.util.HashMap; -import java.util.Map; - -/** - * Simple test class, able to say hello. - */ -public class HelloHandler { - - private final static Logger log = Logger.getLogger(HelloHandler.class.getName()); - - public HelloHandler() throws ClassNotFoundException { - // test native configuration - Class.forName("freemarker.ext.jython.JythonModel"); - } - - /** - * This method will say hello by printing an Apache FreeMarker template - * - * @throws Exception if any unexpected situation occurs - */ - public void sayHello() throws Exception { - try (StringWriter buffer = new StringWriter()) { - Version version = new Version(Configuration.getVersion().toString()); // using latest version - // creates FreeMarker configuration - Configuration cfg = new Configuration( version ); - cfg.setClassForTemplateLoading(HelloDataModel.class, "/freemarker-templates/"); - // creates data model - HelloDataModel data = new HelloDataModel(); - data.setName( "FreeMarker GraalVM Native Demo" ); - data.setVersion( version.toString() ); - log.info( String.format( "name : %s, version : %s", data.getName(), data.getVersion() ) ); - Map<String, Object> input = new HashMap<>(); - input.put( "data", data ); - // process template - Template template = cfg.getTemplate( "hello-world.ftl" ); - template.process( input, buffer ); - log.info( String.format( "result :\n%s", buffer ) ); - } - } - -} diff --git a/freemarker-test-graalvm-native/src/main/resources/freemarker-templates/hello-world.ftl b/freemarker-test-graalvm-native/src/main/resources/templates/hello-world.ftlh similarity index 88% rename from freemarker-test-graalvm-native/src/main/resources/freemarker-templates/hello-world.ftl rename to freemarker-test-graalvm-native/src/main/resources/templates/hello-world.ftlh index 31cd70d1..3d9eb17a 100644 --- a/freemarker-test-graalvm-native/src/main/resources/freemarker-templates/hello-world.ftl +++ b/freemarker-test-graalvm-native/src/main/resources/templates/hello-world.ftlh @@ -18,10 +18,10 @@ --> <html> <head> - <title>Hello : ${data.name}</title> + <title>Hello : ${name}</title> </head> <body> - <h1>Hello : ${data.name}</h1> - <p>Test template for Apache FreeMarker GraalVM native support (${data.version})</p> + <h1>Hello : ${name}</h1> + <p>Test template for Apache FreeMarker GraalVM native support (${version})</p> </body> </html> \ No newline at end of file
