├── .github ├── scripts │ ├── check-snippets.py │ └── requirements.txt └── workflows │ ├── espresso-continuations.yml │ ├── graaljs-maven-webpack-guide.yml │ ├── graaljs-starter.yml │ ├── graalpy-check-snippets.yml │ ├── graalpy-custom-venv-guide.yml │ ├── graalpy-freeze-dependencies-guide.yml │ ├── graalpy-javase-guide.yml │ ├── graalpy-jbang-qrcode.yml │ ├── graalpy-jython-guide.yml │ ├── graalpy-micronaut-guide.yml │ ├── graalpy-micronaut-multithreaded.yml │ ├── graalpy-micronaut-pygal-charts.yml │ ├── graalpy-native-extensions-guide.yml │ ├── graalpy-openai-starter.yml │ ├── graalpy-script-debug.yml │ ├── graalpy-spring-boot-guide.yml │ ├── graalpy-spring-boot-pygal-charts.yml │ ├── graalpy-starter.yml │ ├── graalwasm-embed-c-code-guide.yml │ ├── graalwasm-micronaut-photon.yml │ ├── graalwasm-spring-boot-photon.yml │ └── graalwasm-starter.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── espresso ├── README.md └── espresso-continuations │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ └── main │ └── java │ └── com │ └── example │ ├── MyJavaSerializer.java │ ├── MyKryoSerializer.java │ └── PersistentApp.java ├── graaljs ├── README.md ├── graaljs-maven-webpack-guide │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ ├── App.java │ │ │ ├── Promise.java │ │ │ ├── QRCode.java │ │ │ └── ValueConsumer.java │ │ └── js │ │ ├── .babelrc │ │ ├── main.mjs │ │ ├── package-lock.json │ │ ├── package.json │ │ └── webpack.config.js └── graaljs-starter │ ├── .gitattributes │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties │ ├── README.md │ ├── build.gradle.kts │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── settings.gradle.kts │ └── src │ ├── main │ └── java │ │ └── com │ │ └── example │ │ └── App.java │ └── test │ └── java │ └── com │ └── example │ └── AppTest.java ├── graalpy ├── README.md ├── graalpy-custom-venv-guide │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── example │ │ └── App.java ├── graalpy-freeze-dependencies-guide │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── settings.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── example │ │ └── App.java ├── graalpy-javase-guide │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── screenshot.png │ ├── settings.gradle.kts │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── example │ │ │ ├── App.java │ │ │ ├── GraalPy.java │ │ │ ├── IO.java │ │ │ └── QRCode.java │ │ └── resources │ │ └── META-INF │ │ └── MANIFEST.MF ├── graalpy-jbang-qrcode │ ├── README.md │ └── qrcode.java ├── graalpy-jython-guide │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── screenshot.png │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── example │ │ ├── App.java │ │ ├── EchoInputCallback.java │ │ ├── GraalPyInputCallback.java │ │ ├── InputCallback.java │ │ ├── JythonInputCallback.java │ │ └── Workspace.java ├── graalpy-micronaut-guide │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── aot-jar.properties │ ├── build.gradle.kts │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── micronaut-cli.yml │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── screenshot.png │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── example │ │ │ │ ├── Application.java │ │ │ │ ├── GraalPyContext.java │ │ │ │ ├── SentimentAnalysis.java │ │ │ │ ├── SentimentAnalysisController.java │ │ │ │ └── SentimentIntensityAnalyzer.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── native-image │ │ │ │ └── proxy-config.json │ │ │ ├── application.properties │ │ │ ├── logback.xml │ │ │ └── views │ │ │ └── index.html │ │ └── test │ │ └── java │ │ └── org │ │ └── example │ │ └── SentimentAnalysisControllerTest.java ├── graalpy-micronaut-multithreaded │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── aot-jar.properties │ ├── build.gradle.kts │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── js-modules-by-version-testcount-passingrate.csv │ ├── micronaut-cli.yml │ ├── mvnw │ ├── mvnw.bat │ ├── mvnw.cmd │ ├── pom.xml │ ├── python-modules-by-version-testcount-passingrate.csv │ ├── scaling-dark.png │ ├── scaling-light.png │ ├── screenshot.png │ ├── settings.gradle.kts │ └── src │ │ └── main │ │ ├── java │ │ └── graalpy │ │ │ └── micronaut │ │ │ └── multithreaded │ │ │ ├── Application.java │ │ │ ├── DataAnalysisController.java │ │ │ └── PythonPool.java │ │ └── resources │ │ ├── application.properties │ │ ├── logback.xml │ │ ├── org.graalvm.python.vfs │ │ └── src │ │ │ └── data_analysis.py │ │ └── views │ │ └── index.html ├── graalpy-micronaut-pygal-charts │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── aot-jar.properties │ ├── micronaut-cli.yml │ ├── mvnw │ ├── mvnw.bat │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ ├── Application.java │ │ │ │ ├── DemoController.java │ │ │ │ ├── GraalPyContext.java │ │ │ │ ├── PyGalService.java │ │ │ │ ├── PyGalServiceMixed.java │ │ │ │ ├── PyGalServicePureJava.java │ │ │ │ ├── PyGalServicePurePython.java │ │ │ │ └── PyGalServiceValueAPIDynamic.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── native-image │ │ │ │ └── com.example │ │ │ │ └── demo │ │ │ │ └── reachability-metadata.json │ │ │ ├── application.properties │ │ │ └── logback.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── DemoTest.java ├── graalpy-native-extensions-guide │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── example │ │ ├── App.java │ │ ├── AppLogging.java │ │ └── MultiContextApp.java ├── graalpy-openai-starter │ ├── .gitattributes │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── build.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── settings.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── App.java │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── AppTest.java ├── graalpy-scripts-debug-guide │ ├── .gitattributes │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── .vscode │ │ ├── extensions.json │ │ └── launch.json │ ├── README.md │ ├── build.gradle.kts │ ├── graalpy-vscode-dap-debug.gif │ ├── graalpy-vscode-debug.gif │ ├── graalpy-vscode-pip-install.gif │ ├── graalpy-vscode-pyenv.gif │ ├── graalpy-vscode-select.gif │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── screenshot.png │ ├── settings.gradle.kts │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── App.java │ │ └── resources │ │ └── compare_files.py ├── graalpy-spring-boot-guide │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── screenshot.png │ ├── settings.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── demo │ │ │ │ ├── DemoApplication.java │ │ │ │ ├── DemoController.java │ │ │ │ ├── GraalPyContext.java │ │ │ │ ├── SentimentAnalysisService.java │ │ │ │ └── SentimentIntensityAnalyzer.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── native-image │ │ │ │ └── proxy-config.json │ │ │ ├── application.properties │ │ │ └── templates │ │ │ └── index.html │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── demo │ │ └── DemoApplicationTests.java ├── graalpy-spring-boot-pygal-charts │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── demo │ │ │ │ ├── DemoApplication.java │ │ │ │ ├── DemoController.java │ │ │ │ ├── GraalPyContextConfiguration.java │ │ │ │ ├── PyGalService.java │ │ │ │ ├── PyGalServiceMixed.java │ │ │ │ ├── PyGalServicePureJava.java │ │ │ │ ├── PyGalServicePurePython.java │ │ │ │ └── PyGalServiceValueAPIDynamic.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── native-image │ │ │ │ └── com.example │ │ │ │ └── demo │ │ │ │ └── reachability-metadata.json │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── demo │ │ └── DemoApplicationTests.java └── graalpy-starter │ ├── .gitattributes │ ├── .gitignore │ ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties │ ├── README.md │ ├── build.gradle.kts │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ ├── settings.gradle.kts │ └── src │ ├── main │ └── java │ │ └── com │ │ └── example │ │ └── App.java │ └── test │ └── java │ └── com │ └── example │ └── AppTest.java └── graalwasm ├── README.md ├── graalwasm-embed-c-code-guide ├── .gitignore ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── c │ │ └── floyd.c │ └── java │ │ └── com │ │ └── example │ │ └── App.java │ └── test │ └── java │ └── com │ └── example │ └── AppTest.java ├── graalwasm-micronaut-photon ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties ├── README.md ├── aot-jar.properties ├── micronaut-cli.yml ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ ├── Application.java │ │ │ ├── DemoController.java │ │ │ ├── Photon.java │ │ │ ├── PhotonPool.java │ │ │ └── PhotonService.java │ └── resources │ │ ├── META-INF │ │ └── native-image │ │ │ └── com.example │ │ │ └── demo │ │ │ └── proxy-config.json │ │ ├── application.properties │ │ ├── logback.xml │ │ └── static │ │ └── index.html │ └── test │ └── java │ └── com │ └── example │ └── DemoTest.java ├── graalwasm-spring-boot-photon ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.java │ │ │ ├── DemoController.java │ │ │ ├── Photon.java │ │ │ ├── PhotonPool.java │ │ │ └── PhotonService.java │ └── resources │ │ ├── META-INF │ │ └── native-image │ │ │ └── org.example │ │ │ └── demo │ │ │ └── proxy-config.json │ │ └── application.properties │ └── test │ └── java │ └── com │ └── example │ └── demo │ └── DemoApplicationTests.java └── graalwasm-starter ├── .gitattributes ├── .gitignore ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── README.md ├── build.gradle.kts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mvnw ├── mvnw.cmd ├── pom.xml ├── settings.gradle.kts └── src ├── main ├── java │ └── com │ │ └── example │ │ └── App.java └── resources │ └── com │ └── example │ ├── add-two.wasm │ └── add-two.wat └── test └── java └── com └── example └── AppTest.java /.github/scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | marko 2 | -------------------------------------------------------------------------------- /.github/workflows/espresso-continuations.yml: -------------------------------------------------------------------------------- 1 | name: Test Espresso Continuations 2 | on: 3 | push: 4 | paths: 5 | - 'espresso/espresso-continuations/**' 6 | - '.github/workflows/espresso-continuations.yml' 7 | pull_request: 8 | paths: 9 | - 'espresso/espresso-continuations/**' 10 | - '.github/workflows/espresso-continuations.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'espresso-continuations' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - name: Download Espresso 22 | run: curl -sL -o $RUNNER_TEMP/espresso-linux-amd64.tar.gz https://gds.oracle.com/download/espresso/archive/espresso-java21-24.2.0-linux-amd64.tar.gz 23 | - uses: actions/setup-java@v4 24 | with: 25 | java-version: '21' 26 | distribution: 'jdkfile' 27 | jdkFile: ${{ runner.temp }}/espresso-linux-amd64.tar.gz 28 | - name: Build and run 'espresso-continuations' using Maven 29 | run: | 30 | cd espresso/espresso-continuations 31 | ./mvnw --no-transfer-progress package 32 | $JAVA_HOME/bin/java --experimental-options --java.Continuum=true -jar target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar 33 | ls -lisa state.serial.bin 34 | $JAVA_HOME/bin/java --experimental-options --java.Continuum=true -jar target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar 35 | rm state.serial.bin 36 | $JAVA_HOME/bin/java --experimental-options --java.Continuum=true -jar target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar -s kryo 37 | ls -lisa state.serial.bin 38 | $JAVA_HOME/bin/java --experimental-options --java.Continuum=true -jar target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar -s kryo 39 | -------------------------------------------------------------------------------- /.github/workflows/graaljs-maven-webpack-guide.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalJS Maven Webpack Guide 2 | on: 3 | push: 4 | paths: 5 | - 'graaljs/graaljs-maven-webpack-guide/**' 6 | - '.github/workflows/graaljs-maven-webpack-guide.yml' 7 | pull_request: 8 | paths: 9 | - 'graaljs/graaljs-maven-webpack-guide/**' 10 | - '.github/workflows/graaljs-maven-webpack-guide.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graaljs-maven-webpack-guide' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - name: Build and run 'graaljs-maven-webpack-guide' 28 | run: | 29 | cd graaljs/graaljs-maven-webpack-guide 30 | ./mvnw --no-transfer-progress package 31 | ./mvnw --no-transfer-progress exec:java -Dexec.mainClass=com.example.App -Dexec.args="https://www.graalvm.org/javascript" 32 | -------------------------------------------------------------------------------- /.github/workflows/graaljs-starter.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalJS Starter 2 | on: 3 | push: 4 | paths: 5 | - 'graaljs/graaljs-starter/**' 6 | - '.github/workflows/graaljs-starter.yml' 7 | pull_request: 8 | paths: 9 | - 'graaljs/graaljs-starter/**' 10 | - '.github/workflows/graaljs-starter.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graaljs-starter' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | native-image-job-reports: 'true' 28 | - name: Build, test, and run 'graaljs-starter' using Maven 29 | run: | 30 | cd graaljs/graaljs-starter 31 | ./mvnw --no-transfer-progress test 32 | ./mvnw --no-transfer-progress exec:java 33 | - name: Build, test, and run 'graaljs-starter' using Gradle 34 | run: | 35 | cd graaljs/graaljs-starter 36 | ./gradlew test 37 | ./gradlew run 38 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-check-snippets.yml: -------------------------------------------------------------------------------- 1 | name: Check Snippets in GraalPy Guides 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/**' 6 | - '.github/workflows/graalpy-check-snippets.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/**' 10 | - '.github/workflows/graalpy-check-snippets.yml' 11 | permissions: 12 | contents: read 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Set up Python 20 | uses: actions/setup-python@v5 21 | with: 22 | python-version: graalpy-24.1 23 | - name: Install dependencies 24 | run: | 25 | python -m pip install -r .github/scripts/requirements.txt 26 | - name: Check README snippets 27 | run: find graalpy -name "README.md" -exec python .github/scripts/check-snippets.py "{}" "+" 28 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-custom-venv-guide.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Custom Venv Guide 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-custom-venv-guide/**' 6 | - '.github/workflows/graalpy-custom-venv-guide.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-custom-venv-guide/**' 10 | - '.github/workflows/graalpy-custom-venv-guide.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-custom-venv-guide' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - uses: actions/setup-python@v5 28 | with: 29 | python-version: 'graalpy-24.1' 30 | - name: Build, test, and run 'graalpy-custom-venv-guide' using Maven 31 | shell: bash 32 | run: | 33 | cd graalpy/graalpy-custom-venv-guide 34 | ./mvnw --no-transfer-progress compile 35 | graalpy -m venv venv 36 | ./venv/bin/graalpy -m pip install art==6.3 37 | ./mvnw --no-transfer-progress exec:java -Dexec.mainClass=org.example.App -Dvenv=venv | tee /tmp/output 38 | grep -F " ____ _ ____" /tmp/output 39 | grep -F " / ___| _ __ __ _ __ _ | || _ \ _ _" /tmp/output 40 | # | | _ | '__| / _` | / _` || || |_) || | | | escaping is too cumbersome for this line 41 | grep -F "| |_| || | | (_| || (_| || || __/ | |_| |" /tmp/output 42 | grep -F " \____||_| \__,_| \__,_||_||_| \__, |" /tmp/output 43 | grep -F " |___/" /tmp/output -------------------------------------------------------------------------------- /.github/workflows/graalpy-freeze-dependencies-guide.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Freeze Dependencies Guide 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-freeze-dependencies-guide/**' 6 | - '.github/workflows/graalpy-freeze-dependencies-guide.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-freeze-dependencies-guide/**' 10 | - '.github/workflows/graalpy-freeze-dependencies-guide.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-freeze-dependencies-guide' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - name: Build, test, and run 'graalpy-freeze-dependencies-guide' using Maven 28 | shell: bash 29 | run: | 30 | cd graalpy/graalpy-freeze-dependencies-guide 31 | git clean -fdx 32 | ./mvnw --no-transfer-progress compile 33 | ./mvnw --no-transfer-progress exec:java -Dexec.mainClass=org.example.App | tee /tmp/output 34 | grep darent /tmp/output 35 | - name: Build, test, and run 'graalpy-freeze-dependencies-guide' using Gradle 36 | shell: bash 37 | run: | 38 | cd graalpy/graalpy-freeze-dependencies-guide 39 | git clean -fdx 40 | ./gradlew build 41 | ./gradlew run | tee /tmp/output 42 | grep darent /tmp/output 43 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-javase-guide.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Java SE Guide 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-javase-guide/**' 6 | - '.github/workflows/graalpy-javase-guide.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-javase-guide/**' 10 | - '.github/workflows/graalpy-javase-guide.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-javase-guide' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - name: Build, test, and run 'graalpy-javase-guide' using Maven 28 | run: | 29 | cd graalpy/graalpy-javase-guide 30 | ./mvnw --no-transfer-progress compile 31 | xvfb-run ./mvnw --no-transfer-progress exec:java -Dexec.mainClass=org.example.App -Dgraalpy.resources=./python-resources & 32 | sleep 20 33 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-jbang-qrcode.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy JBang QRCode Demo 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-jbang-qrcode/**' 6 | - '.github/workflows/graalpy-jbang-qrcode.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-jbang-qrcode/**' 10 | - '.github/workflows/graalpy-jbang-qrcode.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-jbang-qrcode' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | - name: Run 'graalpy-jbang-qrcode' demo 27 | run: | 28 | cd graalpy/graalpy-jbang-qrcode 29 | curl -Ls https://sh.jbang.dev | bash -s - run qrcode.java "Hello from GraalPy!" 30 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-jython-guide.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Jython Guide 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-jython-guide/**' 6 | - '.github/workflows/graalpy-jython-guide.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-jython-guide/**' 10 | - '.github/workflows/graalpy-jython-guide.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-jython-guide' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - name: Build, test, and run 'graalpy-jython-guide' using Maven 28 | run: | 29 | cd graalpy/graalpy-jython-guide 30 | ./mvnw --no-transfer-progress compile 31 | xvfb-run ./mvnw --no-transfer-progress exec:java -Dexec.mainClass=org.example.App & 32 | sleep 20 33 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-micronaut-pygal-charts.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Micronaut Pygal Charts 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-micronaut-pygal-charts/**' 6 | - '.github/workflows/graalpy-micronaut-pygal-charts.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-micronaut-pygal-charts/**' 10 | - '.github/workflows/graalpy-micronaut-pygal-charts.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | env: 15 | NATIVE_IMAGE_OPTIONS: '-J-Xmx16g' 16 | jobs: 17 | run: 18 | name: 'graalpy-micronaut-pygal-charts' 19 | runs-on: ubuntu-latest 20 | timeout-minutes: 30 21 | steps: 22 | - uses: actions/checkout@v4 23 | - uses: graalvm/setup-graalvm@v1 24 | with: 25 | java-version: '24.0.0' 26 | distribution: 'graalvm' 27 | github-token: ${{ secrets.GITHUB_TOKEN }} 28 | cache: 'maven' 29 | native-image-job-reports: 'true' 30 | - name: Build, test, and run 'graalpy-micronaut-pygal-charts' using Maven 31 | run: | 32 | cd graalpy/graalpy-micronaut-pygal-charts 33 | ./mvnw --no-transfer-progress clean test -Dmicronaut.http.client.read-timeout=1m 34 | ./mvnw --no-transfer-progress mn:run & 35 | mnpid="$!" 36 | sleep 30 37 | curl --fail-with-body --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/java 38 | kill $mnpid 39 | - name: Build and run native 'graalpy-micronaut-pygal-charts' using Maven 40 | run: | 41 | cd graalpy/graalpy-micronaut-pygal-charts 42 | ./mvnw --no-transfer-progress clean package -DskipTests -Dpackaging=native-image 43 | ./target/demo & 44 | mnpid="$!" 45 | sleep 20 46 | curl --fail-with-body --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/python 47 | kill $mnpid 48 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-native-extensions-guide.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Native Extensions Guide 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-native-extensions-guide/**' 6 | - '.github/workflows/graalpy-native-extensions-guide.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-native-extensions-guide/**' 10 | - '.github/workflows/graalpy-native-extensions-guide.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-native-extensions-guide' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - name: Build, test, and run 'graalpy-native-extensions-guide' using Maven 28 | shell: bash 29 | run: | 30 | cd graalpy/graalpy-native-extensions-guide 31 | ./mvnw --no-transfer-progress compile 32 | ./mvnw --no-transfer-progress exec:java -Dexec.mainClass=org.example.App -Dexec.args="appkle pear anana tomato" | tee /tmp/output 33 | grep "did you mean 'apple'" /tmp/output 34 | ./mvnw --no-transfer-progress exec:java -Dexec.mainClass=org.example.AppLogging -Dexec.args="appkle pear anana tomato" 2>&1 | tee /tmp/output2 35 | grep "Loading C extension module polyleven" /tmp/output2 36 | grep "did you mean 'apple'" /tmp/output2 37 | if mvn package exec:java -Dexec.mainClass=org.example.MultiContextApp -Dexec.args="appkle pear anana strawberry tomato" 2>&1 | tee /tmp/output3; then 38 | echo "the command was supposed to fail" 39 | exit 1 40 | fi 41 | grep "did you mean 'apple'" /tmp/output3 42 | grep "SystemError" /tmp/output3 -------------------------------------------------------------------------------- /.github/workflows/graalpy-openai-starter.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy OpenAI Starter 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-openai-starter/**' 6 | - '.github/workflows/graalpy-openai-starter.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-openai-starter/**' 10 | - '.github/workflows/graalpy-openai-starter.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-openai-starter' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - name: Build, test, and run 'graalpy-openai-starter' using Maven 28 | run: | 29 | cd graalpy/graalpy-openai-starter 30 | ./mvnw --no-transfer-progress test 31 | ./mvnw --no-transfer-progress exec:java || true 32 | - name: Build, test, and run 'graalpy-openai-starter' using Gradle 33 | run: | 34 | cd graalpy/graalpy-openai-starter 35 | ./gradlew test 36 | ./gradlew run || true 37 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-script-debug.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Scripts Guide 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-scripts-debug/**' 6 | - '.github/workflows/graalpy-scripts-debug.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-scripts-debug/**' 10 | - '.github/workflows/graalpy-scripts-debug.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-scripts-debug' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - name: Build, test, and run 'graalpy-scripts-debug' using Maven 28 | run: | 29 | cd graalpy/graalpy-scripts-debug 30 | ./mvnw --no-transfer-progress test 31 | - name: Build, test, and run 'graalpy-scripts-debug' using Gradle 32 | run: | 33 | cd graalpy/graalpy-scripts-debug 34 | ./gradlew test 35 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-spring-boot-pygal-charts.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Spring Pygal Charts 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-spring-boot-pygal-charts/**' 6 | - '.github/workflows/graalpy-spring-boot-pygal-charts.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-spring-boot-pygal-charts/**' 10 | - '.github/workflows/graalpy-spring-boot-pygal-charts.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | env: 15 | NATIVE_IMAGE_OPTIONS: '-J-Xmx16g' 16 | jobs: 17 | run: 18 | name: 'graalpy-spring-boot-pygal-charts' 19 | runs-on: ubuntu-latest 20 | timeout-minutes: 30 21 | steps: 22 | - uses: actions/checkout@v4 23 | - uses: graalvm/setup-graalvm@v1 24 | with: 25 | java-version: '24.0.0' 26 | distribution: 'graalvm' 27 | github-token: ${{ secrets.GITHUB_TOKEN }} 28 | cache: 'maven' 29 | native-image-job-reports: 'true' 30 | - name: Build, test, and run 'graalpy-spring-boot-pygal-charts' using Maven 31 | run: | 32 | cd graalpy/graalpy-spring-boot-pygal-charts 33 | ./mvnw --no-transfer-progress clean test -Dspring.mvc.async.request-timeout=60000 34 | ./mvnw --no-transfer-progress spring-boot:run & 35 | sbpid="$!" 36 | sleep 30 37 | curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/java 38 | kill $sbpid 39 | - name: Build and run native 'graalpy-spring-boot-pygal-charts' using Maven 40 | run: | 41 | cd graalpy/graalpy-spring-boot-pygal-charts 42 | ./mvnw --no-transfer-progress clean -DskipTests -Pnative native:compile 43 | ./target/demo & 44 | sbpid="$!" 45 | sleep 20 46 | curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/python 47 | kill $sbpid 48 | -------------------------------------------------------------------------------- /.github/workflows/graalpy-starter.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalPy Starter 2 | on: 3 | push: 4 | paths: 5 | - 'graalpy/graalpy-starter/**' 6 | - '.github/workflows/graalpy-starter.yml' 7 | pull_request: 8 | paths: 9 | - 'graalpy/graalpy-starter/**' 10 | - '.github/workflows/graalpy-starter.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalpy-starter' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | - name: Build, test, and run 'graalpy-starter' using Maven 28 | run: | 29 | cd graalpy/graalpy-starter 30 | ./mvnw --no-transfer-progress test 31 | ./mvnw --no-transfer-progress exec:java 32 | - name: Build, test, and run 'graalpy-starter' using Gradle 33 | run: | 34 | cd graalpy/graalpy-starter 35 | ./gradlew test 36 | ./gradlew run 37 | -------------------------------------------------------------------------------- /.github/workflows/graalwasm-embed-c-code-guide.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalWasm Embed C in Java Guide 2 | on: 3 | push: 4 | paths: 5 | - 'graalwasm/graalwasm-embed-c-code-guide/**' 6 | - '.github/workflows/graalwasm-embed-c-code-guide.yml' 7 | pull_request: 8 | paths: 9 | - 'graalwasm/graalwasm-embed-c-code-guide/**' 10 | - '.github/workflows/graalwasm-embed-c-code-guide.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalwasm-embed-c-code-guide' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - name: Checkout emscripten-core/emsdk 22 | uses: actions/checkout@v4 23 | with: 24 | repository: emscripten-core/emsdk 25 | path: emsdk 26 | - name: Install and activate latest emsdk 27 | run: | 28 | cd emsdk 29 | ./emsdk install latest 30 | ./emsdk activate latest 31 | - uses: graalvm/setup-graalvm@v1 32 | with: 33 | java-version: '24.0.0' 34 | distribution: 'graalvm' 35 | github-token: ${{ secrets.GITHUB_TOKEN }} 36 | cache: 'maven' 37 | - name: Build, test, and run 'graalwasm-embed-c-code-guide' 38 | run: | 39 | source ./emsdk/emsdk_env.sh 40 | cd graalwasm/graalwasm-embed-c-code-guide 41 | ./mvnw --no-transfer-progress package 42 | ./mvnw --no-transfer-progress exec:java 43 | -------------------------------------------------------------------------------- /.github/workflows/graalwasm-micronaut-photon.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalWasm Micronaut Photon Demo 2 | on: 3 | push: 4 | paths: 5 | - 'graalwasm/graalwasm-micronaut-photon/**' 6 | - '.github/workflows/graalwasm-micronaut-photon.yml' 7 | pull_request: 8 | paths: 9 | - 'graalwasm/graalwasm-micronaut-photon/**' 10 | - '.github/workflows/graalwasm-micronaut-photon.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalwasm-micronaut-photon' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 30 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | native-image-job-reports: 'true' 28 | - name: Package 'graalwasm-micronaut-photon' 29 | run: | 30 | cd graalwasm/graalwasm-micronaut-photon 31 | ./mvnw --no-transfer-progress clean package 32 | - name: Build native 'graalwasm-micronaut-photon' 33 | run: | 34 | cd graalwasm/graalwasm-micronaut-photon 35 | ./mvnw --no-transfer-progress clean package -Dpackaging=native-image 36 | ./target/demo & 37 | sleep 10 38 | curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/photo/flipv 39 | -------------------------------------------------------------------------------- /.github/workflows/graalwasm-spring-boot-photon.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalWasm Spring Boot Photon Demo 2 | on: 3 | push: 4 | paths: 5 | - 'graalwasm/graalwasm-spring-boot-photon/**' 6 | - '.github/workflows/graalwasm-spring-boot-photon.yml' 7 | pull_request: 8 | paths: 9 | - 'graalwasm/graalwasm-spring-boot-photon/**' 10 | - '.github/workflows/graalwasm-spring-boot-photon.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalwasm-spring-boot-photon' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 30 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | native-image-job-reports: 'true' 28 | - name: Package 'graalwasm-spring-boot-photon' 29 | run: | 30 | cd graalwasm/graalwasm-spring-boot-photon 31 | ./mvnw --no-transfer-progress clean package 32 | - name: Build native 'graalwasm-spring-boot-photon' 33 | run: | 34 | cd graalwasm/graalwasm-spring-boot-photon 35 | ./mvnw --no-transfer-progress clean -Pnative native:compile 36 | ./target/demo & 37 | sleep 10 38 | curl --fail-with-body --silent --dump-header - -o /dev/null http://localhost:8080/photo/flipv 39 | -------------------------------------------------------------------------------- /.github/workflows/graalwasm-starter.yml: -------------------------------------------------------------------------------- 1 | name: Test GraalWasm Starter 2 | on: 3 | push: 4 | paths: 5 | - 'graalwasm/graalwasm-starter/**' 6 | - '.github/workflows/graalwasm-starter.yml' 7 | pull_request: 8 | paths: 9 | - 'graalwasm/graalwasm-starter/**' 10 | - '.github/workflows/graalwasm-starter.yml' 11 | workflow_dispatch: 12 | permissions: 13 | contents: read 14 | jobs: 15 | run: 16 | name: 'graalwasm-starter' 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 15 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: graalvm/setup-graalvm@v1 22 | with: 23 | java-version: '24.0.0' 24 | distribution: 'graalvm' 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | cache: 'maven' 27 | native-image-job-reports: 'true' 28 | - name: Build, test, and run 'graalwasm-starter' using Maven 29 | run: | 30 | cd graalwasm/graalwasm-starter 31 | ./mvnw --no-transfer-progress test 32 | ./mvnw --no-transfer-progress exec:java 33 | - name: Build, test, and run 'graalwasm-starter' using Gradle 34 | run: | 35 | cd graalwasm/graalwasm-starter 36 | ./gradlew test 37 | ./gradlew run 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .DS_Store 3 | .factorypath 4 | .gradle 5 | .idea 6 | .project 7 | .settings 8 | *.iml 9 | *.ipr 10 | *.iprof 11 | *.iws 12 | build/ 13 | out/ 14 | bin/ 15 | target/ 16 | node_modules/ 17 | Thumbs.db 18 | .sdkmanrc 19 | settings.json 20 | graalpy/graalpy-javase-guide/python-resources 21 | **/.mvn/wrapper/maven-wrapper.jar 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repository 2 | 3 | We welcome your contributions! There are multiple ways to contribute. 4 | 5 | ## Opening issues 6 | 7 | For bugs or enhancement requests, please file a GitHub issue unless it is 8 | security-related. When filing a bug remember that the better written the bug is, 9 | the more likely it is to be fixed. If you think you've found a security 10 | vulnerability, do not raise a GitHub issue and follow the instructions in our 11 | [security policy](./SECURITY.md). 12 | 13 | ## Contributing code 14 | 15 | We welcome your code contributions. Before submitting code via a pull request, 16 | you will need to have signed the [Oracle Contributor Agreement][OCA] (OCA) and 17 | your commits need to include the following line using the name and e-mail 18 | address you used to sign the OCA: 19 | 20 | ```text 21 | Signed-off-by: Your Name 22 | ``` 23 | 24 | This can be automatically added to pull requests by committing with `--sign-off` 25 | or `-s`, e.g. 26 | 27 | ```text 28 | git commit --signoff 29 | ``` 30 | 31 | Only pull requests from committers that can be verified as having signed the OCA 32 | can be accepted. 33 | 34 | ## Pull request process 35 | 36 | 1. Ensure there is an issue created to track and discuss the fix or enhancement 37 | you intend to submit. 38 | 1. Fork this repository. 39 | 1. Create a branch in your fork to implement the changes. We recommend using 40 | the issue number as part of your branch name, e.g. `1234-fixes`. 41 | 1. Ensure that any documentation is updated with the changes that are required 42 | by your change. 43 | 1. Ensure that any samples are updated if the base image has been changed. 44 | 1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly 45 | what your changes are meant to do and provide simple steps on how to validate 46 | your changes. Ensure that you reference the issue you created as well. 47 | 1. We will assign the pull request to 2-3 people for review before it is merged. 48 | 49 | ## Code of conduct 50 | 51 | Follow the [Golden Rule](https://en.wikipedia.org/wiki/Golden_Rule). If you'd 52 | like more specific guidelines, see the [Contributor Covenant Code of Conduct][COC]. 53 | 54 | [OCA]: https://oca.opensource.oracle.com 55 | [COC]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/ 56 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Oracle and/or its affiliates. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Graal Languages - Demos and Guides 2 | 3 | This repository contains demo applications and guides for [GraalJS](./graaljs), [GraalPy](./graalpy/), [GraalWasm](./graalwasm), and other Graal Languages. 4 | Each demo and guide includes a _README.md_ that explains how to run the application and how it works in more detail. 5 | 6 | ## Help 7 | 8 | If you need help with any of the demos or guides, please [file a GitHub issue](https://github.com/graalvm/graal-languages-demos/issues/new). 9 | 10 | ## Contributing 11 | 12 | This project welcomes contributions from the community. Before submitting a pull request, please [review our contribution guide](./CONTRIBUTING.md). 13 | 14 | ## Security 15 | 16 | Please consult the [security guide](./SECURITY.md) for our responsible security vulnerability disclosure process. 17 | 18 | ## License 19 | 20 | Copyright (c) 2024 Oracle and/or its affiliates. 21 | 22 | Released under the Universal Permissive License v1.0 as shown at 23 | . 24 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting security vulnerabilities 2 | 3 | Oracle values the independent security research community and believes that 4 | responsible disclosure of security vulnerabilities helps us ensure the security 5 | and privacy of all our users. 6 | 7 | Please do NOT file a GitHub issue to report a security vulnerability. If you 8 | believe you have found a security vulnerability, please submit a report to 9 | [secalert_us@oracle.com][1] preferably with a proof of concept. Please review 10 | some additional information on [how to report security vulnerabilities to Oracle][2]. 11 | We encourage people who contact Oracle Security to use email encryption using 12 | [our encryption key][3]. 13 | 14 | We ask that you do not use other channels or contact the project maintainers 15 | directly. 16 | 17 | Non-vulnerability-related security issues including ideas for new or improved 18 | security features are welcome on GitHub Issues. 19 | 20 | ## Security updates, alerts, and bulletins 21 | 22 | Security updates will be released on a regular cadence. Many of our projects 23 | will typically release security fixes in conjunction with the 24 | Oracle Critical Patch Update program. Additional 25 | information, including past advisories, is available on our [security alerts][4] 26 | page. 27 | 28 | ## Security-related information 29 | 30 | We will provide security-related information such as a threat model, considerations 31 | for secure use, or any known security issues in our documentation. Please note 32 | that labs and sample code are intended to demonstrate a concept and may not be 33 | sufficiently hardened for production use. 34 | 35 | [1]: mailto:secalert_us@oracle.com 36 | [2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html 37 | [3]: https://www.oracle.com/security-alerts/encryptionkey.html 38 | [4]: https://www.oracle.com/security-alerts/ 39 | -------------------------------------------------------------------------------- /espresso/README.md: -------------------------------------------------------------------------------- 1 | # Espresso Demos 2 | 3 | This directory contains demo applications for [Espresso](https://www.graalvm.org/reference-manual/java-on-truffle/). 4 | 5 | *Tip: open this directory in IntellIJ IDEA. It should offer to load all Maven projects.* 6 | 7 | ## Demos 8 | 9 | - [Suspend and resume Java applications using Espresso's Continuation API](espresso-continuations/) 10 | -------------------------------------------------------------------------------- /espresso/espresso-continuations/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore maven build output directory 2 | target 3 | 4 | # Ignore application state 5 | state.serial.bin 6 | -------------------------------------------------------------------------------- /espresso/espresso-continuations/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /espresso/espresso-continuations/README.md: -------------------------------------------------------------------------------- 1 | # Suspend and resume Java applications using Espresso's Continuation API 2 | 3 | This demo persists its state by saving it to a file. 4 | Each time it runs, the program increments a counter, displays the updated value, and then exits. 5 | 6 | ## Preparation 7 | 8 | Install [Espresso 24.2.0](https://www.graalvm.org/latest/reference-manual/espresso/) and set the value of `JAVA_HOME` accordingly. 9 | 10 | ## Run the Application 11 | 12 | To build the demo, run: 13 | 14 | ```bash 15 | ./mvnw package 16 | ``` 17 | 18 | To execute the main method, run: 19 | 20 | ```bash 21 | $JAVA_HOME/bin/java --experimental-options --java.Continuum=true \ 22 | -jar target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar 23 | ``` 24 | 25 | To use Kryo as serializer, use the `-s` application argument: 26 | 27 | ```bash 28 | $JAVA_HOME/bin/java --experimental-options --java.Continuum=true \ 29 | -jar target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar -s kryo 30 | ``` 31 | 32 | Note: the default Java and Kryo serializers are not compatible with each other. 33 | When switching between serializers, delete the _state.serial.bin_ file. 34 | -------------------------------------------------------------------------------- /espresso/espresso-continuations/src/main/java/com/example/MyJavaSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import static java.nio.file.StandardOpenOption.*; 10 | 11 | import java.io.IOException; 12 | import java.io.ObjectInputStream; 13 | import java.io.ObjectOutputStream; 14 | import java.nio.file.Files; 15 | import java.nio.file.Path; 16 | 17 | import org.graalvm.continuations.Continuation; 18 | 19 | class MyJavaSerializer implements PersistentApp.MySerializer { 20 | @Override 21 | public Continuation load(Path storagePath) throws IOException, ClassNotFoundException { 22 | try (var in = new ObjectInputStream(Files.newInputStream(storagePath, READ))) { 23 | return (Continuation) in.readObject(); 24 | } 25 | } 26 | 27 | @Override 28 | public void saveTo(Continuation continuation, Path storagePath) throws IOException { 29 | // Will overwrite previously existing file if any. 30 | try (var out = new ObjectOutputStream(Files.newOutputStream(storagePath, CREATE, TRUNCATE_EXISTING, WRITE))) { 31 | out.writeObject(continuation); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /graaljs/README.md: -------------------------------------------------------------------------------- 1 | # GraalJS Demos and Guides 2 | 3 | This directory contains demo applications and guides for [GraalJS](https://www.graalvm.org/javascript/). 4 | 5 | *Tip: open this directory in IntellIJ IDEA. It should offer to load all Maven projects.* 6 | 7 | ## Demos 8 | 9 | - [Minimal Java application that embeds GraalJS](graaljs-starter/) 10 | 11 | ## Guides 12 | 13 | - [Use Node Packages in a Java SE application](graaljs-maven-webpack-guide/) 14 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/src/main/java/com/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. 5 | */ 6 | 7 | package com.example; 8 | 9 | import org.graalvm.polyglot.*; 10 | import org.graalvm.polyglot.proxy.*; 11 | 12 | public class App { 13 | public static void main(String[] args) throws Exception { 14 | try (Context context = Context.newBuilder("js") 15 | .allowHostAccess(HostAccess.ALL) 16 | .option("engine.WarnInterpreterOnly", "false") 17 | .option("js.esm-eval-returns-exports", "true") 18 | .option("js.unhandled-rejections", "throw") 19 | .build()) { 20 | Source bundleSrc = Source.newBuilder("js", App.class.getResource("/bundle/bundle.mjs")).build(); 21 | Value exports = context.eval(bundleSrc); 22 | String input = args.length > 0 ? args[0] : "https://www.graalvm.org/javascript/"; 23 | 24 | // Using Value.as(Class) 25 | QRCode qrCode = exports.getMember("QRCode").as(QRCode.class); 26 | Promise resultPromise = qrCode.toString(input); 27 | resultPromise.then( 28 | (Value result) -> { 29 | System.out.println("Successfully generated QR code for \"" + input + "\"."); 30 | System.out.println(result.asString()); 31 | } 32 | ); 33 | 34 | // Value API version 35 | Value qrCodeValue = exports.getMember("QRCode"); 36 | Value resultValue = qrCodeValue.invokeMember("toString", input); 37 | resultValue.invokeMember("then", 38 | (ProxyExecutable) (arguments) -> { 39 | Value result = arguments[0]; 40 | System.out.println("Successfully generated QR code for \"" + input + "\"."); 41 | System.out.println(result.asString()); 42 | return result; 43 | } 44 | ); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/src/main/java/com/example/Promise.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. 5 | */ 6 | 7 | package com.example; 8 | 9 | public interface Promise { 10 | Promise then(ValueConsumer onResolve); 11 | 12 | Promise then(ValueConsumer onResolve, ValueConsumer onReject); 13 | } 14 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/src/main/java/com/example/QRCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. 5 | */ 6 | 7 | package com.example; 8 | 9 | public interface QRCode { 10 | Promise toString(String data); 11 | 12 | Promise toDataURL(String data, Object options); 13 | } 14 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/src/main/java/com/example/ValueConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. 5 | */ 6 | 7 | package com.example; 8 | 9 | import java.util.function.*; 10 | import org.graalvm.polyglot.*; 11 | 12 | @FunctionalInterface 13 | public interface ValueConsumer extends Consumer { 14 | @Override 15 | void accept(Value value); 16 | } 17 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/src/main/js/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/syntax-dynamic-import"], 3 | "presets": [ 4 | [ 5 | "@babel/preset-env", 6 | { 7 | "modules": false 8 | } 9 | ] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/src/main/js/main.mjs: -------------------------------------------------------------------------------- 1 | // GraalJS doesn't support TextEncoder yet. It's easy to add and here's a polyfill in the meantime. 2 | import 'fast-text-encoding'; 3 | 4 | export * as QRCode from 'qrcode'; // qrcode/lib/server.js 5 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/src/main/js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qrdemo", 3 | "version": "1.0.0", 4 | "description": "QRCode demo app", 5 | "main": "main.mjs", 6 | "author": "GraalVM contributors", 7 | "license": "UPL", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "build": "webpack --mode=production --node-env=production", 11 | "build:dev": "webpack --mode=development", 12 | "build:prod": "webpack --mode=production --node-env=production", 13 | "watch": "webpack --watch" 14 | }, 15 | "dependencies": { 16 | "assert": "^2.1.0", 17 | "browserify-zlib": "^0.2.0", 18 | "fast-text-encoding": "^1.0.6", 19 | "qrcode": "^1.5.4", 20 | "stream-browserify": "^3.0.0", 21 | "util": "^0.12.5" 22 | }, 23 | "devDependencies": { 24 | "@babel/core": "^7.25.2", 25 | "@babel/preset-env": "^7.25.4", 26 | "@webpack-cli/generators": "^3.0.7", 27 | "babel-loader": "^9.1.3", 28 | "webpack": "^5.94.0", 29 | "webpack-cli": "^5.1.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /graaljs/graaljs-maven-webpack-guide/src/main/js/webpack.config.js: -------------------------------------------------------------------------------- 1 | // Generated using webpack-cli https://github.com/webpack/webpack-cli 2 | 3 | const path = require('path'); 4 | const { EnvironmentPlugin } = require('webpack'); 5 | 6 | const isProduction = process.env.NODE_ENV == 'production'; 7 | 8 | const config = { 9 | entry: './main.mjs', 10 | output: { 11 | path: process.env.BUILD_DIR 12 | ? path.resolve(process.env.BUILD_DIR) 13 | : path.resolve(__dirname, '../../../target/classes/bundle'), 14 | filename: 'bundle.mjs', 15 | module: true, 16 | library: { 17 | type: 'module', 18 | }, 19 | globalObject: 'globalThis' 20 | }, 21 | experiments: { 22 | outputModule: true // Generate ES module sources 23 | }, 24 | optimization: { 25 | usedExports: true, // Include only used exports in the bundle 26 | minimize: false, // Disable minification 27 | }, 28 | resolve: { 29 | aliasFields: [], // Disable browser alias to use the server version of the qrcode package 30 | fallback: { // Redirect Node.js core modules to polyfills 31 | "stream": require.resolve("stream-browserify"), 32 | "zlib": require.resolve("browserify-zlib"), 33 | "fs": false // Exclude the fs module altogether 34 | }, 35 | }, 36 | 37 | plugins: [ 38 | // Add your plugins here 39 | // Learn more about plugins from https://webpack.js.org/configuration/plugins/ 40 | // @ts-ignore 41 | new EnvironmentPlugin({ 42 | NODE_DEBUG: false, // Set process.env.NODE_DEBUG to false 43 | }), 44 | ], 45 | module: { 46 | rules: [ 47 | { 48 | test: /\.(js|jsx)$/i, 49 | loader: 'babel-loader', 50 | }, 51 | { 52 | test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i, 53 | type: 'asset', 54 | }, 55 | 56 | // Add your rules for custom modules here 57 | // Learn more about loaders from https://webpack.js.org/loaders/ 58 | ], 59 | }, 60 | mode: isProduction ? 'production' : 'development', 61 | }; 62 | 63 | module.exports = () => config; 64 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | 10 | # Binary files should be left untouched 11 | *.jar binary 12 | 13 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | 7 | # Ignore maven build output directory 8 | target 9 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/README.md: -------------------------------------------------------------------------------- 1 | # GraalJS Quick Start 2 | 3 | A minimal Java application that embeds JavaScript code with GraalJS. 4 | 5 | ## Preparation 6 | 7 | Install GraalVM for JDK 24 and set the value of `JAVA_HOME` accordingly. 8 | We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).) 9 | 10 | ```bash 11 | sdk install java 24-graal 12 | ``` 13 | 14 | ## Run the Application Using Maven 15 | 16 | To build and test the demo, run: 17 | 18 | ```bash 19 | ./mvnw test 20 | ``` 21 | 22 | To execute the main method, run: 23 | 24 | ```bash 25 | ./mvnw exec:java 26 | ``` 27 | 28 | ## Run the Application Using Gradle 29 | 30 | To build and test the demo, run: 31 | 32 | ```bash 33 | ./gradlew test 34 | ``` 35 | 36 | To execute the main method, run: 37 | 38 | ```bash 39 | ./gradlew run 40 | ``` 41 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | // Apply the application plugin to add support for building a CLI application in Java. 3 | application 4 | } 5 | 6 | repositories { 7 | // Use Maven Central for resolving dependencies. 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | implementation("org.graalvm.polyglot:polyglot:24.2.0") 13 | implementation("org.graalvm.polyglot:js:24.2.0") 14 | 15 | // Use JUnit Jupiter for testing. 16 | testImplementation("org.junit.jupiter:junit-jupiter:5.11.0") 17 | 18 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 19 | } 20 | 21 | application { 22 | // Define the main class for the application. 23 | mainClass = "com.example.App" 24 | } 25 | 26 | tasks.named("test") { 27 | // Use JUnit Platform for unit tests. 28 | useJUnitPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graaljs/graaljs-starter/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graaljs/graaljs-starter/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "graaljs-starter" 2 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/src/main/java/com/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import org.graalvm.polyglot.Context; 10 | 11 | public class App { 12 | 13 | public static void main(String[] args) { 14 | try (Context context = Context.create()) { 15 | context.eval("js", "console.log('Hello from GraalJS!')"); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /graaljs/graaljs-starter/src/test/java/com/example/AppTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 12 | 13 | class AppTest { 14 | @Test 15 | void appRuns() { 16 | assertDoesNotThrow(() -> App.main(new String[0])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /graalpy/README.md: -------------------------------------------------------------------------------- 1 | # GraalPy Demos and Guides 2 | 3 | This directory contains demo applications and guides for [GraalPy](https://www.graalvm.org/python/). 4 | 5 | *Tip: open this directory in IntellIJ IDEA. It should offer to load all Maven projects.* 6 | 7 | ## Demos 8 | 9 | - [Minimal Java application that embeds GraalPy](graalpy-starter/) 10 | - [Minimal Java application that embeds `openai` Python package with GraalPy](graalpy-openai-starter/) 11 | - [Embed `qrcode` Python package with GraalPy in JBang](graalpy-jbang-qrcode/) 12 | - [Embed SVG charting library `pygal` with GraalPy in Micronaut](graalpy-micronaut-pygal-charts/) 13 | - [Embed SVG charting library `pygal` with GraalPy in Spring Boot](graalpy-spring-boot-pygal-charts/) 14 | 15 | ## Guides 16 | 17 | - Use GraalPy and GraalPy Maven plugin in a [Java SE application](graalpy-javase-guide/) 18 | - Use GraalPy with popular Java frameworks, such as [Spring Boot](graalpy-spring-boot-guide/) or [Micronaut](graalpy-micronaut-guide/) 19 | - Use GraalPy Maven plugin to install and use Python packages that rely on [native code](graalpy-native-extensions-guide/), e.g. for data science and machine learning 20 | - Manually [install Python packages and files](graalpy-custom-venv-guide/) if the Maven plugin gives not enough control 21 | - [Freeze](graalpy-freeze-dependencies-guide/) transitive Python dependencies for reproducible builds 22 | - [Migrate from Jython](graalpy-jython-guide/) to GraalPy 23 | -------------------------------------------------------------------------------- /graalpy/graalpy-custom-venv-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-custom-venv-guide/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.example 7 | custom-venv 8 | 1.0-SNAPSHOT 9 | customvenv 10 | 11 | 12 | UTF-8 13 | 17 14 | 15 | 16 | 17 | 18 | org.graalvm.polyglot 19 | python 20 | 24.2.0 21 | pom 22 | 23 | 24 | 25 | org.graalvm.polyglot 26 | polyglot 27 | 24.2.0 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /graalpy/graalpy-custom-venv-guide/src/main/java/org/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import org.graalvm.polyglot.*; 10 | import org.graalvm.polyglot.io.*; 11 | 12 | import java.nio.file.*; 13 | 14 | public class App { 15 | private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("windows"); 16 | 17 | public static void main(String[] args) { 18 | if (System.getProperty("venv") == null) { 19 | System.err.println("Provide 'venv' system property."); 20 | System.exit(1); 21 | } 22 | Path executable; 23 | if (IS_WINDOWS) { // ① 24 | executable = Paths.get(System.getProperty("venv"), "Scripts", "python.exe"); 25 | } else { 26 | executable = Paths.get(System.getProperty("venv"), "bin", "python"); 27 | } 28 | try (Context context = Context.newBuilder() // ② 29 | .option("python.Executable", executable.toAbsolutePath().toString()) // ③ 30 | .option("python.ForceImportSite", "true") // ④ 31 | .allowIO(IOAccess.newBuilder().allowHostFileAccess(true).build()) // ⑤ 32 | .build()) { 33 | Value asciiArt = context.eval("python", "import art; art.text2art('GraalPy')"); // ⑥ 34 | System.out.println(asciiArt.asString()); // ⑦ 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /graalpy/graalpy-freeze-dependencies-guide/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore maven build output directory 2 | target 3 | # Ignore custom venv directory 4 | venv -------------------------------------------------------------------------------- /graalpy/graalpy-freeze-dependencies-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-freeze-dependencies-guide/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | application 3 | id("org.graalvm.python") version "24.2.0" 4 | } 5 | 6 | // To make the paths of this reference solution (without 'app' subdirectory for sources) 7 | // and "gradle init ..." based solution (with sources in 'app') the same for README.md 8 | layout.buildDirectory.set(layout.projectDirectory.dir("app/build")) 9 | 10 | if ("true".equals(System.getProperty("no.transitive.dependencies"))) { 11 | graalPy { 12 | packages = setOf("vaderSentiment==3.3.2") // ① 13 | } 14 | } else { 15 | // The default profile shows the end result: all our transitive 16 | // dependencies are explicitly pinned to a specific version. 17 | graalPy { 18 | packages = setOf( 19 | "vaderSentiment==3.3.2", 20 | "certifi==2024.8.30", 21 | "charset-normalizer==3.1.0", 22 | "idna==3.8", 23 | "requests==2.32.3", 24 | "urllib3==2.2.2" 25 | ) 26 | } 27 | } 28 | 29 | repositories { 30 | mavenLocal() 31 | maven { 32 | url = uri("https://repo.maven.apache.org/maven2/") 33 | } 34 | } 35 | 36 | // This dependency is necessary only for the example Java code, not for building and running pip freeze: 37 | dependencies.add("implementation", "org.graalvm.python:python-embedding:24.2.0") 38 | 39 | group = "org.example" 40 | version = "1.0-SNAPSHOT" 41 | description = "javase" 42 | java.sourceCompatibility = JavaVersion.VERSION_17 43 | 44 | application { 45 | mainClass = "org.example.App" 46 | applicationDefaultJvmArgs = listOf("-Dgraalpy.resources=" + System.getProperty("graalpy.resources")) 47 | } 48 | -------------------------------------------------------------------------------- /graalpy/graalpy-freeze-dependencies-guide/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-freeze-dependencies-guide/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalpy/graalpy-freeze-dependencies-guide/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-freeze-dependencies-guide/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "example" 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-freeze-dependencies-guide/src/main/java/org/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | package org.example; 7 | 8 | import org.graalvm.polyglot.Context; 9 | import org.graalvm.python.embedding.utils.GraalPyResources; 10 | 11 | public class App { 12 | public static void main(String[] args) { 13 | try (Context context = GraalPyResources.createContext()) { 14 | context.eval("python", """ 15 | from vaderSentiment.vaderSentiment import NEGATE; 16 | print(NEGATE) 17 | """); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | application 3 | id("org.graalvm.python") version "24.2.0" 4 | } 5 | 6 | graalPy { 7 | packages = setOf("qrcode==7.4.2") // ① 8 | externalDirectory = file("${project.projectDir}/python-resources") // ② 9 | } 10 | 11 | repositories { 12 | mavenLocal() 13 | maven { 14 | url = uri("https://repo.maven.apache.org/maven2/") 15 | } 16 | } 17 | 18 | group = "org.example" 19 | version = "1.0-SNAPSHOT" 20 | description = "javase" 21 | java.sourceCompatibility = JavaVersion.VERSION_17 22 | 23 | application { 24 | mainClass = "org.example.App" 25 | applicationDefaultJvmArgs = listOf("-Dgraalpy.resources=" + System.getProperty("graalpy.resources")) 26 | } 27 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-javase-guide/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.example 6 | javase 7 | 1.0-SNAPSHOT 8 | jar 9 | javase 10 | 11 | 12 | 17 13 | 17 14 | UTF-8 15 | 16 | 17 | 18 | 19 | org.graalvm.polyglot 20 | python 21 | 24.2.0 22 | pom 23 | 24 | 25 | 26 | org.graalvm.python 27 | python-embedding 28 | 24.2.0 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.graalvm.python 36 | graalpy-maven-plugin 37 | 24.2.0 38 | 39 | 40 | qrcode==7.4.2 41 | 42 | 43 | ${project.basedir}/python-resources 44 | 45 | 46 | 47 | 48 | 49 | process-graalpy-resources 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-javase-guide/screenshot.png -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "javase" 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/src/main/java/org/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import java.io.*; 10 | import javax.imageio.ImageIO; 11 | import javax.swing.*; 12 | 13 | public class App { 14 | public static void main(String[] args) throws IOException { 15 | String path = System.getProperty("graalpy.resources"); 16 | if (path == null || path.isBlank() || path.equals("null")) { 17 | System.err.println("Please provide 'graalpy.resources' system property."); 18 | System.exit(1); 19 | } 20 | try (var context = GraalPy.createPythonContext(path)) { // ① 21 | QRCode qrCode = context.eval("python", "import qrcode; qrcode").as(QRCode.class); // ② 22 | IO io = context.eval("python", "import io; io").as(IO.class); 23 | 24 | IO.BytesIO bytesIO = io.BytesIO(); // ③ 25 | qrCode.make("Hello from GraalPy on JDK " + System.getProperty("java.version")).save(bytesIO); 26 | 27 | var qrImage = ImageIO.read(new ByteArrayInputStream(bytesIO.getvalue().toByteArray())); // ④ 28 | JFrame frame = new JFrame("QR Code"); 29 | frame.getContentPane().add(new JLabel(new ImageIcon(qrImage))); 30 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 31 | frame.setSize(400, 400); 32 | frame.setVisible(true); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/src/main/java/org/example/GraalPy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import java.nio.file.Path; 10 | 11 | import org.graalvm.polyglot.Context; 12 | import org.graalvm.python.embedding.utils.*; 13 | 14 | public class GraalPy { 15 | static VirtualFileSystem vfs; 16 | 17 | public static Context createPythonContext(String pythonResourcesDirectory) { // ① 18 | return GraalPyResources.contextBuilder(Path.of(pythonResourcesDirectory)).build(); 19 | } 20 | 21 | public static Context createPythonContextFromResources() { 22 | if (vfs == null) { // ② 23 | vfs = VirtualFileSystem.newBuilder().allowHostIO(VirtualFileSystem.HostIO.READ).build(); 24 | } 25 | return GraalPyResources.contextBuilder(vfs).build(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/src/main/java/org/example/IO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import org.graalvm.polyglot.io.ByteSequence; 10 | 11 | interface IO { 12 | BytesIO BytesIO(); 13 | 14 | interface BytesIO { 15 | ByteSequence getvalue(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/src/main/java/org/example/QRCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | interface QRCode { 10 | PyPNGImage make(String data); 11 | 12 | interface PyPNGImage { 13 | void save(IO.BytesIO bio); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /graalpy/graalpy-javase-guide/src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: org.example.App 3 | -------------------------------------------------------------------------------- /graalpy/graalpy-jbang-qrcode/README.md: -------------------------------------------------------------------------------- 1 | # GraalPy JBang QRCode Demo 2 | 3 | This demo illustrates how GraalPy can be used to embed the [`qrcode` Python package](https://pypi.org/project/qrcode/) in a script that runs on [JBang](https://www.jbang.dev/). 4 | 5 | ## Preparation 6 | 7 | Install GraalVM for JDK 24 and set the value of `JAVA_HOME` accordingly. 8 | We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).) 9 | 10 | ```bash 11 | sdk install java 24-graal 12 | ``` 13 | 14 | Afterward, [install `jbang`](https://www.jbang.dev/download/), for with: 15 | 16 | ```bash 17 | sdk install jbang 18 | ``` 19 | 20 | ## Run the Application 21 | 22 | To start the demo, run: 23 | 24 | ```bash 25 | jbang run qrcode.java "Hello from GraalPy!" 26 | ``` 27 | 28 | ## Implementation Details 29 | 30 | [qrcode.java](qrcode.java) defines required dependencies on GraalPy, which also allows to depend on Python packages. 31 | `//PIP qrcode==7.4.2` defines the dependency on the `qrcode` Python package. 32 | The `main()` method checks the arguments and then creates a new `Context`. 33 | It then fetches the `qrcode` Python module and maps it to a `QRCode` Java interface. 34 | Afterward, it uses the `qrcode` module as illustrated in [this example](https://github.com/lincolnloop/python-qrcode/tree/v7.4.2?tab=readme-ov-file#examples) through Java interfaces. 35 | Finally, it prints the result to `System.out`. 36 | -------------------------------------------------------------------------------- /graalpy/graalpy-jbang-qrcode/qrcode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | //DEPS org.graalvm.python:python-language:24.2.0 8 | //DEPS org.graalvm.python:python-launcher:24.2.0 9 | //DEPS org.graalvm.python:python-resources:24.2.0 10 | //DEPS org.graalvm.python:python-embedding:24.2.0 11 | //DEPS org.graalvm.python:python-embedding-tools:24.2.0 12 | //DEPS org.graalvm.python:jbang:24.2.0 13 | //DEPS org.graalvm.truffle:truffle-runtime:24.2.0 14 | //PIP qrcode==7.4.2 15 | 16 | import org.graalvm.python.embedding.utils.GraalPyResources; 17 | 18 | public class qrcode { 19 | 20 | public static void main(String[] args) { 21 | if (args.length != 1 || args[0].equals("-h") || args[0].equals("--help")) { 22 | System.out.println("This tool takes only a single argument, the QR code data."); 23 | return; 24 | } 25 | try (var context = GraalPyResources.contextBuilder().option("python.PythonHome", "").build()) { 26 | QRCodeModule qrcodeModule = context.eval("python", "import qrcode; qrcode").as(QRCodeModule.class); 27 | IO io = context.eval("python", "import io; io").as(IO.class); 28 | 29 | QRCode qr = qrcodeModule.QRCode(); 30 | qr.add_data(args[0]); 31 | 32 | StringIO f = io.StringIO(); 33 | qr.print_ascii(f); 34 | String qrCodeString = f.getvalue(); 35 | 36 | System.out.println(qrCodeString); 37 | } 38 | } 39 | 40 | public interface QRCodeModule { 41 | QRCode QRCode(); 42 | } 43 | 44 | public interface QRCode { 45 | void add_data(String text); 46 | 47 | void print_ascii(StringIO out); 48 | } 49 | 50 | public interface IO { 51 | StringIO StringIO(); 52 | } 53 | 54 | public interface StringIO { 55 | String getvalue(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /graalpy/graalpy-jython-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-jython-guide/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.example 7 | jython 8 | 1.0-SNAPSHOT 9 | 10 | jython 11 | https://www.example.com 12 | 13 | 14 | UTF-8 15 | 17 16 | 17 | 18 | 19 | 20 | org.python 21 | jython-standalone 22 | 2.7.4 23 | 24 | 25 | org.graalvm.polyglot 26 | python 27 | 24.2.0 28 | pom 29 | 30 | 31 | org.graalvm.polyglot 32 | polyglot 33 | 24.2.0 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /graalpy/graalpy-jython-guide/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-jython-guide/screenshot.png -------------------------------------------------------------------------------- /graalpy/graalpy-jython-guide/src/main/java/org/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import java.util.LinkedHashMap; 10 | 11 | public class App { 12 | public static void main(String[] args) { 13 | var interpreters = new LinkedHashMap(); 14 | interpreters.put("Echo", new EchoInputCallback()); 15 | interpreters.put("Jython", new JythonInputCallback()); 16 | interpreters.put("GraalPy", new GraalPyInputCallback()); 17 | Workspace.open(interpreters); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-jython-guide/src/main/java/org/example/EchoInputCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | final class EchoInputCallback implements InputCallback { 10 | @Override 11 | public void setUp(Workspace workspace) { 12 | } 13 | 14 | @Override 15 | public String interpret(String code) { 16 | return code; 17 | } 18 | 19 | @Override 20 | public void tearDown() { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /graalpy/graalpy-jython-guide/src/main/java/org/example/GraalPyInputCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import org.graalvm.polyglot.*; 10 | 11 | final class GraalPyInputCallback implements InputCallback { 12 | static Source GRAALPY_CODE = Source.create("python", "__import__('sys').version"); 13 | static Engine engine = Engine.create("python"); 14 | private Context python; 15 | 16 | @Override 17 | public void setUp(Workspace workspace) { 18 | this.python = Context.newBuilder("python") // ① 19 | .engine(engine) // ② 20 | .allowAllAccess(true).option("python.EmulateJython", "true") // ③ 21 | .build(); 22 | python.getBindings("python").putMember("this", workspace); // ④ 23 | } 24 | 25 | @Override 26 | public String interpret(String code) { 27 | Value result; 28 | if (code.isBlank()) { 29 | result = python.eval(GRAALPY_CODE); 30 | } else { 31 | result = python.eval("python", code); // ① 32 | } 33 | if (result.isString()) { // ② 34 | return code + "\n... " + result.asString(); 35 | } 36 | return code + "\n...(repr) " + result.toString(); 37 | } 38 | 39 | @Override 40 | public void tearDown() { 41 | python.close(true); // ① 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /graalpy/graalpy-jython-guide/src/main/java/org/example/InputCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | interface InputCallback { 10 | void setUp(Workspace workspace); 11 | 12 | String interpret(String code); 13 | 14 | void tearDown(); 15 | } 16 | -------------------------------------------------------------------------------- /graalpy/graalpy-jython-guide/src/main/java/org/example/JythonInputCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import org.python.core.*; 10 | import org.python.util.PythonInterpreter; 11 | 12 | final class JythonInputCallback implements InputCallback { 13 | static PyCode JYTHON_CODE = new PythonInterpreter().compile("__import__('sys').version"); // ① 14 | private PythonInterpreter python; 15 | 16 | @Override 17 | public void setUp(Workspace workspace) { 18 | var globals = new PyDictionary(); 19 | this.python = new PythonInterpreter(globals); // ② 20 | globals.put(new PyString("this"), workspace); 21 | } 22 | 23 | @Override 24 | public String interpret(String code) { 25 | try { 26 | PyObject result; 27 | if (code.isBlank()) { 28 | result = python.eval(JYTHON_CODE); 29 | } else { 30 | result = python.eval(code); 31 | } 32 | if (result instanceof PyString strResult) { // ③ 33 | return code + "\n... " + strResult.asString(); 34 | } 35 | return code + "\n...(repr) " + result.__repr__(); 36 | } catch (PySyntaxError e) { 37 | python.exec(code); // ④ 38 | return ""; 39 | } 40 | } 41 | 42 | @Override 43 | public void tearDown() { 44 | python.close(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | .DS_Store 3 | .gradle 4 | build/ 5 | target/ 6 | out/ 7 | .micronaut/ 8 | .idea 9 | *.iml 10 | *.ipr 11 | *.iws 12 | .project 13 | .settings 14 | .classpath 15 | .factorypath 16 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/aot-jar.properties: -------------------------------------------------------------------------------- 1 | # AOT configuration properties for jar packaging 2 | # Please review carefully the optimizations enabled below 3 | # Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details 4 | 5 | # Caches environment property values: environment properties will be deemed immutable after application startup. 6 | cached.environment.enabled=true 7 | 8 | # Precomputes Micronaut configuration property keys from the current environment variables 9 | precompute.environment.properties.enabled=true 10 | 11 | # Replaces logback.xml with a pure Java configuration 12 | logback.xml.to.java.enabled=true 13 | 14 | # Converts YAML configuration files to Java configuration 15 | yaml.to.java.config.enabled=true 16 | 17 | # Scans for service types ahead-of-time, avoiding classpath scanning at startup 18 | serviceloading.jit.enabled=true 19 | 20 | # Scans reactive types at build time instead of runtime 21 | scan.reactive.types.enabled=true 22 | 23 | # Deduces the environment at build time instead of runtime 24 | deduce.environment.enabled=true 25 | 26 | # Checks for the existence of some types at build time instead of runtime 27 | known.missing.types.enabled=true 28 | 29 | # Precomputes property sources at build time 30 | sealed.property.source.enabled=true 31 | 32 | # The list of service types to be scanned (comma separated) 33 | service.types=io.micronaut.context.env.PropertySourceLoader,io.micronaut.inject.BeanConfiguration,io.micronaut.inject.BeanDefinitionReference,io.micronaut.http.HttpRequestFactory,io.micronaut.http.HttpResponseFactory,io.micronaut.core.beans.BeanIntrospectionReference,io.micronaut.core.convert.TypeConverterRegistrar,io.micronaut.context.env.PropertyExpressionResolver 34 | 35 | # A list of types that the AOT analyzer needs to check for existence (comma separated) 36 | known.missing.types.list=io.reactivex.Observable,reactor.core.publisher.Flux,kotlinx.coroutines.flow.Flow,io.reactivex.rxjava3.core.Flowable,io.reactivex.rxjava3.core.Observable,io.reactivex.Single,reactor.core.publisher.Mono,io.reactivex.Maybe,io.reactivex.rxjava3.core.Single,io.reactivex.rxjava3.core.Maybe,io.reactivex.Completable,io.reactivex.rxjava3.core.Completable,io.methvin.watchservice.MacOSXListeningWatchService,io.micronaut.core.async.publisher.CompletableFuturePublisher,io.micronaut.core.async.publisher.Publishers.JustPublisher,io.micronaut.core.async.subscriber.Completable 37 | 38 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("org.graalvm.python") version "24.2.0" 3 | // ... 4 | id("com.github.johnrengelman.shadow") version "8.1.1" 5 | id("io.micronaut.application") version "4.4.2" 6 | id("io.micronaut.aot") version "4.4.2" 7 | } 8 | 9 | graalPy { 10 | packages = setOf( // ① 11 | "vader-sentiment==3.2.1.1", // ② 12 | "requests" // ③ 13 | ) 14 | } 15 | 16 | version = "0.1" 17 | group = "com.example" 18 | 19 | repositories { 20 | mavenCentral() 21 | } 22 | 23 | dependencies { 24 | implementation("io.micronaut.views:micronaut-views-thymeleaf") // ④ 25 | 26 | annotationProcessor("io.micronaut:micronaut-http-validation") 27 | annotationProcessor("io.micronaut.serde:micronaut-serde-processor") 28 | implementation("io.micronaut.serde:micronaut-serde-jackson") 29 | compileOnly("io.micronaut:micronaut-http-client") 30 | runtimeOnly("ch.qos.logback:logback-classic") 31 | testImplementation("io.micronaut:micronaut-http-client") 32 | } 33 | 34 | application { 35 | mainClass = "org.example.Application" 36 | } 37 | 38 | java { 39 | sourceCompatibility = JavaVersion.toVersion("17") 40 | targetCompatibility = JavaVersion.toVersion("17") 41 | } 42 | 43 | graalvmNative.toolchainDetection = false 44 | 45 | micronaut { 46 | runtime("netty") 47 | testRuntime("junit5") 48 | processing { 49 | incremental(true) 50 | annotations("com.example.*") 51 | } 52 | aot { 53 | // Please review carefully the optimizations enabled below 54 | // Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details 55 | optimizeServiceLoading = false 56 | convertYamlToJava = false 57 | precomputeOperations = true 58 | cacheEnvironment = true 59 | optimizeClassLoading = true 60 | deduceEnvironment = true 61 | optimizeNetty = true 62 | replaceLogbackXml = true 63 | } 64 | } 65 | 66 | tasks.withType { 67 | systemProperty("micronaut.http.client.read-timeout", System.getProperty("micronaut.http.client.read-timeout")) 68 | } 69 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=4.6.3 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-micronaut-guide/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/micronaut-cli.yml: -------------------------------------------------------------------------------- 1 | applicationType: default 2 | defaultPackage: org.example 3 | testFramework: junit 4 | sourceLanguage: java 5 | buildTool: gradle_kotlin # maven 6 | features: [app-name, gradle, http-client-test, java, java-application, junit, logback, maven, maven-enforcer-plugin, micronaut-aot, micronaut-http-validation, netty-server, properties, readme, serialization-jackson, shade, static-resources] 7 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-micronaut-guide/screenshot.png -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name="demo" 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/main/java/org/example/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | import io.micronaut.runtime.Micronaut; 9 | 10 | public class Application { 11 | 12 | public static void main(String[] args) { 13 | Micronaut.run(Application.class, args); 14 | } 15 | } -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/main/java/org/example/GraalPyContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import io.micronaut.context.annotation.Context; 10 | import jakarta.annotation.PreDestroy; 11 | import org.graalvm.python.embedding.utils.GraalPyResources; 12 | 13 | @Context // ① 14 | public final class GraalPyContext { 15 | 16 | static final String PYTHON = "python"; 17 | 18 | private final org.graalvm.polyglot.Context context; 19 | 20 | public GraalPyContext() { 21 | context = GraalPyResources.createContext(); // ② 22 | context.initialize(PYTHON); // ③ 23 | } 24 | 25 | org.graalvm.polyglot.Context get() { 26 | return context; // ④ 27 | } 28 | 29 | @PreDestroy 30 | void close() { 31 | try { 32 | context.close(true); // ⑤ 33 | } catch (Exception e) { 34 | // ignore 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/main/java/org/example/SentimentAnalysis.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import io.micronaut.context.annotation.Bean; 10 | import org.graalvm.polyglot.Value; 11 | import java.util.Map; 12 | import static org.example.GraalPyContext.PYTHON; 13 | 14 | @Bean 15 | public class SentimentAnalysis { 16 | 17 | private final SentimentIntensityAnalyzer sentimentIntensityAnalyzer; 18 | 19 | public SentimentAnalysis(GraalPyContext context) { 20 | Value value = context.get().eval(PYTHON, """ 21 | from vader_sentiment.vader_sentiment import SentimentIntensityAnalyzer 22 | SentimentIntensityAnalyzer() # ① 23 | """); 24 | sentimentIntensityAnalyzer = value.as(SentimentIntensityAnalyzer.class); // ② 25 | } 26 | 27 | public Map getPolarityScores(String text) { 28 | return sentimentIntensityAnalyzer.polarity_scores(text); // ③ 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/main/java/org/example/SentimentAnalysisController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import io.micronaut.http.annotation.*; 10 | import io.micronaut.scheduling.TaskExecutors; 11 | import io.micronaut.scheduling.annotation.ExecuteOn; 12 | import io.micronaut.views.View; 13 | import java.util.Map; 14 | 15 | @Controller // ① 16 | public class SentimentAnalysisController { 17 | 18 | private final SentimentAnalysis sentimentAnalysis; 19 | 20 | SentimentAnalysisController(SentimentAnalysis sentimentAnalysis) { // ② 21 | this.sentimentAnalysis = sentimentAnalysis; 22 | } 23 | 24 | @Get // ③ 25 | @View("index") // ④ 26 | public void index() { 27 | 28 | } 29 | 30 | @Get(value = "/analyze") // ⑤ 31 | @ExecuteOn(TaskExecutors.BLOCKING) // ⑥ 32 | public Map answer(String text) { 33 | return sentimentAnalysis.getPolarityScores(text); // ⑦ 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/main/java/org/example/SentimentIntensityAnalyzer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import java.util.Map; 10 | 11 | public interface SentimentIntensityAnalyzer { 12 | Map polarity_scores(String text); // ① 13 | } 14 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/main/resources/META-INF/native-image/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ["org.example.SentimentIntensityAnalyzer"] 3 | ] -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 02 15:53:44 CEST 2024 2 | micronaut.application.name=demo -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-guide/src/test/java/org/example/SentimentAnalysisControllerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package org.example; 8 | 9 | import io.micronaut.http.client.HttpClient; 10 | import io.micronaut.http.client.annotation.Client; 11 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 12 | import org.junit.jupiter.api.Test; 13 | import java.util.Map; 14 | import static org.junit.jupiter.api.Assertions.assertTrue; 15 | 16 | @MicronautTest // ① 17 | class SentimentAnalysisControllerTest { 18 | @Test 19 | void testAnalyzeResponse(@Client("/") HttpClient client) { // ② 20 | Map response = client.toBlocking().retrieve("/analyze?text=happy", Map.class); // ③ 21 | assertTrue(response.get("compound") > 0.1); 22 | response = client.toBlocking().retrieve("/analyze?text=sad", Map.class); 23 | assertTrue(response.get("compound") < -0.1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/aot-jar.properties: -------------------------------------------------------------------------------- 1 | # AOT configuration properties for jar packaging 2 | # Please review carefully the optimizations enabled below 3 | # Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details 4 | 5 | # Caches environment property values: environment properties will be deemed immutable after application startup. 6 | cached.environment.enabled=true 7 | 8 | # Precomputes Micronaut configuration property keys from the current environment variables 9 | precompute.environment.properties.enabled=true 10 | 11 | # Replaces logback.xml with a pure Java configuration 12 | logback.xml.to.java.enabled=true 13 | 14 | # Converts YAML configuration files to Java configuration 15 | yaml.to.java.config.enabled=true 16 | 17 | # Scans for service types ahead-of-time, avoiding classpath scanning at startup 18 | serviceloading.jit.enabled=true 19 | 20 | # Scans reactive types at build time instead of runtime 21 | scan.reactive.types.enabled=true 22 | 23 | # Deduces the environment at build time instead of runtime 24 | deduce.environment.enabled=true 25 | 26 | # Checks for the existence of some types at build time instead of runtime 27 | known.missing.types.enabled=true 28 | 29 | # Precomputes property sources at build time 30 | sealed.property.source.enabled=true 31 | 32 | # The list of service types to be scanned (comma separated) 33 | service.types=io.micronaut.context.env.PropertySourceLoader,io.micronaut.inject.BeanConfiguration,io.micronaut.inject.BeanDefinitionReference,io.micronaut.http.HttpRequestFactory,io.micronaut.http.HttpResponseFactory,io.micronaut.core.beans.BeanIntrospectionReference,io.micronaut.core.convert.TypeConverterRegistrar,io.micronaut.context.env.PropertyExpressionResolver 34 | 35 | # A list of types that the AOT analyzer needs to check for existence (comma separated) 36 | known.missing.types.list=io.reactivex.Observable,reactor.core.publisher.Flux,kotlinx.coroutines.flow.Flow,io.reactivex.rxjava3.core.Flowable,io.reactivex.rxjava3.core.Observable,io.reactivex.Single,reactor.core.publisher.Mono,io.reactivex.Maybe,io.reactivex.rxjava3.core.Single,io.reactivex.rxjava3.core.Maybe,io.reactivex.Completable,io.reactivex.rxjava3.core.Completable,io.methvin.watchservice.MacOSXListeningWatchService,io.micronaut.core.async.publisher.CompletableFuturePublisher,io.micronaut.core.async.publisher.Publishers.JustPublisher,io.micronaut.core.async.subscriber.Completable 37 | 38 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/gradle.properties: -------------------------------------------------------------------------------- 1 | micronautVersion=4.7.4 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-micronaut-multithreaded/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/micronaut-cli.yml: -------------------------------------------------------------------------------- 1 | applicationType: default 2 | defaultPackage: graalpy.micronaut.multithreaded 3 | testFramework: junit 4 | sourceLanguage: java 5 | buildTool: maven 6 | features: [app-name, graalvm, http-client-test, java, java-application, junit, logback, maven, maven-enforcer-plugin, micronaut-aot, micronaut-http-validation, netty-server, properties, readme, serialization-jackson, shade, static-resources, views-fieldset, views-thymeleaf] 7 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/scaling-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-micronaut-multithreaded/scaling-dark.png -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/scaling-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-micronaut-multithreaded/scaling-light.png -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-micronaut-multithreaded/screenshot.png -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name="demo" 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/src/main/java/graalpy/micronaut/multithreaded/Application.java: -------------------------------------------------------------------------------- 1 | package graalpy.micronaut.multithreaded; 2 | 3 | import io.micronaut.runtime.Micronaut; 4 | 5 | public class Application { 6 | 7 | public static void main(String[] args) { 8 | Micronaut.run(Application.class, args); 9 | } 10 | } -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/src/main/java/graalpy/micronaut/multithreaded/DataAnalysisController.java: -------------------------------------------------------------------------------- 1 | package graalpy.micronaut.multithreaded; 2 | 3 | import io.micronaut.http.HttpStatus; 4 | import io.micronaut.http.MediaType; 5 | import io.micronaut.http.annotation.Controller; 6 | import io.micronaut.http.annotation.Get; 7 | import io.micronaut.http.annotation.Part; 8 | import io.micronaut.http.annotation.Post; 9 | import io.micronaut.http.exceptions.HttpStatusException; 10 | import io.micronaut.http.multipart.StreamingFileUpload; 11 | import io.micronaut.scheduling.TaskExecutors; 12 | import io.micronaut.scheduling.annotation.ExecuteOn; 13 | import io.micronaut.views.View; 14 | 15 | @Controller // ① 16 | public class DataAnalysisController { 17 | private final PythonPool pool; 18 | 19 | public DataAnalysisController(PythonPool pool) { // ② 20 | this.pool = pool; 21 | } 22 | 23 | @Get // ③ 24 | @View("index") // ④ 25 | public void index() { 26 | } 27 | 28 | @Post(value = "/data_analysis", consumes = MediaType.MULTIPART_FORM_DATA, produces = MediaType.TEXT_PLAIN) // ⑤ 29 | @ExecuteOn(TaskExecutors.IO) // ⑥ 30 | String analyzeCsvMulti(StreamingFileUpload file, 31 | @Part("poolSize") String poolSizeString) { 32 | try { 33 | pool.setPoolSize(Integer.parseInt(poolSizeString)); 34 | String csv = new String(file.asInputStream().readAllBytes(), "UTF-8"); 35 | return pool.execute((c) -> { // ⑦ 36 | return c.eval("python", "import data_analysis; data_analysis").invokeMember("mean", csv).toString(); 37 | }); 38 | } catch (Exception e) { 39 | throw new HttpStatusException(HttpStatus.BAD_REQUEST, e.getMessage()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #Thu Jan 16 09:37:12 CET 2025 2 | micronaut.application.name=graalpy-micronaut-multithreaded 3 | micronaut.server.multipart.max-file-size=209715200 4 | micronaut.server.multipart.enabled=true 5 | micronaut.server.max-request-size=209715200 6 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-multithreaded/src/main/resources/org.graalvm.python.vfs/src/data_analysis.py: -------------------------------------------------------------------------------- 1 | import io 2 | import numpy as np 3 | 4 | 5 | def mean(csv: str) -> list[float]: 6 | ary = np.genfromtxt(io.StringIO(csv), delimiter=",", invalid_raise=False) 7 | return ary.transpose().mean(axis=1).tolist() 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | .DS_Store 3 | .gradle 4 | build/ 5 | target/ 6 | out/ 7 | .micronaut/ 8 | .idea 9 | *.iml 10 | *.ipr 11 | *.iws 12 | .project 13 | .settings 14 | .classpath 15 | .factorypath 16 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/aot-jar.properties: -------------------------------------------------------------------------------- 1 | # AOT configuration properties for jar packaging 2 | # Please review carefully the optimizations enabled below 3 | # Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details 4 | 5 | # Caches environment property values: environment properties will be deemed immutable after application startup. 6 | cached.environment.enabled=true 7 | 8 | # Precomputes Micronaut configuration property keys from the current environment variables 9 | precompute.environment.properties.enabled=true 10 | 11 | # Replaces logback.xml with a pure Java configuration 12 | logback.xml.to.java.enabled=true 13 | 14 | # Converts YAML configuration files to Java configuration 15 | yaml.to.java.config.enabled=true 16 | 17 | # Scans for service types ahead-of-time, avoiding classpath scanning at startup 18 | serviceloading.jit.enabled=true 19 | 20 | # Scans reactive types at build time instead of runtime 21 | scan.reactive.types.enabled=true 22 | 23 | # Deduces the environment at build time instead of runtime 24 | deduce.environment.enabled=true 25 | 26 | # Checks for the existence of some types at build time instead of runtime 27 | known.missing.types.enabled=true 28 | 29 | # Precomputes property sources at build time 30 | sealed.property.source.enabled=true 31 | 32 | # The list of service types to be scanned (comma separated) 33 | service.types=io.micronaut.context.env.PropertySourceLoader,io.micronaut.inject.BeanConfiguration,io.micronaut.inject.BeanDefinitionReference,io.micronaut.http.HttpRequestFactory,io.micronaut.http.HttpResponseFactory,io.micronaut.core.beans.BeanIntrospectionReference,io.micronaut.core.convert.TypeConverterRegistrar,io.micronaut.context.env.PropertyExpressionResolver 34 | 35 | # A list of types that the AOT analyzer needs to check for existence (comma separated) 36 | known.missing.types.list=io.reactivex.Observable,reactor.core.publisher.Flux,kotlinx.coroutines.flow.Flow,io.reactivex.rxjava3.core.Flowable,io.reactivex.rxjava3.core.Observable,io.reactivex.Single,reactor.core.publisher.Mono,io.reactivex.Maybe,io.reactivex.rxjava3.core.Single,io.reactivex.rxjava3.core.Maybe,io.reactivex.Completable,io.reactivex.rxjava3.core.Completable,io.methvin.watchservice.MacOSXListeningWatchService,io.micronaut.core.async.publisher.CompletableFuturePublisher,io.micronaut.core.async.publisher.Publishers.JustPublisher,io.micronaut.core.async.subscriber.Completable 37 | 38 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/micronaut-cli.yml: -------------------------------------------------------------------------------- 1 | applicationType: default 2 | defaultPackage: com.example 3 | testFramework: junit 4 | sourceLanguage: java 5 | buildTool: maven 6 | features: [app-name, http-client-test, java, java-application, junit, logback, maven, maven-enforcer-plugin, micronaut-aot, micronaut-http-validation, netty-server, properties, readme, serialization-jackson, shade, static-resources] 7 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/java/com/example/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import io.micronaut.runtime.Micronaut; 10 | 11 | public class Application { 12 | 13 | public static void main(String[] args) { 14 | Micronaut.run(Application.class, args); 15 | } 16 | } -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/java/com/example/DemoController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import io.micronaut.http.MediaType; 10 | import io.micronaut.http.annotation.Controller; 11 | import io.micronaut.http.annotation.Get; 12 | import io.micronaut.http.annotation.Produces; 13 | 14 | @Controller 15 | public class DemoController { 16 | 17 | private final PyGalServicePurePython pyGalServicePurePython; 18 | private final PyGalServicePureJava pyGalServicePureJava; 19 | private final PyGalServiceMixed pyGalServiceMixed; 20 | private final PyGalServiceValueAPIDynamic pyGalServiceValueAPIDynamic; 21 | 22 | DemoController(PyGalServicePurePython pyGalServicePurePython, PyGalServicePureJava pyGalServicePureJava, PyGalServiceMixed pyGalServiceMixed, PyGalServiceValueAPIDynamic pyGalServiceValueAPIDynamic) { 23 | this.pyGalServicePurePython = pyGalServicePurePython; 24 | this.pyGalServicePureJava = pyGalServicePureJava; 25 | this.pyGalServiceMixed = pyGalServiceMixed; 26 | this.pyGalServiceValueAPIDynamic = pyGalServiceValueAPIDynamic; 27 | } 28 | 29 | @Get("/python") 30 | @Produces(MediaType.IMAGE_SVG) 31 | public String renderXYChartPurePython() { 32 | return pyGalServicePurePython.renderXYChart(); 33 | } 34 | 35 | @Get("/java") 36 | @Produces(MediaType.IMAGE_SVG) 37 | public String renderXYChartPureJava() { 38 | return pyGalServicePureJava.renderXYChart(); 39 | } 40 | 41 | @Get("/mixed") 42 | @Produces(MediaType.IMAGE_SVG) 43 | public String renderXYChartMixed() { 44 | return pyGalServiceMixed.renderXYChart(); 45 | } 46 | 47 | @Get("/dynamic") 48 | @Produces(MediaType.IMAGE_SVG) 49 | public String renderXYChartValueAPIDynamic() { 50 | return pyGalServiceValueAPIDynamic.renderXYChart(); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/java/com/example/GraalPyContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import io.micronaut.context.annotation.Context; 10 | import jakarta.annotation.PreDestroy; 11 | import org.graalvm.polyglot.Value; 12 | import org.graalvm.python.embedding.utils.GraalPyResources; 13 | 14 | @Context 15 | public class GraalPyContext { 16 | private final org.graalvm.polyglot.Context context = GraalPyResources.createContext(); 17 | 18 | public GraalPyContext() { 19 | context.initialize("python"); 20 | } 21 | 22 | public Value eval(String source) { 23 | return context.eval("python", source); 24 | } 25 | 26 | @PreDestroy 27 | void close() { 28 | context.close(true); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/java/com/example/PyGalService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | /** 10 | * Example PyGal code: 11 | *
12 |  *     from math import cos
13 |  *     xy_chart = pygal.XY()
14 |  *     xy_chart.title = 'XY Cosinus'
15 |  *     xy_chart.add('x = cos(y)', [(cos(x / 10.), x / 10.) for x in range(-50, 50, 5)])
16 |  *     xy_chart.add('y = cos(x)', [(x / 10., cos(x / 10.)) for x in range(-50, 50, 5)])
17 |  *     xy_chart.add('x = 1',  [(1, -5), (1, 5)])
18 |  *     xy_chart.add('x = -1', [(-1, -5), (-1, 5)])
19 |  *     xy_chart.add('y = 1',  [(-5, 1), (5, 1)])
20 |  *     xy_chart.add('y = -1', [(-5, -1), (5, -1)])
21 |  *     xy_chart.render()
22 |  * 
23 | */ 24 | interface PyGalService { 25 | String renderXYChart(); 26 | } -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/java/com/example/PyGalServiceMixed.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import jakarta.inject.Singleton; 10 | 11 | import java.util.List; 12 | import java.util.stream.IntStream; 13 | 14 | @Singleton 15 | public class PyGalServiceMixed implements PyGalService { 16 | private final RenderXYFunction renderXYFunction; 17 | 18 | PyGalServiceMixed(GraalPyContext graalPyContext) { 19 | renderXYFunction = graalPyContext.eval( 20 | // language=python 21 | """ 22 | import pygal 23 | 24 | def render_xy(title, label_datapoint_entries): 25 | xy_chart = pygal.XY() 26 | xy_chart.title = title 27 | for entry in label_datapoint_entries: 28 | xy_chart.add(entry.label(), entry.dataPoints()) 29 | return xy_chart.render().decode() 30 | 31 | render_xy""").as(RenderXYFunction.class); 32 | } 33 | 34 | public record Entry(String label, double[][] dataPoints) { 35 | } 36 | 37 | @FunctionalInterface 38 | public interface RenderXYFunction { 39 | String apply(String title, List labelDatapointEntries); 40 | } 41 | 42 | @Override 43 | public String renderXYChart() { 44 | String title = "XY Cosinus"; 45 | List labelDatapointEntries = List.of( 46 | new Entry("x = cos(y)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{Math.cos(x / 10.0), x / 10.0}).toArray(double[][]::new)), 47 | new Entry("y = cos(x)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{x / 10.0, Math.cos(x / 10.0)}).toArray(double[][]::new)), 48 | new Entry("x = 1", new double[][]{{1, -5}, {1, 5}}), 49 | new Entry("x = -1", new double[][]{{-1, -5}, {-1, 5}}), 50 | new Entry("y = 1", new double[][]{{-5, 1}, {5, 1}}), 51 | new Entry("y = -1", new double[][]{{-5, -1}, {5, -1}}) 52 | ); 53 | return renderXYFunction.apply(title, labelDatapointEntries); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/java/com/example/PyGalServicePureJava.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import jakarta.inject.Singleton; 10 | import org.graalvm.polyglot.Value; 11 | 12 | import java.util.stream.IntStream; 13 | 14 | 15 | @Singleton 16 | public class PyGalServicePureJava implements PyGalService { 17 | private final PyGal pyGalModule; 18 | 19 | PyGalServicePureJava(GraalPyContext graalPyContext) { 20 | pyGalModule = graalPyContext.eval("import pygal; pygal").as(PyGal.class); 21 | } 22 | 23 | public interface PyGal { 24 | XY XY(); 25 | } 26 | 27 | public interface XY { 28 | default void title(String title) { 29 | Value.asValue(this).putMember("title", title); 30 | } 31 | 32 | void add(String label, Object[] values); 33 | 34 | BytesIO render(); 35 | } 36 | 37 | public interface BytesIO { 38 | String decode(); 39 | } 40 | 41 | @Override 42 | public String renderXYChart() { 43 | XY xyChart = pyGalModule.XY(); 44 | xyChart.title("XY Cosinus"); 45 | xyChart.add("x = cos(y)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{Math.cos(x / 10.0), x / 10.0}).toArray(double[][]::new)); 46 | xyChart.add("y = cos(x)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{x / 10.0, Math.cos(x / 10.0)}).toArray(double[][]::new)); 47 | xyChart.add("x = 1", new int[][]{{1, -5}, {1, 5}}); 48 | xyChart.add("x = -1", new int[][]{{-1, -5}, {-1, 5}}); 49 | xyChart.add("y = 1", new int[][]{{-5, 1}, {5, 1}}); 50 | xyChart.add("y = -1", new int[][]{{-5, -1}, {5, -1}}); 51 | return xyChart.render().decode(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/java/com/example/PyGalServicePurePython.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import jakarta.inject.Singleton; 10 | 11 | @Singleton 12 | public class PyGalServicePurePython implements PyGalService { 13 | private final String purePythonXY; 14 | 15 | PyGalServicePurePython(GraalPyContext graalPyContext) { 16 | purePythonXY = graalPyContext.eval( 17 | // language=python 18 | """ 19 | import pygal 20 | from math import cos 21 | xy_chart = pygal.XY() 22 | xy_chart.title = 'XY Cosinus' 23 | xy_chart.add('x = cos(y)', [(cos(x / 10.), x / 10.) for x in range(-50, 50, 5)]) 24 | xy_chart.add('y = cos(x)', [(x / 10., cos(x / 10.)) for x in range(-50, 50, 5)]) 25 | xy_chart.add('x = 1', [(1, -5), (1, 5)]) 26 | xy_chart.add('x = -1', [(-1, -5), (-1, 5)]) 27 | xy_chart.add('y = 1', [(-5, 1), (5, 1)]) 28 | xy_chart.add('y = -1', [(-5, -1), (5, -1)]) 29 | xy_chart.render().decode() 30 | """).asString(); 31 | } 32 | 33 | @Override 34 | public String renderXYChart() { 35 | return purePythonXY; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/java/com/example/PyGalServiceValueAPIDynamic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | 10 | import jakarta.inject.Singleton; 11 | import org.graalvm.polyglot.Value; 12 | 13 | import java.util.stream.IntStream; 14 | 15 | @Singleton 16 | public class PyGalServiceValueAPIDynamic implements PyGalService { 17 | private final Value pyGalModule; 18 | 19 | PyGalServiceValueAPIDynamic(GraalPyContext context) { 20 | pyGalModule = context.eval("import pygal; pygal"); 21 | } 22 | 23 | @Override 24 | public String renderXYChart() { 25 | Value xyChart = pyGalModule.invokeMember("XY"); 26 | xyChart.putMember("title", "XY Cosinus"); 27 | xyChart.invokeMember("add", "x = cos(y)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{Math.cos(x / 10.0), x / 10.0}).toArray(double[][]::new)); 28 | xyChart.invokeMember("add", "y = cos(x)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{x / 10.0, Math.cos(x / 10.0)}).toArray(double[][]::new)); 29 | xyChart.invokeMember("add", "x = 1", new int[][]{{1, -5}, {1, 5}}); 30 | xyChart.invokeMember("add", "x = -1", new int[][]{{-1, -5}, {-1, 5}}); 31 | xyChart.invokeMember("add", "y = 1", new int[][]{{-5, 1}, {5, 1}}); 32 | xyChart.invokeMember("add", "y = -1", new int[][]{{-5, -1}, {5, -1}}); 33 | return xyChart.invokeMember("render").invokeMember("decode").asString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/resources/META-INF/native-image/com.example/demo/reachability-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "reflection": [ 3 | { 4 | "type": "com.example.PyGalServiceMixed$Entry" 5 | }, 6 | { 7 | "type": "com.example.PyGalServiceMixed$RenderXYFunction" 8 | }, 9 | { 10 | "type": "com.example.PyGalServicePureJava$BytesIO" 11 | }, 12 | { 13 | "type": "com.example.PyGalServicePureJava$PyGal" 14 | }, 15 | { 16 | "type": "com.example.PyGalServicePureJava$XY" 17 | }, 18 | { 19 | "type": { 20 | "proxy": [ 21 | "com.example.PyGalServiceMixed$RenderXYFunction" 22 | ] 23 | } 24 | }, 25 | { 26 | "type": { 27 | "proxy": [ 28 | "com.example.PyGalServicePureJava$PyGal" 29 | ] 30 | } 31 | }, 32 | { 33 | "type": { 34 | "proxy": [ 35 | "com.example.PyGalServicePureJava$XY" 36 | ] 37 | } 38 | }, 39 | { 40 | "type": { 41 | "proxy": [ 42 | "com.example.PyGalServicePureJava$BytesIO" 43 | ] 44 | } 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 09 12:42:25 UTC 2024 2 | micronaut.application.name=demo 3 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /graalpy/graalpy-micronaut-pygal-charts/src/test/java/com/example/DemoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 10 | import jakarta.inject.Inject; 11 | import org.junit.jupiter.api.Assertions; 12 | import org.junit.jupiter.api.Test; 13 | 14 | import java.util.HashSet; 15 | import java.util.List; 16 | 17 | @MicronautTest 18 | class DemoTest { 19 | 20 | @Inject 21 | private PyGalServicePureJava pyGalServicePureJava; 22 | @Inject 23 | private PyGalServicePurePython pyGalServicePurePython; 24 | @Inject 25 | private PyGalServiceMixed pyGalServiceMixed; 26 | @Inject 27 | private PyGalServiceValueAPIDynamic pyGalServiceValueAPIDynamic; 28 | 29 | @Test 30 | void testIdentity() { 31 | // Patterns to remove unique identifiers that PyGal adds every time a chart is rendered 32 | String identifierPattern = "[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}"; 33 | String chartPattern = "chart-" + identifierPattern; 34 | String pyGalConfigPattern = "pygal\\.config\\['" + identifierPattern + "']"; 35 | 36 | // We use a HashSet to check whether the charts are identical 37 | HashSet xyCharts = new HashSet<>(); 38 | for (PyGalService service : List.of(pyGalServicePureJava, pyGalServicePurePython, pyGalServiceMixed, pyGalServiceValueAPIDynamic)) { 39 | String xyChart = service.renderXYChart(); 40 | String xzChartSanitized = xyChart.replaceAll(chartPattern, "chart").replaceAll(pyGalConfigPattern, "pygal.config"); 41 | xyCharts.add(xzChartSanitized); 42 | } 43 | Assertions.assertEquals(1, xyCharts.size(), "xyCharts are not identical"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /graalpy/graalpy-native-extensions-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-native-extensions-guide/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.example 7 | native-ext 8 | 1.0-SNAPSHOT 9 | jar 10 | fruit-arbitrator 11 | 12 | 13 | 17 14 | 17 15 | UTF-8 16 | 17 | 18 | 19 | 20 | org.graalvm.python 21 | python 22 | 24.2.0 23 | pom 24 | 25 | 26 | 27 | org.graalvm.python 28 | python-embedding 29 | 24.2.0 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.graalvm.python 37 | graalpy-maven-plugin 38 | 24.2.0 39 | 40 | 41 | polyleven==0.8 42 | 43 | 44 | 45 | 46 | 47 | process-graalpy-resources 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /graalpy/graalpy-native-extensions-guide/src/main/java/org/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | package org.example; 7 | 8 | import org.graalvm.polyglot.*; 9 | import org.graalvm.python.embedding.utils.GraalPyResources; 10 | 11 | import java.util.Set; 12 | 13 | public class App { 14 | private static final Set FRUITS = Set.of( 15 | "apple", "banana", "peach", "grape", "orange", 16 | "pear", "mango", "pineapple", "lemon", "lime", "apricot"); // ① 17 | 18 | public static void main(String[] args) { 19 | try (Context context = GraalPyResources.createContext()) { // ② 20 | Value pythonBindings = context.getBindings("python"); // ③ 21 | pythonBindings.putMember("fruits", FRUITS.toArray()); // ④ 22 | 23 | // ⑤ 24 | context.eval("python", """ 25 | import polyleven 26 | def get_similar_word(value): 27 | words = [x for x in fruits if polyleven.levenshtein(x, value) <= 1] # ⑥ 28 | return words[0] if words else None 29 | """); 30 | 31 | 32 | Value getSimilarWord = pythonBindings.getMember("get_similar_word"); // ⑦ 33 | 34 | for (String value : args) { 35 | if (FRUITS.contains(value)) { 36 | System.out.printf("✅ %s%n", value); 37 | } else { 38 | System.out.printf("❌ %s", value); 39 | Value similarWord = getSimilarWord.execute(value); // ⑧ 40 | if (!similarWord.isNull()) { // ⑨ 41 | System.out.printf(" (did you mean '%s')%n", similarWord.asString()); // ⑩ 42 | } else { 43 | System.out.println(); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /graalpy/graalpy-native-extensions-guide/src/main/java/org/example/AppLogging.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | package org.example; 7 | 8 | import org.graalvm.polyglot.Context; 9 | import org.graalvm.polyglot.Value; 10 | import org.graalvm.python.embedding.utils.GraalPyResources; 11 | 12 | import java.util.Set; 13 | 14 | public class AppLogging { 15 | private static final Set FRUITS = Set.of( 16 | "apple", "banana", "peach", "grape", "orange", 17 | "pear", "mango", "pineapple", "lemon", "lime", "apricot"); 18 | 19 | public static void main(String[] args) { 20 | try (Context context = GraalPyResources.contextBuilder() 21 | .option("log.python.capi.level", "WARNING") // ① 22 | .option("python.WarnExperimentalFeatures", "true") // ② 23 | .build()) { 24 | Value pythonBindings = context.getBindings("python"); 25 | pythonBindings.putMember("fruits", FRUITS.toArray()); 26 | 27 | context.eval("python", """ 28 | import polyleven 29 | def get_similar_word(value): 30 | words = [x for x in fruits if polyleven.levenshtein(x, value) <= 1] 31 | return words[0] if words else None 32 | """); 33 | 34 | 35 | Value getSimilarWord = pythonBindings.getMember("get_similar_word"); 36 | 37 | for (String value : args) { 38 | if (FRUITS.contains(value)) { 39 | System.out.printf("✅ %s%n", value); 40 | } else { 41 | System.out.printf("❌ %s", value); 42 | Value similarWord = getSimilarWord.execute(value); 43 | if (!similarWord.isNull()) { 44 | System.out.printf(" (did you mean '%s')%n", similarWord.asString()); 45 | } else { 46 | System.out.println(); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /graalpy/graalpy-native-extensions-guide/src/main/java/org/example/MultiContextApp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | package org.example; 7 | 8 | import org.graalvm.polyglot.*; 9 | import org.graalvm.python.embedding.utils.GraalPyResources; 10 | 11 | import java.util.Set; 12 | 13 | public class MultiContextApp { 14 | private static final Set FRUITS = Set.of( 15 | "apple", "banana", "peach", "grape", "orange", 16 | "pear", "mango", "pineapple", "lemon", "lime", "apricot"); 17 | 18 | public static String getSimilarWord(String value) { 19 | try (Context context = GraalPyResources.contextBuilder().build()) { 20 | context.eval("python", """ 21 | import polyleven 22 | def get_similar_word(value): 23 | words = [x for x in fruits if polyleven.levenshtein(x, value) <= 1] 24 | return words[0] if words else None 25 | """); 26 | 27 | Value pythonBindings = context.getBindings("python"); 28 | pythonBindings.putMember("fruits", FRUITS.toArray()); 29 | Value result = pythonBindings 30 | .getMember("get_similar_word") 31 | .execute(value); 32 | return result.isNull() ? null : result.asString(); 33 | } 34 | } 35 | 36 | public static void main(String[] args) { 37 | for (String value : args) { 38 | if (FRUITS.contains(value)) { 39 | System.out.printf("✅ %s%n", value); 40 | } else { 41 | System.out.printf("❌ %s", value); 42 | String similarWord = getSimilarWord(value); 43 | if (similarWord != null) { 44 | System.out.printf(" (did you mean '%s')%n", similarWord); 45 | } else { 46 | System.out.println(); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /graalpy/graalpy-openai-starter/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | 10 | # Binary files should be left untouched 11 | *.jar binary 12 | 13 | -------------------------------------------------------------------------------- /graalpy/graalpy-openai-starter/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | 7 | # Ignore maven build output directory 8 | target 9 | -------------------------------------------------------------------------------- /graalpy/graalpy-openai-starter/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-openai-starter/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | // Apply the application plugin to add support for building a CLI application in Java. 3 | application 4 | // Apply GraalPy plugin to add Python packages as dependencies. 5 | id("org.graalvm.python") version "24.2.0" 6 | } 7 | 8 | repositories { 9 | // Use Maven Central for resolving dependencies. 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | // Use JUnit Jupiter for testing. 15 | testImplementation("org.junit.jupiter:junit-jupiter:5.11.0") 16 | 17 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 18 | } 19 | 20 | graalPy { 21 | packages = setOf( 22 | "annotated-types==0.7.0", 23 | "anyio==4.6.0", 24 | "certifi==2024.8.30", 25 | "distro==1.9.0", 26 | "h11==0.14.0", 27 | "hpy==0.9.0", 28 | "httpcore==1.0.5", 29 | "httpx==0.27.2", 30 | "idna==3.10", 31 | "jiter==0.5.0", // uses a native extension 32 | "openai==1.47.1", 33 | "pydantic==2.4.2", 34 | "pydantic_core==2.10.1", // uses a native extension 35 | "sniffio==1.3.1", 36 | "tqdm==4.66.5", 37 | "typing_extensions==4.12.2" 38 | ) 39 | } 40 | 41 | application { 42 | // Define the main class for the application. 43 | mainClass = "com.example.App" 44 | } 45 | 46 | tasks.named("test") { 47 | // Use JUnit Platform for unit tests. 48 | useJUnitPlatform() 49 | } 50 | -------------------------------------------------------------------------------- /graalpy/graalpy-openai-starter/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-openai-starter/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalpy/graalpy-openai-starter/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-openai-starter/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "graalpy-openai-starter" 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-openai-starter/src/test/java/com/example/AppTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 12 | import static org.junit.jupiter.api.Assumptions.assumeTrue; 13 | 14 | class AppTest { 15 | @Test 16 | void appRuns() { 17 | assumeTrue(System.getenv("OPENAI_API_KEY") != null, "The OPENAI_API_KEY environment variable must be set"); 18 | assertDoesNotThrow(() -> App.main(new String[0])); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | 10 | # Binary files should be left untouched 11 | *.jar binary 12 | 13 | -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | 7 | # Ignore maven build output directory 8 | target 9 | 10 | # Ignore JDTLS build directory 11 | bin -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-python.python", 4 | "vscjava.vscode-java-pack" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [{ 3 | "name": "GraalPy: Attach embedded", 4 | "type": "debugpy", 5 | "request": "attach", 6 | "connect": { "host": "localhost", "port": 4711 }, 7 | }] 8 | } -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | application; 3 | id("org.openjfx.javafxplugin") version "0.1.0" 4 | } 5 | 6 | javafx { 7 | version = "23.0.1" 8 | modules = listOf("javafx.controls") 9 | } 10 | 11 | repositories { 12 | // Use Maven Central for resolving dependencies. 13 | mavenCentral() 14 | } 15 | 16 | dependencies { 17 | implementation("org.graalvm.polyglot:python:24.2.0") // ① 18 | implementation("org.graalvm.polyglot:polyglot:24.2.0") // ③ 19 | implementation("org.graalvm.tools:dap-tool:24.2.0") // ④ 20 | } 21 | 22 | application { 23 | // Define the main class for the application. 24 | mainClass = "com.example.App" 25 | } 26 | -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/graalpy-vscode-dap-debug.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-scripts-debug-guide/graalpy-vscode-dap-debug.gif -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/graalpy-vscode-debug.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-scripts-debug-guide/graalpy-vscode-debug.gif -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/graalpy-vscode-pip-install.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-scripts-debug-guide/graalpy-vscode-pip-install.gif -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/graalpy-vscode-pyenv.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-scripts-debug-guide/graalpy-vscode-pyenv.gif -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/graalpy-vscode-select.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-scripts-debug-guide/graalpy-vscode-select.gif -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-scripts-debug-guide/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-scripts-debug-guide/screenshot.png -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "graalpy-python-script-embedding" 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-scripts-debug-guide/src/main/resources/compare_files.py: -------------------------------------------------------------------------------- 1 | import polyglot # pyright: ignore 2 | 3 | from difflib import SequenceMatcher 4 | from os import PathLike 5 | 6 | 7 | @polyglot.export_value # ① 8 | def compare_files(a: PathLike, b: PathLike) -> float: 9 | with open(a) as file_1, open(b) as file_2: 10 | file1_data = file_1.read() 11 | file2_data = file_2.read() 12 | similarity_ratio = SequenceMatcher(None, file1_data, file2_data).ratio() 13 | return similarity_ratio 14 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.graalvm.python' version '24.2.0' 3 | // ... 4 | id 'java' 5 | id 'org.springframework.boot' version '3.3.5' 6 | id 'io.spring.dependency-management' version '1.1.6' 7 | id 'org.graalvm.buildtools.native' version '0.10.3' 8 | } 9 | 10 | graalPy { 11 | packages = [ // ① 12 | 'vader-sentiment==3.2.1.1', // ② 13 | 'requests' // ③ 14 | ] 15 | } 16 | 17 | group = 'com.example' 18 | version = '0.0.1-SNAPSHOT' 19 | 20 | java { 21 | toolchain { 22 | languageVersion = JavaLanguageVersion.of(17) 23 | } 24 | } 25 | 26 | repositories { 27 | mavenCentral() 28 | } 29 | 30 | dependencies { 31 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 32 | implementation 'org.springframework.boot:spring-boot-starter-web' 33 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 34 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher' 35 | } 36 | 37 | tasks.named('test') { 38 | useJUnitPlatform() 39 | } 40 | 41 | test { 42 | systemProperty "spring.mvc.async.request-timeout", System.getProperty("spring.mvc.async.request-timeout") 43 | } 44 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-spring-boot-guide/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-spring-boot-guide/screenshot.png -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'demo' 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | 12 | @SpringBootApplication 13 | public class DemoApplication { 14 | public static void main(String[] args) { 15 | SpringApplication.run(DemoApplication.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/src/main/java/com/example/demo/DemoController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.util.Map; 13 | 14 | @Controller 15 | public class DemoController { 16 | private final SentimentAnalysisService sentimentAnalysisService; // ① 17 | 18 | public DemoController(SentimentAnalysisService sentimentAnalysisService) { 19 | this.sentimentAnalysisService = sentimentAnalysisService; 20 | } 21 | 22 | @GetMapping("/") 23 | public String answer() { // ② 24 | return "index"; 25 | } 26 | 27 | @GetMapping(value = "/analyze", produces = "application/json") 28 | @ResponseBody 29 | public Map answer(@RequestParam String text) { // ③ 30 | return sentimentAnalysisService.getSentimentScore(text); // ④ 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/src/main/java/com/example/demo/GraalPyContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import jakarta.annotation.PreDestroy; 10 | import org.graalvm.polyglot.Context; 11 | import org.graalvm.polyglot.Value; 12 | import org.graalvm.python.embedding.utils.GraalPyResources; 13 | import org.springframework.stereotype.Component; 14 | 15 | @Component // ① 16 | public class GraalPyContext { 17 | static final String PYTHON = "python"; 18 | 19 | private final Context context; 20 | 21 | public GraalPyContext() { 22 | context = GraalPyResources.contextBuilder().build(); // ② 23 | context.initialize(PYTHON); // ③ 24 | } 25 | 26 | public Value eval(String source) { 27 | return context.eval(PYTHON, source); // ④ 28 | } 29 | 30 | @PreDestroy 31 | public void close() { 32 | context.close(true); // ⑤ 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/src/main/java/com/example/demo/SentimentAnalysisService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.Map; 12 | 13 | @Service 14 | public class SentimentAnalysisService { 15 | private final SentimentIntensityAnalyzer sentimentIntensityAnalyzer; 16 | 17 | public SentimentAnalysisService(GraalPyContext context) { 18 | var value = context.eval(""" 19 | from vader_sentiment.vader_sentiment import SentimentIntensityAnalyzer 20 | SentimentIntensityAnalyzer() # ① 21 | """); 22 | sentimentIntensityAnalyzer = value.as(SentimentIntensityAnalyzer.class); // ② 23 | } 24 | 25 | public Map getSentimentScore(String text) { 26 | return sentimentIntensityAnalyzer.polarity_scores(text); // ③ 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/src/main/java/com/example/demo/SentimentIntensityAnalyzer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import java.util.Map; 10 | 11 | public interface SentimentIntensityAnalyzer { 12 | Map polarity_scores(String text); // ① 13 | } 14 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/src/main/resources/META-INF/native-image/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ["com.example.demo.SentimentIntensityAnalyzer"] 3 | ] 4 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=demo 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-guide/src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.junit.jupiter.api.Test; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 12 | import org.springframework.boot.test.context.SpringBootTest; 13 | import org.springframework.test.annotation.DirtiesContext; 14 | import org.springframework.test.web.servlet.MockMvc; 15 | 16 | import static org.hamcrest.Matchers.greaterThan; 17 | import static org.hamcrest.Matchers.lessThan; 18 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 19 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 20 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 21 | 22 | @SpringBootTest 23 | @AutoConfigureMockMvc 24 | @DirtiesContext // Necessary to shut down GraalPy context 25 | class DemoApplicationTests { 26 | 27 | @Autowired 28 | private MockMvc mockMvc; // ① 29 | 30 | @Test 31 | void testIndex() throws Exception { // ② 32 | mockMvc.perform(get("/")).andExpect(status().isOk()); 33 | } 34 | 35 | @Test 36 | void testSentimentAnalysis() throws Exception { // ③ 37 | mockMvc.perform(get("/analyze").param("text", "I'm happy")) 38 | .andExpect(status().isOk()) 39 | .andExpect(jsonPath("$.compound", greaterThan(0.1))); 40 | mockMvc.perform(get("/analyze").param("text", "This sucks")) 41 | .andExpect(status().isOk()) 42 | .andExpect(jsonPath("$.compound", lessThan(-0.1))); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | 12 | @SpringBootApplication 13 | public class DemoApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(DemoApplication.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/java/com/example/demo/DemoController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | @RestController 13 | public class DemoController { 14 | 15 | private final PyGalServicePurePython pyGalServicePurePython; 16 | private final PyGalServicePureJava pyGalServicePureJava; 17 | private final PyGalServiceMixed pyGalServiceMixed; 18 | private final PyGalServiceValueAPIDynamic pyGalServiceValueAPIDynamic; 19 | 20 | public DemoController(PyGalServicePurePython pyGalServicePurePython, PyGalServicePureJava pyGalServicePureJava, PyGalServiceMixed pyGalServiceMixed, PyGalServiceValueAPIDynamic pyGalServiceValueAPIDynamic) { 21 | this.pyGalServicePurePython = pyGalServicePurePython; 22 | this.pyGalServicePureJava = pyGalServicePureJava; 23 | this.pyGalServiceMixed = pyGalServiceMixed; 24 | this.pyGalServiceValueAPIDynamic = pyGalServiceValueAPIDynamic; 25 | } 26 | 27 | @GetMapping(value = "/python", produces = "image/svg+xml") 28 | public String renderXYChartPurePython() { 29 | return pyGalServicePurePython.renderXYChart(); 30 | } 31 | 32 | @GetMapping(value = "/java", produces = "image/svg+xml") 33 | public String renderXYChartPureJava() { 34 | return pyGalServicePureJava.renderXYChart(); 35 | } 36 | 37 | @GetMapping(value = "/mixed", produces = "image/svg+xml") 38 | public String renderXYChartMixed() { 39 | return pyGalServiceMixed.renderXYChart(); 40 | } 41 | 42 | @GetMapping(value = "/dynamic", produces = "image/svg+xml") 43 | public String renderXYChartValueAPIDynamic() { 44 | return pyGalServiceValueAPIDynamic.renderXYChart(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/java/com/example/demo/GraalPyContextConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.graalvm.polyglot.Context; 10 | import org.graalvm.polyglot.Value; 11 | import org.graalvm.python.embedding.utils.GraalPyResources; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | 15 | @Configuration 16 | public class GraalPyContextConfiguration { 17 | /* 18 | * Make GraalPy context available for injection as a Spring bean. 19 | */ 20 | @Bean(destroyMethod = "close") 21 | public GraalPyContext graalPyContext() { 22 | Context context = GraalPyResources.createContext(); 23 | context.initialize("python"); 24 | return new GraalPyContext(context); 25 | } 26 | 27 | public record GraalPyContext(Context context) { 28 | public Value eval(String source) { 29 | return context.eval("python", source); 30 | } 31 | 32 | public void close() { 33 | context.close(true); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/java/com/example/demo/PyGalService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | /** 10 | * Example PyGal code: 11 | *
12 |  *     from math import cos
13 |  *     xy_chart = pygal.XY()
14 |  *     xy_chart.title = 'XY Cosinus'
15 |  *     xy_chart.add('x = cos(y)', [(cos(x / 10.), x / 10.) for x in range(-50, 50, 5)])
16 |  *     xy_chart.add('y = cos(x)', [(x / 10., cos(x / 10.)) for x in range(-50, 50, 5)])
17 |  *     xy_chart.add('x = 1',  [(1, -5), (1, 5)])
18 |  *     xy_chart.add('x = -1', [(-1, -5), (-1, 5)])
19 |  *     xy_chart.add('y = 1',  [(-5, 1), (5, 1)])
20 |  *     xy_chart.add('y = -1', [(-5, -1), (5, -1)])
21 |  *     xy_chart.render()
22 |  * 
23 | */ 24 | interface PyGalService { 25 | String renderXYChart(); 26 | } -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/java/com/example/demo/PyGalServicePureJava.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import com.example.demo.GraalPyContextConfiguration.GraalPyContext; 10 | import org.graalvm.polyglot.Value; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.stream.IntStream; 14 | 15 | 16 | @Service 17 | public class PyGalServicePureJava implements PyGalService { 18 | private final PyGal pyGalModule; 19 | 20 | PyGalServicePureJava(GraalPyContext graalPyContext) { 21 | pyGalModule = graalPyContext.eval("import pygal; pygal").as(PyGal.class); 22 | } 23 | 24 | public interface PyGal { 25 | XY XY(); 26 | } 27 | 28 | public interface XY { 29 | default void title(String title) { 30 | Value.asValue(this).putMember("title", title); 31 | } 32 | 33 | void add(String label, Object[] values); 34 | 35 | BytesIO render(); 36 | } 37 | 38 | public interface BytesIO { 39 | String decode(); 40 | } 41 | 42 | @Override 43 | public String renderXYChart() { 44 | XY xyChart = pyGalModule.XY(); 45 | xyChart.title("XY Cosinus"); 46 | xyChart.add("x = cos(y)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{Math.cos(x / 10.0), x / 10.0}).toArray(double[][]::new)); 47 | xyChart.add("y = cos(x)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{x / 10.0, Math.cos(x / 10.0)}).toArray(double[][]::new)); 48 | xyChart.add("x = 1", new int[][]{{1, -5}, {1, 5}}); 49 | xyChart.add("x = -1", new int[][]{{-1, -5}, {-1, 5}}); 50 | xyChart.add("y = 1", new int[][]{{-5, 1}, {5, 1}}); 51 | xyChart.add("y = -1", new int[][]{{-5, -1}, {5, -1}}); 52 | return xyChart.render().decode(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/java/com/example/demo/PyGalServicePurePython.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import com.example.demo.GraalPyContextConfiguration.GraalPyContext; 10 | import org.springframework.stereotype.Service; 11 | 12 | @Service 13 | public class PyGalServicePurePython implements PyGalService { 14 | private final String purePythonXY; 15 | 16 | PyGalServicePurePython(GraalPyContext graalPyContext) { 17 | purePythonXY = graalPyContext.eval( 18 | // language=python 19 | """ 20 | import pygal 21 | from math import cos 22 | xy_chart = pygal.XY() 23 | xy_chart.title = 'XY Cosinus' 24 | xy_chart.add('x = cos(y)', [(cos(x / 10.), x / 10.) for x in range(-50, 50, 5)]) 25 | xy_chart.add('y = cos(x)', [(x / 10., cos(x / 10.)) for x in range(-50, 50, 5)]) 26 | xy_chart.add('x = 1', [(1, -5), (1, 5)]) 27 | xy_chart.add('x = -1', [(-1, -5), (-1, 5)]) 28 | xy_chart.add('y = 1', [(-5, 1), (5, 1)]) 29 | xy_chart.add('y = -1', [(-5, -1), (5, -1)]) 30 | xy_chart.render().decode() 31 | """).asString(); 32 | } 33 | 34 | @Override 35 | public String renderXYChart() { 36 | return purePythonXY; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/java/com/example/demo/PyGalServiceValueAPIDynamic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | 10 | import com.example.demo.GraalPyContextConfiguration.GraalPyContext; 11 | import org.graalvm.polyglot.Value; 12 | import org.springframework.stereotype.Service; 13 | 14 | import java.util.stream.IntStream; 15 | 16 | @Service 17 | public class PyGalServiceValueAPIDynamic implements PyGalService { 18 | private final Value pyGalModule; 19 | 20 | PyGalServiceValueAPIDynamic(GraalPyContext context) { 21 | pyGalModule = context.eval("import pygal; pygal"); 22 | } 23 | 24 | @Override 25 | public String renderXYChart() { 26 | Value xyChart = pyGalModule.invokeMember("XY"); 27 | xyChart.putMember("title", "XY Cosinus"); 28 | xyChart.invokeMember("add", "x = cos(y)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{Math.cos(x / 10.0), x / 10.0}).toArray(double[][]::new)); 29 | xyChart.invokeMember("add", "y = cos(x)", IntStream.range(-50, 50).filter(x -> x % 5 == 0).mapToObj(x -> new double[]{x / 10.0, Math.cos(x / 10.0)}).toArray(double[][]::new)); 30 | xyChart.invokeMember("add", "x = 1", new int[][]{{1, -5}, {1, 5}}); 31 | xyChart.invokeMember("add", "x = -1", new int[][]{{-1, -5}, {-1, 5}}); 32 | xyChart.invokeMember("add", "y = 1", new int[][]{{-5, 1}, {5, 1}}); 33 | xyChart.invokeMember("add", "y = -1", new int[][]{{-5, -1}, {5, -1}}); 34 | return xyChart.invokeMember("render").invokeMember("decode").asString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/resources/META-INF/native-image/com.example/demo/reachability-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "reflection": [ 3 | { 4 | "type": "com.example.demo.PyGalServiceMixed$Entry" 5 | }, 6 | { 7 | "type": "com.example.demo.PyGalServiceMixed$RenderXYFunction" 8 | }, 9 | { 10 | "type": "com.example.demo.PyGalServicePureJava$BytesIO" 11 | }, 12 | { 13 | "type": "com.example.demo.PyGalServicePureJava$PyGal" 14 | }, 15 | { 16 | "type": "com.example.demo.PyGalServicePureJava$XY" 17 | }, 18 | { 19 | "type": { 20 | "proxy": [ 21 | "com.example.demo.PyGalServiceMixed$RenderXYFunction" 22 | ] 23 | } 24 | }, 25 | { 26 | "type": { 27 | "proxy": [ 28 | "com.example.demo.PyGalServicePureJava$PyGal" 29 | ] 30 | } 31 | }, 32 | { 33 | "type": { 34 | "proxy": [ 35 | "com.example.demo.PyGalServicePureJava$XY" 36 | ] 37 | } 38 | }, 39 | { 40 | "type": { 41 | "proxy": [ 42 | "com.example.demo.PyGalServicePureJava$BytesIO" 43 | ] 44 | } 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=demo 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-spring-boot-pygal-charts/src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.junit.jupiter.api.Assertions; 10 | import org.junit.jupiter.api.Test; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.boot.test.context.SpringBootTest; 13 | 14 | import java.util.HashSet; 15 | import java.util.List; 16 | 17 | @SpringBootTest 18 | class DemoApplicationTests { 19 | 20 | @Autowired 21 | private PyGalServicePureJava pyGalServicePureJava; 22 | @Autowired 23 | private PyGalServicePurePython pyGalServicePurePython; 24 | @Autowired 25 | private PyGalServiceMixed pyGalServiceMixed; 26 | @Autowired 27 | private PyGalServiceValueAPIDynamic pyGalServiceValueAPIDynamic; 28 | 29 | @Test 30 | void testIdentity() { 31 | // Patterns to remove unique identifiers that PyGal adds every time a chart is rendered 32 | String identifierPattern = "[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}"; 33 | String chartPattern = "chart-" + identifierPattern; 34 | String pyGalConfigPattern = "pygal\\.config\\['" + identifierPattern + "']"; 35 | 36 | // We use a HashSet to check whether the charts are identical 37 | HashSet xyCharts = new HashSet<>(); 38 | for (PyGalService service : List.of(pyGalServicePureJava, pyGalServicePurePython, pyGalServiceMixed, pyGalServiceValueAPIDynamic)) { 39 | String xyChart = service.renderXYChart(); 40 | String xzChartSanitized = xyChart.replaceAll(chartPattern, "chart").replaceAll(pyGalConfigPattern, "pygal.config"); 41 | xyCharts.add(xzChartSanitized); 42 | } 43 | Assertions.assertEquals(1, xyCharts.size(), "xyCharts are not identical"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | 10 | # Binary files should be left untouched 11 | *.jar binary 12 | 13 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | 7 | # Ignore maven build output directory 8 | target 9 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/README.md: -------------------------------------------------------------------------------- 1 | # GraalPy Quick Start 2 | 3 | A minimal Java application that embeds Python code with GraalPy. 4 | 5 | ## Preparation 6 | 7 | Install GraalVM for JDK 24 and set the value of `JAVA_HOME` accordingly. 8 | We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).) 9 | 10 | ```bash 11 | sdk install java 24-graal 12 | ``` 13 | 14 | ## Run the Application Using Maven 15 | 16 | To build and test the demo, run: 17 | 18 | ```bash 19 | ./mvnw test 20 | ``` 21 | 22 | To execute the main method, run: 23 | 24 | ```bash 25 | ./mvnw exec:java 26 | ``` 27 | 28 | ## Run the Application Using Gradle 29 | 30 | To build and test the demo, run: 31 | 32 | ```bash 33 | ./gradlew test 34 | ``` 35 | 36 | To execute the main method, run: 37 | 38 | ```bash 39 | ./gradlew run 40 | ``` 41 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | // Apply the application plugin to add support for building a CLI application in Java. 3 | application 4 | } 5 | 6 | repositories { 7 | // Use Maven Central for resolving dependencies. 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | implementation("org.graalvm.polyglot:polyglot:24.2.0") 13 | implementation("org.graalvm.polyglot:python:24.2.0") 14 | 15 | // Use JUnit Jupiter for testing. 16 | testImplementation("org.junit.jupiter:junit-jupiter:5.11.0") 17 | 18 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 19 | } 20 | 21 | application { 22 | // Define the main class for the application. 23 | mainClass = "com.example.App" 24 | } 25 | 26 | tasks.named("test") { 27 | // Use JUnit Platform for unit tests. 28 | useJUnitPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalpy/graalpy-starter/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalpy/graalpy-starter/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "graalpy-starter" 2 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/src/main/java/com/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import org.graalvm.polyglot.Context; 10 | import org.graalvm.polyglot.io.IOAccess; 11 | 12 | public class App { 13 | 14 | public static void main(String[] args) { 15 | try (Context context = Context.newBuilder("python") 16 | /* Enabling some of these is needed for various standard library modules */ 17 | .allowNativeAccess(false) 18 | .allowCreateThread(false) 19 | .allowIO(IOAccess.newBuilder() 20 | .allowHostFileAccess(false) 21 | .allowHostSocketAccess(false) 22 | .build()) 23 | .build()) { 24 | context.eval("python", "print('Hello from GraalPy!')"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /graalpy/graalpy-starter/src/test/java/com/example/AppTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 12 | 13 | class AppTest { 14 | @Test 15 | void appRuns() { 16 | assertDoesNotThrow(() -> App.main(new String[0])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /graalwasm/README.md: -------------------------------------------------------------------------------- 1 | # GraalWasm Demos and Guides 2 | 3 | This directory contains demo applications and guides for [GraalWasm](https://www.graalvm.org/webassembly/). 4 | 5 | *Tip: open this directory in IntellIJ IDEA. It should offer to load all Maven projects.* 6 | 7 | ## Demos 8 | 9 | - [Minimal Java application that embeds GraalWasm](graalwasm-starter/) 10 | - [Embed Photon image processing library with GraalWasm in Micronaut](graalwasm-micronaut-photon/) 11 | - [Embed Photon image processing library with GraalWasm in Spring Boot](graalwasm-spring-boot-photon/) 12 | 13 | ## Guides 14 | 15 | - [Embed C in Java Using GraalWasm](graalwasm-embed-c-code-guide/) 16 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-embed-c-code-guide/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore maven build output directory 2 | target 3 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-embed-c-code-guide/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-embed-c-code-guide/src/main/c/floyd.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void floyd() { 4 | int number = 1; 5 | int rows = 10; 6 | for (int i = 1; i <= rows; i++) { 7 | for (int j = 1; j <= i; j++) { 8 | printf("%d ", number); 9 | ++number; 10 | } 11 | printf(".\n"); 12 | } 13 | } 14 | 15 | int main() { 16 | floyd(); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-embed-c-code-guide/src/main/java/com/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import java.io.IOException; 10 | import java.net.URL; 11 | 12 | import org.graalvm.polyglot.Context; 13 | import org.graalvm.polyglot.Source; 14 | import org.graalvm.polyglot.Value; 15 | 16 | public class App { 17 | public static void main(String[] args) throws IOException { 18 | // Find the WebAssembly module resource 19 | URL wasmFile = App.class.getResource("floyd.wasm"); 20 | 21 | // Setup context 22 | Context.Builder contextBuilder = Context.newBuilder("wasm").option("wasm.Builtins", "wasi_snapshot_preview1"); 23 | Source.Builder sourceBuilder = Source.newBuilder("wasm", wasmFile).name("example"); 24 | Source source = sourceBuilder.build(); 25 | Context context = contextBuilder.build(); 26 | 27 | // Evaluate the WebAssembly module 28 | context.eval(source); 29 | 30 | // Execute the floyd function 31 | context.getBindings("wasm").getMember("example").getMember("_initialize").executeVoid(); 32 | Value mainFunction = context.getBindings("wasm").getMember("example").getMember("floyd"); 33 | mainFunction.execute(); 34 | context.close(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-embed-c-code-guide/src/test/java/com/example/AppTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import org.junit.jupiter.api.Test; 10 | import static org.junit.jupiter.api.Assertions.*; 11 | 12 | class AppTest { 13 | @Test 14 | void appRuns() { 15 | assertDoesNotThrow(() -> App.main(new String[0])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/aot-jar.properties: -------------------------------------------------------------------------------- 1 | # AOT configuration properties for jar packaging 2 | # Please review carefully the optimizations enabled below 3 | # Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details 4 | 5 | # Caches environment property values: environment properties will be deemed immutable after application startup. 6 | cached.environment.enabled=true 7 | 8 | # Precomputes Micronaut configuration property keys from the current environment variables 9 | precompute.environment.properties.enabled=true 10 | 11 | # Replaces logback.xml with a pure Java configuration 12 | logback.xml.to.java.enabled=true 13 | 14 | # Converts YAML configuration files to Java configuration 15 | yaml.to.java.config.enabled=true 16 | 17 | # Scans for service types ahead-of-time, avoiding classpath scanning at startup 18 | serviceloading.jit.enabled=true 19 | 20 | # Scans reactive types at build time instead of runtime 21 | scan.reactive.types.enabled=true 22 | 23 | # Deduces the environment at build time instead of runtime 24 | deduce.environment.enabled=true 25 | 26 | # Checks for the existence of some types at build time instead of runtime 27 | known.missing.types.enabled=true 28 | 29 | # Precomputes property sources at build time 30 | sealed.property.source.enabled=true 31 | 32 | # The list of service types to be scanned (comma separated) 33 | service.types=io.micronaut.context.env.PropertySourceLoader,io.micronaut.inject.BeanConfiguration,io.micronaut.inject.BeanDefinitionReference,io.micronaut.http.HttpRequestFactory,io.micronaut.http.HttpResponseFactory,io.micronaut.core.beans.BeanIntrospectionReference,io.micronaut.core.convert.TypeConverterRegistrar,io.micronaut.context.env.PropertyExpressionResolver 34 | 35 | # A list of types that the AOT analyzer needs to check for existence (comma separated) 36 | known.missing.types.list=io.reactivex.Observable,reactor.core.publisher.Flux,kotlinx.coroutines.flow.Flow,io.reactivex.rxjava3.core.Flowable,io.reactivex.rxjava3.core.Observable,io.reactivex.Single,reactor.core.publisher.Mono,io.reactivex.Maybe,io.reactivex.rxjava3.core.Single,io.reactivex.rxjava3.core.Maybe,io.reactivex.Completable,io.reactivex.rxjava3.core.Completable,io.methvin.watchservice.MacOSXListeningWatchService,io.micronaut.core.async.publisher.CompletableFuturePublisher,io.micronaut.core.async.publisher.Publishers.JustPublisher,io.micronaut.core.async.subscriber.Completable 37 | 38 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/micronaut-cli.yml: -------------------------------------------------------------------------------- 1 | applicationType: default 2 | defaultPackage: com.example 3 | testFramework: junit 4 | sourceLanguage: java 5 | buildTool: maven 6 | features: [app-name, http-client-test, java, java-application, junit, logback, maven, maven-enforcer-plugin, micronaut-aot, micronaut-http-validation, netty-server, properties, readme, serialization-jackson, shade, static-resources] 7 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/src/main/java/com/example/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import io.micronaut.runtime.Micronaut; 10 | 11 | public class Application { 12 | 13 | public static void main(String[] args) { 14 | Micronaut.run(Application.class, args); 15 | } 16 | } -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/src/main/java/com/example/DemoController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import io.micronaut.context.annotation.Parameter; 10 | import io.micronaut.http.HttpResponse; 11 | import io.micronaut.http.MediaType; 12 | import io.micronaut.http.annotation.Controller; 13 | import io.micronaut.http.annotation.Get; 14 | import io.micronaut.http.annotation.Produces; 15 | import io.micronaut.scheduling.TaskExecutors; 16 | import io.micronaut.scheduling.annotation.ExecuteOn; 17 | 18 | import java.net.URI; 19 | import java.net.URISyntaxException; 20 | 21 | @Controller 22 | public class DemoController { 23 | private final PhotonService photonService; 24 | 25 | public DemoController(PhotonService photonService) { 26 | this.photonService = photonService; 27 | } 28 | 29 | @Get("/photo/{effectName}") 30 | @Produces(MediaType.IMAGE_PNG) 31 | @ExecuteOn(TaskExecutors.BLOCKING) 32 | public byte[] renderPhoto(@Parameter String effectName) { 33 | return photonService.processImage(effectName); 34 | } 35 | 36 | @Get("/") 37 | public HttpResponse index() throws URISyntaxException { 38 | return HttpResponse.redirect(new URI("/index.html")); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/src/main/java/com/example/Photon.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import org.graalvm.polyglot.Value; 10 | import org.graalvm.polyglot.io.ByteSequence; 11 | 12 | public record Photon(Value module, Value imageContent) { 13 | 14 | boolean implementsEffect(String effectName) { 15 | return module.hasMember(effectName); 16 | } 17 | 18 | void applyEffect(String effectName, PhotonImage image) { 19 | module.invokeMember(effectName, image); 20 | } 21 | 22 | PhotonImage createImage() { 23 | return module.getMember("PhotonImage").invokeMember("new_from_byteslice", imageContent).as(PhotonImage.class); 24 | } 25 | 26 | public interface PhotonImage { 27 | void free(); 28 | } 29 | 30 | public static byte[] toByteArray(PhotonImage photonImage) { 31 | return Value.asValue(photonImage).invokeMember("get_bytes").getMember("buffer").as(ByteSequence.class).toByteArray(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/src/main/java/com/example/PhotonService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import io.micronaut.http.HttpStatus; 10 | import io.micronaut.http.exceptions.HttpStatusException; 11 | import jakarta.inject.Singleton; 12 | 13 | @Singleton 14 | public class PhotonService { 15 | private final PhotonPool photonPool; 16 | 17 | PhotonService(PhotonPool photonPool) { 18 | this.photonPool = photonPool; 19 | } 20 | 21 | public byte[] processImage(String effectName) { 22 | Photon photon = photonPool.take(); 23 | try { 24 | if (!photon.implementsEffect(effectName)) { 25 | throw new HttpStatusException(HttpStatus.NOT_FOUND, "Effect " + effectName + " not found in Photon"); 26 | } 27 | Photon.PhotonImage image = photon.createImage(); 28 | photon.applyEffect(effectName, image); 29 | byte[] result = Photon.toByteArray(image); 30 | image.free(); 31 | return result; 32 | } finally { 33 | photonPool.release(photon); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/src/main/resources/META-INF/native-image/com.example/demo/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "interfaces": [ 4 | "com.example.Photon$PhotonImage" 5 | ] 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | micronaut.application.name=demo 2 | micronaut.router.static-resources.default.paths=classpath:static 3 | micronaut.router.static-resources.default.mapping=/*.html 4 | micronaut.router.static-resources.default.enabled=true 5 | 6 | micronaut.server.cors.enabled=true 7 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-micronaut-photon/src/test/java/com/example/DemoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 10 | import jakarta.inject.Inject; 11 | import org.junit.jupiter.api.Assertions; 12 | import org.junit.jupiter.api.Test; 13 | 14 | @MicronautTest 15 | class DemoTest { 16 | 17 | @Inject 18 | private PhotonService photonService; 19 | 20 | @Test 21 | void testEffectEquality() { 22 | for (String effectName : new String[]{"default", "grayscale", "flipv", "fliph"}) { 23 | byte[] imageContent1 = photonService.processImage(effectName); 24 | byte[] imageContent2 = photonService.processImage(effectName); 25 | Assertions.assertArrayEquals(imageContent1, imageContent2, "Two processed images not identical when effect '%s' is used".formatted(effectName)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-spring-boot-photon/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-spring-boot-photon/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | 12 | @SpringBootApplication 13 | public class DemoApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(DemoApplication.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-spring-boot-photon/src/main/java/com/example/demo/DemoController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | public class DemoController { 15 | private final PhotonService photonService; 16 | 17 | public DemoController(PhotonService photonService) { 18 | this.photonService = photonService; 19 | } 20 | 21 | @GetMapping(value = "/photo/{effectName}", produces = "image/png") 22 | public byte[] renderPhoto(@PathVariable String effectName) { 23 | return photonService.processImage(effectName); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-spring-boot-photon/src/main/java/com/example/demo/Photon.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.graalvm.polyglot.Value; 10 | import org.graalvm.polyglot.io.ByteSequence; 11 | 12 | public record Photon(Value module, Value imageContent) { 13 | 14 | boolean implementsEffect(String effectName) { 15 | return module.hasMember(effectName); 16 | } 17 | 18 | void applyEffect(String effectName, PhotonImage image) { 19 | module.invokeMember(effectName, image); 20 | } 21 | 22 | PhotonImage createImage() { 23 | return module.getMember("PhotonImage").invokeMember("new_from_byteslice", imageContent).as(PhotonImage.class); 24 | } 25 | 26 | public interface PhotonImage { 27 | void free(); 28 | } 29 | 30 | public static byte[] toByteArray(PhotonImage photonImage) { 31 | return Value.asValue(photonImage).invokeMember("get_bytes").getMember("buffer").as(ByteSequence.class).toByteArray(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-spring-boot-photon/src/main/java/com/example/demo/PhotonService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.stereotype.Service; 11 | import org.springframework.web.server.ResponseStatusException; 12 | 13 | @Service 14 | class PhotonService { 15 | private final PhotonPool photonPool; 16 | 17 | PhotonService(PhotonPool photonPool) { 18 | this.photonPool = photonPool; 19 | } 20 | 21 | public byte[] processImage(String effectName) { 22 | Photon photon = photonPool.take(); 23 | try { 24 | if (!photon.implementsEffect(effectName)) { 25 | throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Effect " + effectName + " not found in Photon"); 26 | } 27 | Photon.PhotonImage image = photon.createImage(); 28 | photon.applyEffect(effectName, image); 29 | byte[] result = Photon.toByteArray(image); 30 | image.free(); 31 | return result; 32 | } finally { 33 | photonPool.release(photon); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-spring-boot-photon/src/main/resources/META-INF/native-image/org.example/demo/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "interfaces": [ 4 | "com.example.demo.Photon$PhotonImage" 5 | ] 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-spring-boot-photon/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=demo 2 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-spring-boot-photon/src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example.demo; 8 | 9 | import org.junit.jupiter.api.Assertions; 10 | import org.junit.jupiter.api.Test; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.boot.test.context.SpringBootTest; 13 | 14 | @SpringBootTest 15 | class DemoApplicationTests { 16 | 17 | @Autowired 18 | private PhotonService photonService; 19 | 20 | @Test 21 | void testEffectEquality() { 22 | for (String effectName : new String[]{"default", "grayscale", "flipv", "fliph"}) { 23 | byte[] imageContent1 = photonService.processImage(effectName); 24 | byte[] imageContent2 = photonService.processImage(effectName); 25 | Assertions.assertArrayEquals(imageContent1, imageContent2, "Two processed images not identical when effect '%s' is used".formatted(effectName)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | 10 | # Binary files should be left untouched 11 | *.jar binary 12 | 13 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | 7 | # Ignore maven build output directory 8 | target 9 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/README.md: -------------------------------------------------------------------------------- 1 | # GraalWasm Quick Start 2 | 3 | A minimal Java application that embeds a WebAssembly module with GraalWasm. 4 | 5 | ## Preparation 6 | 7 | Install GraalVM for JDK 24 and set the value of `JAVA_HOME` accordingly. 8 | We recommend using [SDKMAN!](https://sdkman.io/). (For other download options, see [GraalVM Downloads](https://www.graalvm.org/downloads/).) 9 | 10 | ```bash 11 | sdk install java 24-graal 12 | ``` 13 | 14 | ## Run the Application Using Maven 15 | 16 | To build and test the demo, run: 17 | 18 | ```bash 19 | ./mvnw test 20 | ``` 21 | 22 | To execute the main method, run: 23 | 24 | ```bash 25 | ./mvnw exec:java 26 | ``` 27 | 28 | ## Run the Application Using Gradle 29 | 30 | To build and test the demo, run: 31 | 32 | ```bash 33 | ./gradlew test 34 | ``` 35 | 36 | To execute the main method, run: 37 | 38 | ```bash 39 | ./gradlew run 40 | ``` 41 | 42 | ## Implementation Details 43 | 44 | The WebAssembly is stored in the resource file `add-two.wasm`. 45 | You can examine its textual representation in the resource file `add-two.wat`. 46 | If you want to experiment with and tweak the WebAssembly module, you will need to rebuild the `add-two.wasm` file from the `add-two.wat` file. 47 | For that, you can use the `wat2wasm` tool from the [wabt toolkit](https://github.com/WebAssembly/wabt). 48 | You can also use [this web app](https://webassembly.github.io/wabt/demo/wat2wasm/) to run `wat2wasm` in your browser instead of installing `wabt`. 49 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | // Apply the application plugin to add support for building a CLI application in Java. 3 | application 4 | } 5 | 6 | repositories { 7 | // Use Maven Central for resolving dependencies. 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | implementation("org.graalvm.polyglot:polyglot:24.2.0") 13 | implementation("org.graalvm.polyglot:wasm:24.2.0") 14 | 15 | // Use JUnit Jupiter for testing. 16 | testImplementation("org.junit.jupiter:junit-jupiter:5.11.0") 17 | 18 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 19 | } 20 | 21 | application { 22 | // Define the main class for the application. 23 | mainClass = "com.example.App" 24 | } 25 | 26 | tasks.named("test") { 27 | // Use JUnit Platform for unit tests. 28 | useJUnitPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/graal-languages-demos/8be2559b5b827e00fa191028ecee53b807a217fe/graalwasm/graalwasm-starter/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "graalwasm-starter" 2 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/src/main/java/com/example/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import java.io.IOException; 10 | import java.net.URL; 11 | 12 | import org.graalvm.polyglot.Context; 13 | import org.graalvm.polyglot.Source; 14 | import org.graalvm.polyglot.Value; 15 | 16 | public class App { 17 | 18 | public static void main(String[] args) throws IOException { 19 | try (Context context = Context.create()) { 20 | URL wasmFile = App.class.getResource("add-two.wasm"); 21 | String moduleName = "main"; 22 | context.eval(Source.newBuilder("wasm", wasmFile).name(moduleName).build()); 23 | Value addTwo = context.getBindings("wasm").getMember(moduleName).getMember("addTwo"); 24 | System.out.println("addTwo(40, 2) = " + addTwo.execute(40, 2)); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/src/main/resources/com/example/add-two.wasm: -------------------------------------------------------------------------------- 1 | asm` 2 | addTwo 3 |  j -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/src/main/resources/com/example/add-two.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "addTwo") (param i32 i32) (result i32) 3 | local.get 0 4 | local.get 1 5 | i32.add)) -------------------------------------------------------------------------------- /graalwasm/graalwasm-starter/src/test/java/com/example/AppTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * 4 | * Licensed under the Universal Permissive License v 1.0 as shown at https://opensource.org/license/UPL. 5 | */ 6 | 7 | package com.example; 8 | 9 | import java.io.IOException; 10 | 11 | import org.junit.jupiter.api.Test; 12 | import static org.junit.jupiter.api.Assertions.*; 13 | 14 | class AppTest { 15 | @Test 16 | void appRuns() { 17 | assertDoesNotThrow(() -> App.main(new String[0])); 18 | } 19 | } 20 | --------------------------------------------------------------------------------