Fix Graal initialization - #21444
Conversation
The fix consists of swapping the classloader while creating the engine, using the core GraalUtil for language resolution, implementing `isReady()` to indicate when initialization is complete, and breaking the cyclic dependency caused by the dependency trackers. In addition, the features have been modified to rely on the core defined Graal features. Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
|
@florian-h05 @HolgerHees FYI. |
|
How did you test it if the core component is missing? I have to admit, I’ve never compiled and enabled parts of the core itself. I’d like to test it. |
|
I always work with both core and addons in parallel, so for me that's no problem. To make this work, you must check-out and build openhab/openhab-core#5787. That installs "that version of core" into your local I do however use the "demo app" to run OH. If you use Karaf, you must then build the distro itself, and then either use the Running the "demo app" is quite easy normally, just go to the If you want to try to "demo app" route (which is definitely quicker if it works, I can provide the files I used. They do include other stuff not relevant for this, like bindings I'm working on or use for testing etc., and you might need to remove some of them to make it resolve (because you don't have "my" bindings in your
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.openhab.demo</groupId>
<artifactId>org.openhab.demo.app</artifactId>
<version>5.3.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>openHAB Demo :: App</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<oh.java.version>21</oh.java.version>
<maven.compiler.release>${oh.java.version}</maven.compiler.release>
<bnd.version>7.1.0</bnd.version>
<graalvm.version>25.0.1</graalvm.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openhab.core.bom</groupId>
<artifactId>org.openhab.core.bom.runtime</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.core.bom</groupId>
<artifactId>org.openhab.core.bom.openhab-core</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.ui.bom</groupId>
<artifactId>org.openhab.ui.bom.openhab-ui</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.milllan</artifactId>
<version>1.0.2-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.shelly</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.enocean</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.jsscripting</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.pythonscripting</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.jrubyscripting</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.groovyscripting</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.jythonscripting</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.pythonscripting</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.basicprofiles</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.bin2json</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.exec</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.jinja</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.jsonpath</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.map</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.regex</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.scale</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.xpath</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.xslt</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.chromecast</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.exec</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.energidataservice</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.unifiprotect</artifactId>
<version>4.0.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.network</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.astro</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.onkyo</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.upnpcontrol</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.ecobee</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.ntfy</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.io.mcp</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.config.discovery.usbserial.windowsregistry</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.zwave</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.io.thingtypes</artifactId>
<version>1.0.1-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<!-- GraalVM dependencies -->
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.graal</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.polyglot.polyglot</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.js.js-scriptengine</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.js.js-language</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.python.python-language</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.python.python-resources</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.llvm.llvm-api</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.regex.regex</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.sdk.collections</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.sdk.nativeimage</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.sdk.jniutils</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.sdk.word</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.shadowed.icu4j</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.shadowed.json</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.shadowed.xz</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.tools.chromeinspector-tool</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.tools.profiler-tool</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.truffle.truffle-api</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.truffle.truffle-nfi</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.truffle.truffle-nfi-libffi</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.truffle.truffle-compiler</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.osgiify</groupId>
<artifactId>org.graalvm.truffle.truffle-runtime</artifactId>
<version>${graalvm.version}</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.shell.remote</artifactId>
<version>1.2.0</version>
</dependency>
<!-- uncomment this and add the name of your binding that you want to work on
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.YOURBINDINGNAME</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
-->
<!-- uncomment this if you want to work on the Zigbee binding
<dependency>
<groupId>org.openhab.addons.bom</groupId>
<artifactId>org.openhab.addons.bom.zigbee</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
-->
</dependencies>
<build>
<pluginManagement>
<plugins>
<!-- Use the bnd-maven-plugin and assemble the symbolic names -->
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
<version>${bnd.version}</version>
<executions>
<execution>
<goals>
<goal>bnd-process</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Required to make the maven-jar-plugin pick up the bnd generated manifest. Also avoid packaging empty Jars -->
<!-- Moved... -->
<!-- Setup the indexer for running and testing -->
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-indexer-maven-plugin</artifactId>
<version>${bnd.version}</version>
<configuration>
<localURLs>REQUIRED</localURLs>
<attach>false</attach>
</configuration>
<executions>
<execution>
<id>index</id>
<goals>
<goal>index</goal>
</goals>
<configuration>
<indexName>${project.artifactId}</indexName>
</configuration>
</execution>
<execution>
<id>test-index</id>
<goals>
<goal>index</goal>
</goals>
<configuration>
<indexName>${project.artifactId}</indexName>
<outputFile>${project.build.directory}/test-index.xml</outputFile>
<scopes>
<scope>test</scope>
</scopes>
</configuration>
</execution>
</executions>
</plugin>
<!-- Define the version of the resolver plugin we use -->
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-resolver-maven-plugin</artifactId>
<version>${bnd.version}</version>
<configuration>
<failOnChanges>false</failOnChanges>
<bndruns>
</bndruns>
</configuration>
<executions>
<execution>
<goals>
<goal>resolve</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Define the version of the export plugin we use -->
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-export-maven-plugin</artifactId>
<version>${bnd.version}</version>
<configuration>
<resolve>true</resolve>
<failOnChanges>true</failOnChanges>
</configuration>
<executions>
<execution>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Define the version of the testing plugin that we use -->
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-testing-maven-plugin</artifactId>
<version>${bnd.version}</version>
<executions>
<execution>
<goals>
<goal>testing</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Define the version of the baseline plugin we use and avoid failing when no baseline jar exists. -->
<!-- (for example before the first release) -->
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-baseline-maven-plugin</artifactId>
<version>${bnd.version}</version>
<configuration>
<failOnMissing>false</failOnMissing>
</configuration>
<executions>
<execution>
<goals>
<goal>baseline</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Allow running openHAB demo app from a Maven/bnd task -->
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-run-maven-plugin</artifactId>
<version>${bnd.version}</version>
<configuration>
<includeDependencyManagement>true</includeDependencyManagement>
<bndrun>app.bndrun</bndrun>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.4.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.2</version>
<configuration>
<outputDirectory>${project.build.directory}/site</outputDirectory>
<failOnError>!${quality.skip}</failOnError>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.15.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<preparationGoals>clean install</preparationGoals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.13.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.21.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
</plugin>
<!-- This plugin's configuration is used to store Eclipse m2e settings only. -->
<!-- It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-indexer-maven-plugin</artifactId>
<versionRange>[3.1.0,)</versionRange>
<goals>
<goal>index</goal>
<goal>local-index</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-run-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-export-maven-plugin</artifactId>
<configuration>
<failOnChanges>false</failOnChanges>
<bndruns>
<bndrun>app.bndrun</bndrun>
</bndruns>
</configuration>
</plugin>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-resolver-maven-plugin</artifactId>
<configuration>
<bndruns>
<bndrun>app.bndrun</bndrun>
</bndruns>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>openhab-artifactory-release</id>
<name>JFrog Artifactory Repository</name>
<url>https://openhab.jfrog.io/openhab/libs-release</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>openhab-artifactory-snapshot</id>
<name>JFrog Artifactory Repository</name>
<url>https://openhab.jfrog.io/openhab/libs-snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</repository>
</repositories>
<profiles>
<profile>
<id>with-bnd-resolver-resolve</id>
<activation>
<property>
<name>withResolver</name>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-resolver-maven-plugin</artifactId>
<version>${bnd.version}</version>
<executions>
<execution>
<goals>
<goal>resolve</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<id>j21</id>
<properties>
<oh.java.version>21</oh.java.version>
<maven.compiler.release>${oh.java.version}</maven.compiler.release>
</properties>
</profile>
</profiles>
</project>
You must run: from the ..from the same folder. All that said, if you're new to the "demo app", bndrun and all that, it's a lot to take in at once, and it might end up being a frustrating experience. Perhaps the simplest path is to just build all of core, from the core repo root: Once that's done, go to the root of the Once that's done, if you want a local Karaf installation built inside the The ready-to-run Karaf installation can then be found in |
This is a companion PR of openhab/openhab-core#5787. The build will fail because the changes from openhab/openhab-core#5787 aren't in core.
I've done multiple things to make Graal initialization work. I'm hopeful that this will also make it possible to install and uninstall Graal based add-ons without restarting.
The steps are:
GraalUtilfor thread-safe language resolutionisReady()to indicate when initialization is completeTogether these things make this seem dead stable to me. I can't say for sure that every measure is required; I've just worked to solve the problems I've met along the way. Maybe some aren't ultimately necessary, but I've included it all. Some things might be "better" even if they weren't the direct cause of the initialization problems.
I'm creating this as a draft, because both this and the core PR need further evaluation/discussion/testing.