diff --git a/bundles/org.openhab.automation.groovyscripting/README.md b/bundles/org.openhab.automation.groovyscripting/README.md
index 50348251f80..77f9c6e5c4c 100644
--- a/bundles/org.openhab.automation.groovyscripting/README.md
+++ b/bundles/org.openhab.automation.groovyscripting/README.md
@@ -1,6 +1,6 @@
# Groovy Scripting
-This add-on provides support for [Groovy](https://groovy-lang.org/) 4.0.7 that can be used as a scripting language within automation rules and which eliminates the need to manually install Groovy.
+This add-on provides support for [Groovy](https://groovy-lang.org/) 4.0.9 that can be used as a scripting language within automation rules and which eliminates the need to manually install Groovy.
## Creating Groovy Scripts
diff --git a/bundles/org.openhab.automation.groovyscripting/pom.xml b/bundles/org.openhab.automation.groovyscripting/pom.xml
index 86c995c76f0..b45e1ee3181 100644
--- a/bundles/org.openhab.automation.groovyscripting/pom.xml
+++ b/bundles/org.openhab.automation.groovyscripting/pom.xml
@@ -15,8 +15,8 @@
openHAB Add-ons :: Bundles :: Automation :: Groovy Scripting
- com.ibm.icu.*;resolution:=optional,groovy.runtime.metaclass;resolution:=optional,groovyjarjarantlr4.stringtemplate;resolution:=optional,org.abego.treelayout.*;resolution:=optional,org.apache.ivy.*;resolution:=optional,org.stringtemplate.v4.*;resolution:=optional
- 4.0.7
+ com.ibm.icu.*;resolution:=optional,groovy.runtime.metaclass;resolution:=optional,groovyjarjarantlr4.stringtemplate;resolution:=optional,org.abego.treelayout.*;resolution:=optional,org.apache.ivy.*;resolution:=optional,org.fusesource.jansi.*;resolution:=optional,org.stringtemplate.v4.*;resolution:=optional
+ 4.0.9
@@ -32,12 +32,48 @@
${groovy.version}
compile
+
+ org.apache.groovy
+ groovy-json
+ ${groovy.version}
+ compile
+
org.apache.groovy
groovy-xml
${groovy.version}
compile
+
+ org.apache.groovy
+ groovy-yaml
+ ${groovy.version}
+ compile
+
+
+
+
+
+ biz.aQute.bnd
+ bnd-maven-plugin
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.openhab.automation.groovyscripting/src/main/java/org/openhab/automation/groovyscripting/internal/GroovyScriptEngineFactory.java b/bundles/org.openhab.automation.groovyscripting/src/main/java/org/openhab/automation/groovyscripting/internal/GroovyScriptEngineFactory.java
index a8b54c4a578..3e6b35942f2 100644
--- a/bundles/org.openhab.automation.groovyscripting/src/main/java/org/openhab/automation/groovyscripting/internal/GroovyScriptEngineFactory.java
+++ b/bundles/org.openhab.automation.groovyscripting/src/main/java/org/openhab/automation/groovyscripting/internal/GroovyScriptEngineFactory.java
@@ -44,7 +44,7 @@ public class GroovyScriptEngineFactory extends AbstractScriptEngineFactory {
.flatMap(List::stream) //
.collect(Collectors.toUnmodifiableList());
- private final GroovyClassLoader gcl = new GroovyClassLoader();
+ private final GroovyClassLoader gcl = new GroovyClassLoader(GroovyScriptEngineFactory.class.getClassLoader());
public GroovyScriptEngineFactory() {
String scriptDir = OpenHAB.getConfigFolder() + File.separator + FILE_DIRECTORY;
diff --git a/itests/org.openhab.automation.groovyscripting.tests/NOTICE b/itests/org.openhab.automation.groovyscripting.tests/NOTICE
new file mode 100644
index 00000000000..38d625e3492
--- /dev/null
+++ b/itests/org.openhab.automation.groovyscripting.tests/NOTICE
@@ -0,0 +1,13 @@
+This content is produced and maintained by the openHAB project.
+
+* Project home: https://www.openhab.org
+
+== Declared Project Licenses
+
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License 2.0 which is available at
+https://www.eclipse.org/legal/epl-2.0/.
+
+== Source Code
+
+https://github.com/openhab/openhab-addons
diff --git a/itests/org.openhab.automation.groovyscripting.tests/itest.bndrun b/itests/org.openhab.automation.groovyscripting.tests/itest.bndrun
new file mode 100644
index 00000000000..cea071367d4
--- /dev/null
+++ b/itests/org.openhab.automation.groovyscripting.tests/itest.bndrun
@@ -0,0 +1,80 @@
+-include: ../itest-common.bndrun
+
+Bundle-SymbolicName: ${project.artifactId}
+Fragment-Host: org.openhab.automation.groovyscripting
+
+-runrequires: \
+ bnd.identity;id='org.openhab.automation.groovyscripting.tests',\
+ bnd.identity;id='org.openhab.core',\
+ bnd.identity;id='org.openhab.automation.groovyscripting'
+
+# We would like to use the "volatile" storage only
+-runblacklist: \
+ bnd.identity;id='org.openhab.core.storage.json'
+
+#
+# done
+#
+-runbundles: \
+ biz.aQute.tester.junit-platform;version='[6.4.0,6.4.1)',\
+ ch.qos.logback.classic;version='[1.2.11,1.2.12)',\
+ ch.qos.logback.core;version='[1.2.11,1.2.12)',\
+ com.fasterxml.jackson.core.jackson-annotations;version='[2.14.1,2.14.2)',\
+ com.fasterxml.jackson.core.jackson-core;version='[2.14.2,2.14.3)',\
+ com.fasterxml.jackson.core.jackson-databind;version='[2.14.2,2.14.3)',\
+ com.fasterxml.jackson.dataformat.jackson-dataformat-yaml;version='[2.14.2,2.14.3)',\
+ com.google.gson;version='[2.9.1,2.9.2)',\
+ com.sun.jna;version='[5.12.1,5.12.2)',\
+ com.sun.xml.bind.jaxb-osgi;version='[2.3.3,2.3.4)',\
+ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\
+ jakarta.annotation-api;version='[1.3.5,1.3.6)',\
+ jakarta.annotation-api;version='[2.0.0,2.0.1)',\
+ jakarta.inject.jakarta.inject-api;version='[2.0.0,2.0.1)',\
+ jakarta.xml.bind-api;version='[2.3.3,2.3.4)',\
+ javax.measure.unit-api;version='[2.1.2,2.1.3)',\
+ jollyday;version='[0.5.10,0.5.11)',\
+ junit-jupiter-api;version='[5.8.1,5.8.2)',\
+ junit-jupiter-engine;version='[5.8.1,5.8.2)',\
+ junit-platform-commons;version='[1.8.1,1.8.2)',\
+ junit-platform-engine;version='[1.8.1,1.8.2)',\
+ junit-platform-launcher;version='[1.8.1,1.8.2)',\
+ org.apache.servicemix.specs.activation-api-1.2.1;version='[1.2.1,1.2.2)',\
+ org.eclipse.equinox.event;version='[1.4.300,1.4.301)',\
+ org.glassfish.hk2.external.javax.inject;version='[2.4.0,2.4.1)',\
+ org.glassfish.hk2.osgi-resource-locator;version='[1.0.3,1.0.4)',\
+ org.hamcrest;version='[2.2.0,2.2.1)',\
+ org.jsr-305;version='[3.0.2,3.0.3)',\
+ org.openhab.automation.groovyscripting;version='[4.0.0,4.0.1)',\
+ org.openhab.automation.groovyscripting.tests;version='[4.0.0,4.0.1)',\
+ org.openhab.core;version='[4.0.0,4.0.1)',\
+ org.openhab.core.automation;version='[4.0.0,4.0.1)',\
+ org.openhab.core.automation.module.script;version='[4.0.0,4.0.1)',\
+ org.openhab.core.config.core;version='[4.0.0,4.0.1)',\
+ org.openhab.core.ephemeris;version='[4.0.0,4.0.1)',\
+ org.openhab.core.io.console;version='[4.0.0,4.0.1)',\
+ org.openhab.core.test;version='[4.0.0,4.0.1)',\
+ org.openhab.core.thing;version='[4.0.0,4.0.1)',\
+ org.openhab.core.transform;version='[4.0.0,4.0.1)',\
+ org.opentest4j;version='[1.2.0,1.2.1)',\
+ org.osgi.service.event;version='[1.4.0,1.4.1)',\
+ org.osgi.util.function;version='[1.2.0,1.2.1)',\
+ org.osgi.util.promise;version='[1.2.0,1.2.1)',\
+ org.threeten.extra;version='[1.5.0,1.5.1)',\
+ org.yaml.snakeyaml;version='[1.33.0,1.33.1)',\
+ si-units;version='[2.1.0,2.1.1)',\
+ si.uom.si-quantity;version='[2.1.0,2.1.1)',\
+ tech.units.indriya;version='[2.1.2,2.1.3)',\
+ uom-lib-common;version='[2.1.0,2.1.1)',\
+ xstream;version='[1.4.19,1.4.20)',\
+ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\
+ org.apache.felix.http.servlet-api;version='[1.2.0,1.2.1)',\
+ org.apache.felix.scr;version='[2.2.4,2.2.5)',\
+ org.eclipse.jetty.http;version='[9.4.50,9.4.51)',\
+ org.eclipse.jetty.io;version='[9.4.50,9.4.51)',\
+ org.eclipse.jetty.security;version='[9.4.50,9.4.51)',\
+ org.eclipse.jetty.server;version='[9.4.50,9.4.51)',\
+ org.eclipse.jetty.servlet;version='[9.4.50,9.4.51)',\
+ org.eclipse.jetty.util;version='[9.4.50,9.4.51)',\
+ org.eclipse.jetty.util.ajax;version='[9.4.50,9.4.51)',\
+ org.ops4j.pax.logging.pax-logging-api;version='[2.2.0,2.2.1)',\
+ org.osgi.service.component;version='[1.5.0,1.5.1)'
diff --git a/itests/org.openhab.automation.groovyscripting.tests/pom.xml b/itests/org.openhab.automation.groovyscripting.tests/pom.xml
new file mode 100644
index 00000000000..305257ba5a4
--- /dev/null
+++ b/itests/org.openhab.automation.groovyscripting.tests/pom.xml
@@ -0,0 +1,25 @@
+
+
+
+ 4.0.0
+
+
+ org.openhab.addons.itests
+ org.openhab.addons.reactor.itests
+ 4.0.0-SNAPSHOT
+
+
+ org.openhab.automation.groovyscripting.tests
+
+ openHAB Add-ons :: Integration Tests :: Groovy Scripting
+
+
+
+ org.openhab.addons.bundles
+ org.openhab.automation.groovyscripting
+ ${project.version}
+
+
+
+
diff --git a/itests/org.openhab.automation.groovyscripting.tests/src/main/java/org/openhab/automation/groovyscripting/SlurperOSGiTest.java b/itests/org.openhab.automation.groovyscripting.tests/src/main/java/org/openhab/automation/groovyscripting/SlurperOSGiTest.java
new file mode 100644
index 00000000000..42da7e1f69e
--- /dev/null
+++ b/itests/org.openhab.automation.groovyscripting.tests/src/main/java/org/openhab/automation/groovyscripting/SlurperOSGiTest.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.automation.groovyscripting;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.openhab.core.automation.module.script.ScriptEngineContainer;
+import org.openhab.core.automation.module.script.ScriptEngineManager;
+import org.openhab.core.test.java.JavaOSGiTest;
+
+/**
+ * This tests the JSON, XML and YAML slurpers using the Groovy scripting engine.
+ *
+ * @author Wouter Born - Initial contribution
+ */
+@NonNullByDefault
+public class SlurperOSGiTest extends JavaOSGiTest {
+
+ private @NonNullByDefault({}) ScriptEngine engine;
+
+ private final String path = "OH-INF/automation/jsr223/";
+
+ @BeforeEach
+ public void init() {
+ ScriptEngineManager scriptManager = getService(ScriptEngineManager.class);
+ ScriptEngineContainer container = scriptManager.createScriptEngine("groovy", "myGroovyEngine");
+ engine = container.getScriptEngine();
+ }
+
+ private void evalScript(String fileName) throws ScriptException, IOException {
+ URL url = bundleContext.getBundle().getResource(path + fileName);
+ engine.eval(new InputStreamReader(url.openStream()));
+ }
+
+ @Test
+ public void jsonSlurper() throws ScriptException, IOException {
+ evalScript("json-slurper.groovy");
+ }
+
+ @Test
+ public void xmlSlurper() throws ScriptException, IOException {
+ evalScript("xml-slurper.groovy");
+ }
+
+ @Test
+ public void yamlSlurper() throws ScriptException, IOException {
+ evalScript("yaml-slurper.groovy");
+ }
+}
diff --git a/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/json-slurper.groovy b/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/json-slurper.groovy
new file mode 100644
index 00000000000..41790c7c7b5
--- /dev/null
+++ b/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/json-slurper.groovy
@@ -0,0 +1,22 @@
+import static org.hamcrest.CoreMatchers.*
+import static org.hamcrest.MatcherAssert.assertThat
+
+import groovy.json.JsonSlurper
+
+def json = '''\
+{
+ "person": {
+ "name": "John",
+ "age": 10,
+ "pets": ["cat", "dog"]
+ }
+}
+'''
+
+def result = new JsonSlurper().parseText(json)
+
+assertThat(result.person.name, is("John"))
+assertThat(result.person.age, is(10))
+assertThat(result.person.pets.size(), is(2))
+assertThat(result.person.pets[0], is("cat"))
+assertThat(result.person.pets[1], is("dog"))
diff --git a/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/xml-slurper.groovy b/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/xml-slurper.groovy
new file mode 100644
index 00000000000..82ccf3c91a3
--- /dev/null
+++ b/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/xml-slurper.groovy
@@ -0,0 +1,23 @@
+import static org.hamcrest.CoreMatchers.*
+import static org.hamcrest.MatcherAssert.assertThat
+
+import groovy.xml.XmlSlurper
+
+def xml = '''\
+
+
+ Brigitte
+ 34
+ bird
+ fish
+
+
+'''
+
+def result = new XmlSlurper().parseText(xml)
+
+assertThat(result.person.name, is("Brigitte"))
+assertThat(result.person.age, is(34))
+assertThat(result.person.pets.size(), is(2))
+assertThat(result.person.pets[0], is("bird"))
+assertThat(result.person.pets[1], is("fish"))
diff --git a/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/yaml-slurper.groovy b/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/yaml-slurper.groovy
new file mode 100644
index 00000000000..61948dffe30
--- /dev/null
+++ b/itests/org.openhab.automation.groovyscripting.tests/src/main/resources/OH-INF/automation/jsr223/yaml-slurper.groovy
@@ -0,0 +1,21 @@
+import static org.hamcrest.CoreMatchers.*
+import static org.hamcrest.MatcherAssert.assertThat
+
+import groovy.yaml.YamlSlurper
+
+def yaml = '''\
+person:
+ name: "Itsuki"
+ age: 78
+ pets:
+ - rabbit
+ - snake
+'''
+
+def result = new YamlSlurper().parseText(yaml)
+
+assertThat(result.person.name, is("Itsuki"))
+assertThat(result.person.age, is(78))
+assertThat(result.person.pets.size(), is(2))
+assertThat(result.person.pets[0], is("rabbit"))
+assertThat(result.person.pets[1], is("snake"))
diff --git a/itests/pom.xml b/itests/pom.xml
index d83e3e60fda..a89697ce3d8 100644
--- a/itests/pom.xml
+++ b/itests/pom.xml
@@ -17,6 +17,7 @@
openHAB Add-ons :: Integration Tests
+ org.openhab.automation.groovyscripting.tests
org.openhab.automation.jsscriptingnashorn.tests
org.openhab.binding.astro.tests
org.openhab.binding.avmfritz.tests