ORDS and GraphQL: using Maven to build the polyglot and js dependencies for GraalVM for JDK 21

Disclaimer

This article is an expansion from a previous, separate Oracle forums thread. The question posed was (paraphrasing):

Can I use ORDS with Oracle GraalVM for JDK 21 (despite the ORDS team only officially claiming support for Oracle JDK 17, Oracle JDK 21, Oracle GraalVM Enterprise Edition for Java version 17, and Oracle GraalVM Enterprise Edition for Java version 21)?

And, if I can, how do I install the Oracle GraalVM for JDK 21 graaljs and polyglot dependencies required for ORDS’ GraphQL UI and querying capabilities?

I’m also reiterating, that what follows is experimental only. We still need to investigate the possibility of supporting Oracle GraalVM for JDK 17 or 21 (the non-Enterprise Editions) in future ORDS releases. So, stay tuned. With all the disclaimers and release of liability out of the way, read on if you’d like learn how to build these dependencies for Oracle GraalVM for JDK 21.

You’ll need Maven first though.

Install Maven

Install the Java project build tool Maven. Installation instructions for your OS can be found here.

Create a new Maven project

Next, create a new Maven project1 (you can use the maven-archetype-quickstart archetype for your project) by executing this command in your terminal:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false

Next cd into the project folder (e.g., the artifactId, in this case “my-app”):

cd my-app

Your project folder will resemble the following:

.
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── mycompany
    │               └── app
    │                   └── App.java
    └── test
        └── java
            └── com
                └── mycompany
                    └── app
                        └── AppTest.java

You can disregard /src/test subfolder and its descendants.

Modify the pom.xml file

You will need to modify the quickstart project’s pom.xml file. Add the following dependencies2 in the <dependencies></dependencies> parameter section:

<dependency>
    <groupId>org.graalvm.polyglot</groupId>
    <artifactId>polyglot</artifactId>
    <version>[TBD]</version>
</dependency>
<dependency>
    <groupId>org.graalvm.polyglot</groupId>
    <artifactId>js</artifactId>
    <version>[TBD]</version>
    <type>pom</type>
</dependency>

How do I know which version to choose?

Check the Release Notes for the JDK you intend to use. In this case, I’m configuring Oracle GraalVM for JDK 21.0.7, which is based on Oracle JDK 21. The Release Notes state:

Truffle languages and other components version 23.1.7 are designed for use with GraalVM for JDK 21.0.7.” So, I’m using the following polyglot and js versions.

Updated pom.xml file

Your updated POM.xml file should end up looking like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>my-app</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>5.11.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
    </dependency>
    <!-- Optionally: parameterized tests support -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-params</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.graalvm.polyglot</groupId>
      <artifactId>polyglot</artifactId>
      <version>23.1.7</version>
    </dependency>
    <dependency>
      <groupId>org.graalvm.polyglot</groupId>
      <artifactId>js</artifactId>
      <version>23.1.7</version>
      <type>pom</type>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.4.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.3.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.13.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>3.3.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.4.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>3.1.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>3.1.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.12.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.6.1</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Copy the Maven dependencies

Save your changes, and then from your terminal execute the following command:

mvn dependency:copy-dependencies

You’ll notice a new /target/dependency subfolder in your project, along with new .jar and .pom files:

.
├── pom.xml
├── src
│   ├── main
│   │   └── java
│   │       └── com
│   │           └── mycompany
│   │               └── app
│   │                   └── App.java
│   └── test
│       └── java
│           └── com
│               └── mycompany
│                   └── app
│                       └── AppTest.java
└── target
    ├── classes
    │   └── com
    │       └── mycompany
    │           └── app
    │               └── App.class
    ├── dependency
    │   ├── apiguardian-api-1.1.2.jar
    │   ├── collections-23.1.7.jar
    │   ├── icu4j-23.1.7.jar
    │   ├── jniutils-23.1.7.jar
    │   ├── js-23.1.7.pom
    │   ├── js-community-23.1.7.pom
    │   ├── js-language-23.1.7.jar
    │   ├── junit-jupiter-api-5.11.0.jar
    │   ├── junit-jupiter-params-5.11.0.jar
    │   ├── junit-platform-commons-1.11.0.jar
    │   ├── nativebridge-23.1.7.jar
    │   ├── nativeimage-23.1.7.jar
    │   ├── opentest4j-1.3.0.jar
    │   ├── polyglot-23.1.7.jar
    │   ├── regex-23.1.7.jar
    │   ├── truffle-api-23.1.7.jar
    │   ├── truffle-compiler-23.1.7.jar
    │   ├── truffle-enterprise-23.1.7.jar
    │   ├── truffle-runtime-23.1.7.jar
    │   └── word-23.1.7.jar
    └── test-classes
        └── com
            └── mycompany
                └── app
                    └── AppTest.class

Relocate the new .pom and .jar files

You’ll need to move all of the files from this temporary app project, and place them into your [ORDS product folder]/lib/ext folder. If you recall, when you first configure and install ORDS, the best practice is to set the ORDS/bin3 and ORDS_CONFIG environment variables.

If I issue the ENV command in a terminal, I’ll see something similar to the following:

TMPDIR=/var/folders/wm/t9qmbgnn3f577b51xzb5yrkc0000gp/T/
__CFBundleIdentifier=com.apple.Terminal
XPC_FLAGS=0x0
TERM=xterm-256color
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.sFYLlexTu3/Listeners
XPC_SERVICE_NAME=0
TERM_PROGRAM=Apple_Terminal
TERM_PROGRAM_VERSION=455.1
TERM_SESSION_ID=*********-****-****-****-**********
SHELL=/bin/zsh
HOME=/Users/choina
LOGNAME=choina
USER=choina
PATH=/opt/homebrew/Caskroom/sqlcl/25.1.1.113.2054/sqlcl/bin:/Library/Frameworks/Python.framework/Versions/3.13/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/podman/bin:/Users/choina/ords/25.2.0.r1651520/bin
SHLVL=1
PWD=/Users/choina/my-app
OLDPWD=/Users/choina
HOMEBREW_PREFIX=/opt/homebrew
HOMEBREW_CELLAR=/opt/homebrew/Cellar
HOMEBREW_REPOSITORY=/opt/homebrew
INFOPATH=/opt/homebrew/share/info:
ORDS_CONFIG=/Users/choina/ords/ords_config
LANG=en_US.UTF-8
_=/usr/bin/env
```

Notice in the PATH variable the location of my “ORDS Product Folder”: /Users/choina/ords/25.2.0.r1651520/bin. You can use that “root” /Users/choina/ords/25.2.0.r1651520/ and cd directly to the /lib/ext folder. Like this:

cd /Users/choina/ords/25.2.0.r1651520/lib/ext

Drag and drop (or use the mv command) all of these new .jar and .pom files from the /target/dependency folder into the ORDS /lib/ext folder. Your ORDS product folder will now look something like this:

.
├── bin
│   ├── ords
│   ├── ords-metrics
│   └── ords.exe
├── docs
│   └── javadoc
│       └── plugin-api
├── examples
│   ├── application-container
│   │   └── README.md
│   ├── db_auth
│   │   ├── index.html
│   │   └── sql
│   ├── ords-metrics
│   │   ├── create_alarms.sh
│   │   └── ords-metrics.service
│   ├── plugins
│   │   ├── lib
│   │   ├── plugin-demo
│   │   └── plugin-javascript
│   ├── pre_hook
│   │   ├── index.html
│   │   ├── README.md
│   │   └── sql
│   └── soda
│       └── getting-started
├── icons
│   └── ords_logo2.ico
├── lib
│   └── ext
│       ├── apiguardian-api-1.1.2.jar
│       ├── collections-23.1.7.jar
│       ├── icu4j-23.1.7.jar
│       ├── jniutils-23.1.7.jar
│       ├── js-language-23.1.7.jar
│       ├── junit-jupiter-api-5.11.0.jar
│       ├── junit-jupiter-params-5.11.0.jar
│       ├── junit-platform-commons-1.11.0.jar
│       ├── nativebridge-23.1.7.jar
│       ├── nativeimage-23.1.7.jar
│       ├── opentest4j-1.3.0.jar
│       ├── polyglot-23.1.7.jar
│       ├── README
│       ├── regex-23.1.7.jar
│       ├── truffle-api-23.1.7.jar
│       ├── truffle-compiler-23.1.7.jar
│       ├── truffle-enterprise-23.1.7.jar
│       ├── truffle-runtime-23.1.7.jar
│       └── word-23.1.7.jar
├── LICENSE.txt
├── linux-support
│   ├── man
│   │   ├── ords.1
│   │   ├── ords.conf.5
│   │   └── ords.service.8
│   ├── ords.conf
│   ├── ords.service
│   ├── ords.sh
│   └── README.md
├── NOTICE.txt
├── ords.war
├── scripts
│   ├── installer
│   │   ├── apex_ords_app_con_grants.sql
│   │   ├── ords_installer_privileges.sql
│   │   └── ords_set_editioning.sql
│   └── migrate
│       ├── ords_manual_migrate_workspace.sql
│       ├── ords_manual_migrate.sql
│       ├── ords_migrate_apex_rest.sql
│       ├── ords_migrate_report.sql
│       └── ords_migrate_workspace_rest.sql
└── THIRD-PARTY-LICENSES.txt

Close out all of your terminal sessions. And make sure you are using the correct version of Java; you can check with the java --version command.

Restart ORDS and test

Restart ORDS, the ords/_/graphiql endpoint should be available. You can access it one of three ways:

  1. Directly by navigating to http://host:port/ords/[your schema]/_/graphiql
  2. From:
    • the SQL Developer Web LaunchPad
    • the SQL Developer (Hamburger) menu

The end

That’s it. You should now have a test/experimental version of GraalVM for JDK 21 with the required Graal js and polyglot dependencies installed (much like you would with the now-deprecated gu installer).

  1. Refer to the quick Maven start guide if you run into trouble. And read up on the structure of the quickstart archetype here. ↩︎
  2. Examples are taken from here. ↩︎
  3. ORDS/bin is a reference to one of the subfolders in your (parent) “ORDS Product folder.” ↩︎

Leave a Reply

Your email address will not be published. Required fields are marked *