This is an automated email from the ASF dual-hosted git repository.

dominikriemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to refs/heads/dev by this push:
     new faa9e05ed4 refactor: Remove groovy support from adapter script 
transformation (#4653)
faa9e05ed4 is described below

commit faa9e05ed44dd5f9c686db5e8f8d34cd825d2fd3
Author: Sven Oehler <[email protected]>
AuthorDate: Tue Jun 30 08:31:54 2026 +0200

    refactor: Remove groovy support from adapter script transformation (#4653)
---
 pom.xml                                            |   7 -
 .../management/management/GuessManagement.java     |   2 +-
 .../transformer/api/TransformationEngines.java     |  26 ++
 streampipes-connect-transformer-groovy/pom.xml     |  78 -----
 .../transformer/groovy/GroovyScriptContext.java    |  25 --
 .../transformer/groovy/GroovyScriptEngine.java     |  80 ------
 .../sandbox/RestrictedGroovyClassLoader.java       |  59 ----
 .../transformer/groovy/sandbox/SandboxPolicy.java  | 187 ------------
 .../transformer/groovy/sandbox/ScriptSandbox.java  |  51 ----
 .../ast/AstChecksCompilationCustomizer.java        |  39 ---
 .../groovy/sandbox/ast/AstChecksVisitor.java       | 109 -------
 .../sandbox/ast/SecureCustomizerFactory.java       |  59 ----
 .../error/SandboxCompilationMessageResolver.java   | 112 --------
 .../SandboxViolationClassNotFoundException.java    |  26 --
 .../sandbox/error/SandboxViolationException.java   |  26 --
 .../transformer/groovy/GroovyScriptEngineTest.java | 318 ---------------------
 streampipes-extensions-management/pom.xml          |   5 -
 .../connect/AdapterWorkerManagement.java           |  13 +
 .../connect/adapter/ScriptContextResolver.java     |   4 -
 .../minimal/StreamPipesCoreApplicationMinimal.java |   2 -
 streampipes-service-core/pom.xml                   |   5 -
 .../service/core/StreamPipesCoreApplication.java   |   2 -
 streampipes-service-extensions/pom.xml             |   5 -
 .../StreamPipesExtensionsServiceBase.java          |   2 -
 24 files changed, 40 insertions(+), 1202 deletions(-)

diff --git a/pom.xml b/pom.xml
index f5bac2c0bf..c5f8dde27a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,7 +60,6 @@
         <error-prone.version>2.10.0</error-prone.version>
         <google-maps-services.version>2.2.0</google-maps-services.version>
         <graalvm.js.version>25.0.2</graalvm.js.version>
-        <groovy.version>5.0.3</groovy.version>
         <grpc.version>1.80.0</grpc.version>
         <guava.version>33.5.0-jre</guava.version>
         <hadoop.version>3.4.1</hadoop.version>
@@ -459,11 +458,6 @@
                 <artifactId>commons-configuration2</artifactId>
                 <version>${commons-configuration2.version}</version>
             </dependency>
-            <dependency>
-                <groupId>org.apache.groovy</groupId>
-                <artifactId>groovy</artifactId>
-                <version>${groovy.version}</version>
-            </dependency>
             <dependency>
                 <groupId>org.apache.httpcomponents</groupId>
                 <artifactId>fluent-hc</artifactId>
@@ -934,7 +928,6 @@
         <module>streampipes-wrapper-siddhi</module>
         <module>streampipes-wrapper-standalone</module>
         <module>streampipes-connect-transformer-api</module>
-        <module>streampipes-connect-transformer-groovy</module>
         <module>streampipes-connect-transformer-js</module>
         <module>streampipes-health-monitoring</module>
     </modules>
diff --git 
a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/GuessManagement.java
 
b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/GuessManagement.java
index 1cbde82a00..700ad4e0ac 100644
--- 
a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/GuessManagement.java
+++ 
b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/GuessManagement.java
@@ -131,7 +131,7 @@ public class GuessManagement {
           throw new AdapterException("No samples available to transform");
         }
 
-      } catch (ScriptCompilationException | ScriptExecutionException e) {
+      } catch (ScriptCompilationException | ScriptExecutionException | 
IllegalArgumentException e) {
         throw new AdapterException(String.format("Could not execute script: 
%s", e.getMessage()));
       }
     }
diff --git 
a/streampipes-connect-transformer-api/src/main/java/org/apache/streampipes/connect/transformer/api/TransformationEngines.java
 
b/streampipes-connect-transformer-api/src/main/java/org/apache/streampipes/connect/transformer/api/TransformationEngines.java
index 99b2a8863c..01ee009441 100644
--- 
a/streampipes-connect-transformer-api/src/main/java/org/apache/streampipes/connect/transformer/api/TransformationEngines.java
+++ 
b/streampipes-connect-transformer-api/src/main/java/org/apache/streampipes/connect/transformer/api/TransformationEngines.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
+import java.util.stream.Collectors;
 
 public enum TransformationEngines {
 
@@ -36,9 +37,16 @@ public enum TransformationEngines {
   }
 
   public TransformationEngine getTransformationEngine(String language) {
+    validateSupportedLanguage(language);
     return transformationEngines.get(language).get();
   }
 
+  public void validateSupportedLanguage(String language) {
+    if (!transformationEngines.containsKey(language)) {
+      throw new IllegalArgumentException(unsupportedLanguageMessage(language));
+    }
+  }
+
   public List<ScriptMetadata> getAvailableEngineMetadata() {
     return transformationEngines
         .values()
@@ -46,4 +54,22 @@ public enum TransformationEngines {
         .map(transformationEngineSupplier -> 
transformationEngineSupplier.get().metadata())
         .toList();
   }
+
+  private String unsupportedLanguageMessage(String language) {
+    var requestedLanguage = language == null || language.isBlank()
+        ? "missing"
+        : "'" + language + "'";
+
+    var supportedLanguages = transformationEngines.keySet()
+        .stream()
+        .sorted()
+        .collect(Collectors.joining(", "));
+
+    var message = "Unsupported script transformation language " + 
requestedLanguage + ". ";
+    if (supportedLanguages.isBlank()) {
+      return message + "No script transformation languages are available.";
+    }
+
+    return message + "Supported languages: " + supportedLanguages + ".";
+  }
 }
diff --git a/streampipes-connect-transformer-groovy/pom.xml 
b/streampipes-connect-transformer-groovy/pom.xml
deleted file mode 100644
index e634d028da..0000000000
--- a/streampipes-connect-transformer-groovy/pom.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one or more
-  ~ contributor license agreements.  See the NOTICE file distributed with
-  ~ this work for additional information regarding copyright ownership.
-  ~ The ASF licenses this file to You under the Apache License, Version 2.0
-  ~ (the "License"); you may not use this file except in compliance with
-  ~ the License.  You may obtain a copy of the License at
-  ~
-  ~    http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
-  -->
-
-
-<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>
-    <parent>
-        <groupId>org.apache.streampipes</groupId>
-        <artifactId>streampipes-parent</artifactId>
-        <version>0.99.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>streampipes-connect-transformer-groovy</artifactId>
-
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.streampipes</groupId>
-            <artifactId>streampipes-connect-transformer-api</artifactId>
-            <version>0.99.0-SNAPSHOT</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.streampipes</groupId>
-            <artifactId>streampipes-client-api</artifactId>
-            <version>0.99.0-SNAPSHOT</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.groovy</groupId>
-            <artifactId>groovy</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-api</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.streampipes</groupId>
-            <artifactId>streampipes-client</artifactId>
-            <version>0.99.0-SNAPSHOT</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-checkstyle-plugin</artifactId>
-                <configuration>
-                    <propertyExpansion>
-                        
checkstyle.config.base.path=${project.parent.basedir}/tools/maven
-                    </propertyExpansion>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptContext.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptContext.java
deleted file mode 100644
index 4d5f0029e7..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptContext.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy;
-
-import org.apache.streampipes.client.api.IStreamPipesClient;
-import org.apache.streampipes.connect.transformer.api.Context;
-
-public record GroovyScriptContext(IStreamPipesClient client) implements 
Context {
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptEngine.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptEngine.java
deleted file mode 100644
index 1baf7f59d4..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptEngine.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy;
-
-import org.apache.streampipes.connect.transformer.api.Context;
-import org.apache.streampipes.connect.transformer.api.OutputCollector;
-import org.apache.streampipes.connect.transformer.api.ScriptTransformer;
-import org.apache.streampipes.connect.transformer.api.TransformationEngine;
-import 
org.apache.streampipes.connect.transformer.api.exception.ScriptCompilationException;
-import 
org.apache.streampipes.connect.transformer.api.exception.ScriptExecutionException;
-import 
org.apache.streampipes.connect.transformer.api.utils.TransformationEngineConversionUtils;
-import org.apache.streampipes.connect.transformer.groovy.sandbox.ScriptSandbox;
-import org.apache.streampipes.model.connect.ScriptMetadata;
-
-import groovy.lang.Binding;
-import groovy.lang.GroovyShell;
-import groovy.lang.Script;
-import org.codehaus.groovy.runtime.InvokerHelper;
-
-import java.util.Map;
-
-public class GroovyScriptEngine implements TransformationEngine {
-
-  @Override
-  public ScriptMetadata metadata() {
-    return new ScriptMetadata(
-        "groovy",
-        "Groovy",
-        "out.collect(input)"
-    );
-  }
-
-  @Override
-  public ScriptTransformer compile(String code) throws 
ScriptCompilationException {
-    GroovyShell shell = 
ScriptSandbox.createShell(GroovyScriptEngine.class.getClassLoader());
-    Script script;
-    try {
-      script = shell.parse(code);
-    } catch (Exception e) {
-      throw new 
ScriptCompilationException(ScriptSandbox.resolveCompilationErrorMessage(e), e);
-    }
-
-    Class<? extends Script> scriptClass = script.getClass();
-
-    return (input, out, ctx) -> execute(scriptClass, input, out, ctx);
-  }
-
-  private void execute(Class<? extends Script> scriptClass,
-                       Map<String, Object> input,
-                       OutputCollector<Map<String, Object>> out,
-                       Context ctx)
-      throws ScriptExecutionException {
-    try {
-      Binding binding = new Binding();
-      binding.setVariable("input", input);
-      binding.setVariable("out", 
TransformationEngineConversionUtils.convertingCollector(out, 
metadata().language()));
-      binding.setVariable("ctx", ctx);
-      Script scriptInstance = InvokerHelper.createScript(scriptClass, binding);
-      scriptInstance.run();
-    } catch (Exception e) {
-      throw new ScriptExecutionException("Groovy template execution failed", 
e);
-    }
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/RestrictedGroovyClassLoader.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/RestrictedGroovyClassLoader.java
deleted file mode 100644
index adb3e28fca..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/RestrictedGroovyClassLoader.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox;
-
-import 
org.apache.streampipes.connect.transformer.groovy.sandbox.error.SandboxViolationClassNotFoundException;
-
-import groovy.lang.GroovyClassLoader;
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.CompilerConfiguration;
-
-public final class RestrictedGroovyClassLoader extends GroovyClassLoader {
-
-  public RestrictedGroovyClassLoader(ClassLoader parent, CompilerConfiguration 
configuration) {
-    super(parent, configuration);
-  }
-
-  @Override
-  public Class<?> loadClass(String name) throws ClassNotFoundException {
-    rejectForbiddenClass(name);
-    return super.loadClass(name);
-  }
-
-  @Override
-  protected Class<?> loadClass(String name, boolean resolve)
-      throws ClassNotFoundException, CompilationFailedException {
-    rejectForbiddenClass(name);
-    return super.loadClass(name, resolve);
-  }
-
-  @Override
-  public Class loadClass(String name, boolean lookupScriptFiles, boolean 
preferClassOverScript, boolean resolve)
-      throws ClassNotFoundException, CompilationFailedException {
-    rejectForbiddenClass(name);
-    return super.loadClass(name, lookupScriptFiles, preferClassOverScript, 
resolve);
-  }
-
-  private void rejectForbiddenClass(String className) throws 
ClassNotFoundException {
-    if (SandboxPolicy.blocksType(className)) {
-      throw new SandboxViolationClassNotFoundException(
-          SandboxPolicy.VIOLATION_MESSAGE + ": access to class '" + className 
+ "' is forbidden");
-    }
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/SandboxPolicy.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/SandboxPolicy.java
deleted file mode 100644
index 18b41e3b51..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/SandboxPolicy.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox;
-
-import groovy.lang.Binding;
-
-import java.util.List;
-import java.util.Set;
-
-public final class SandboxPolicy {
-
-  public static final String VIOLATION_MESSAGE = "Groovy script violates 
sandbox restrictions";
-
-  private static final List<String> DISALLOWED_IMPORTS = List.of(
-      "java.io.File",
-      "java.io.FileInputStream",
-      "java.io.FileOutputStream",
-      "java.io.RandomAccessFile",
-      "java.net.InetAddress",
-      "java.net.ServerSocket",
-      "java.net.Socket",
-      "java.net.URI",
-      "java.net.URL",
-      "java.lang.Class",
-      "java.lang.ClassLoader",
-      "java.lang.Process",
-      "java.lang.ProcessBuilder",
-      "java.lang.Runtime",
-      "java.lang.System",
-      "java.lang.Thread",
-      "java.nio.channels.FileChannel",
-      "java.nio.file.Files",
-      "java.nio.file.Path",
-      "java.nio.file.Paths",
-      "groovy.lang.GroovyClassLoader",
-      "groovy.lang.GroovyShell",
-      "groovy.transform.ASTTest",
-      "groovy.util.Eval"
-  );
-  private static final List<String> DISALLOWED_STAR_IMPORTS = List.of(
-      "java.io",
-      "java.net",
-      "java.nio",
-      "java.nio.channels",
-      "java.nio.file",
-      "java.lang.reflect",
-      "groovy.io"
-  );
-  private static final List<String> DISALLOWED_STATIC_IMPORTS = List.of(
-      "java.lang.System",
-      "java.lang.Runtime",
-      "java.nio.file.Files",
-      "java.nio.file.Paths"
-  );
-  private static final Set<String> DISABLED_GLOBAL_AST_TRANSFORMATIONS = 
Set.of(
-      "groovy.grape.GrabAnnotationTransformation",
-      "org.codehaus.groovy.transform.ASTTestTransformation",
-      "org.codehaus.groovy.transform.AnnotationCollectorTransform"
-  );
-  private static final Set<String> DISALLOWED_EXACT_TYPES = Set.of(
-      "java.io.File",
-      "java.io.FileInputStream",
-      "java.io.FileOutputStream",
-      "java.io.RandomAccessFile",
-      "java.net.InetAddress",
-      "java.net.ServerSocket",
-      "java.net.Socket",
-      "java.net.URI",
-      "java.net.URL",
-      "java.lang.Class",
-      "java.lang.ClassLoader",
-      "java.lang.Process",
-      "java.lang.ProcessBuilder",
-      "java.lang.Runtime",
-      "java.lang.System",
-      "java.lang.Thread",
-      "java.nio.channels.FileChannel",
-      "java.nio.file.Files",
-      "java.nio.file.Path",
-      "java.nio.file.Paths",
-      "groovy.lang.GroovyClassLoader",
-      "groovy.lang.GroovyShell",
-      "groovy.transform.ASTTest",
-      "groovy.util.Eval"
-  );
-  private static final Set<String> DISALLOWED_SIMPLE_TYPES = Set.of(
-      "File",
-      "FileInputStream",
-      "FileOutputStream",
-      "RandomAccessFile",
-      "InetAddress",
-      "ServerSocket",
-      "Socket",
-      "URI",
-      "URL",
-      "Class",
-      "ClassLoader",
-      "Process",
-      "ProcessBuilder",
-      "Runtime",
-      "System",
-      "Thread",
-      "FileChannel",
-      "Files",
-      "Path",
-      "Paths",
-      "GroovyClassLoader",
-      "GroovyShell",
-      "ASTTest",
-      "Eval"
-  );
-  private static final List<String> DISALLOWED_TYPE_PREFIXES = List.of(
-      "java.io.",
-      "java.net.",
-      "java.nio.",
-      "java.nio.channels.",
-      "java.nio.file.",
-      "java.lang.reflect.",
-      "groovy.io."
-  );
-  private static final Set<String> DISALLOWED_PROPERTY_NAMES = Set.of(
-      "class",
-      "classLoader",
-      "metaClass"
-  );
-
-  private SandboxPolicy() {
-  }
-
-  public static Binding createBinding() {
-    return new Binding();
-  }
-
-  public static List<String> disallowedImports() {
-    return DISALLOWED_IMPORTS;
-  }
-
-  public static List<String> disallowedStarImports() {
-    return DISALLOWED_STAR_IMPORTS;
-  }
-
-  public static List<String> disallowedStaticImports() {
-    return DISALLOWED_STATIC_IMPORTS;
-  }
-
-  public static Set<String> disabledGlobalAstTransformations() {
-    return DISABLED_GLOBAL_AST_TRANSFORMATIONS;
-  }
-
-  public static Set<String> disallowedPropertyNames() {
-    return DISALLOWED_PROPERTY_NAMES;
-  }
-
-  public static boolean blocksType(String typeName) {
-    if (typeName == null || typeName.isBlank()) {
-      return false;
-    }
-
-    if (DISALLOWED_EXACT_TYPES.contains(typeName) || 
DISALLOWED_SIMPLE_TYPES.contains(typeName)) {
-      return true;
-    }
-
-    for (String prefix : DISALLOWED_TYPE_PREFIXES) {
-      if (typeName.startsWith(prefix)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ScriptSandbox.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ScriptSandbox.java
deleted file mode 100644
index 2f26ec4365..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ScriptSandbox.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox;
-
-import 
org.apache.streampipes.connect.transformer.groovy.sandbox.ast.AstChecksCompilationCustomizer;
-import 
org.apache.streampipes.connect.transformer.groovy.sandbox.ast.SecureCustomizerFactory;
-import 
org.apache.streampipes.connect.transformer.groovy.sandbox.error.SandboxCompilationMessageResolver;
-
-import groovy.lang.GroovyShell;
-import org.codehaus.groovy.control.CompilerConfiguration;
-
-public final class ScriptSandbox {
-
-  private ScriptSandbox() {
-  }
-
-  public static GroovyShell createShell(ClassLoader parent) {
-    CompilerConfiguration configuration = new CompilerConfiguration();
-    
configuration.setDisabledGlobalASTTransformations(SandboxPolicy.disabledGlobalAstTransformations());
-    configuration.addCompilationCustomizers(
-        SecureCustomizerFactory.create(),
-        new AstChecksCompilationCustomizer()
-    );
-
-    return new GroovyShell(
-        new RestrictedGroovyClassLoader(parent, configuration),
-        SandboxPolicy.createBinding(),
-        configuration
-    );
-  }
-
-  public static String resolveCompilationErrorMessage(Exception error) {
-    return SandboxCompilationMessageResolver.resolve(error);
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/AstChecksCompilationCustomizer.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/AstChecksCompilationCustomizer.java
deleted file mode 100644
index 05a6a7751d..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/AstChecksCompilationCustomizer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox.ast;
-
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.classgen.GeneratorContext;
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.CompilePhase;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.customizers.CompilationCustomizer;
-
-public final class AstChecksCompilationCustomizer extends 
CompilationCustomizer {
-
-  public AstChecksCompilationCustomizer() {
-    super(CompilePhase.SEMANTIC_ANALYSIS);
-  }
-
-  @Override
-  public void call(SourceUnit source, GeneratorContext context, ClassNode 
classNode)
-      throws CompilationFailedException {
-    new AstChecksVisitor(source).visitClass(classNode);
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/AstChecksVisitor.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/AstChecksVisitor.java
deleted file mode 100644
index 7fd75a2465..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/AstChecksVisitor.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox.ast;
-
-import org.apache.streampipes.connect.transformer.groovy.sandbox.SandboxPolicy;
-import 
org.apache.streampipes.connect.transformer.groovy.sandbox.error.SandboxViolationException;
-
-import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.MethodCallExpression;
-import org.codehaus.groovy.ast.expr.PropertyExpression;
-import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.control.SourceUnit;
-
-public final class AstChecksVisitor extends ClassCodeVisitorSupport {
-
-  private final SourceUnit sourceUnit;
-
-  public AstChecksVisitor(SourceUnit sourceUnit) {
-    this.sourceUnit = sourceUnit;
-  }
-
-  @Override
-  protected SourceUnit getSourceUnit() {
-    return sourceUnit;
-  }
-
-  @Override
-  public void visitConstructorCallExpression(ConstructorCallExpression call) {
-    rejectForbiddenType(call.getType(), "constructor access");
-    super.visitConstructorCallExpression(call);
-  }
-
-  @Override
-  public void visitClassExpression(ClassExpression expression) {
-    rejectForbiddenType(expression.getType(), "class access");
-    super.visitClassExpression(expression);
-  }
-
-  @Override
-  public void visitMethodCallExpression(MethodCallExpression call) {
-    rejectForbiddenExpression(call.getObjectExpression(), "method access");
-    super.visitMethodCallExpression(call);
-  }
-
-  @Override
-  public void visitStaticMethodCallExpression(StaticMethodCallExpression call) 
{
-    rejectForbiddenType(call.getOwnerType(), "static method access");
-    super.visitStaticMethodCallExpression(call);
-  }
-
-  @Override
-  public void visitPropertyExpression(PropertyExpression expression) {
-    String propertyName = expression.getPropertyAsString();
-    if (propertyName != null && 
SandboxPolicy.disallowedPropertyNames().contains(propertyName)) {
-      throw new SandboxViolationException(
-          SandboxPolicy.VIOLATION_MESSAGE + ": access to property '" + 
propertyName + "' is forbidden");
-    }
-
-    rejectForbiddenExpression(expression.getObjectExpression(), "property 
access");
-    super.visitPropertyExpression(expression);
-  }
-
-  private void rejectForbiddenExpression(Expression expression, String 
operation) {
-    if (expression instanceof ClassExpression classExpression) {
-      rejectForbiddenType(classExpression.getType(), operation);
-    } else if (expression instanceof VariableExpression variableExpression) {
-      if (SandboxPolicy.blocksType(variableExpression.getName())) {
-        throw new SandboxViolationException(
-            SandboxPolicy.VIOLATION_MESSAGE + ": access to class '" + 
variableExpression.getName() + "' is forbidden");
-      }
-    } else {
-      rejectForbiddenType(expression.getType(), operation);
-    }
-  }
-
-  private void rejectForbiddenType(ClassNode classNode, String operation) {
-    if (classNode != null) {
-      rejectForbiddenType(classNode.getName(), operation);
-    }
-  }
-
-  private void rejectForbiddenType(String typeName, String operation) {
-    if (SandboxPolicy.blocksType(typeName)) {
-      throw new SandboxViolationException(
-          SandboxPolicy.VIOLATION_MESSAGE + ": " + operation + " to '" + 
typeName + "' is forbidden");
-    }
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/SecureCustomizerFactory.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/SecureCustomizerFactory.java
deleted file mode 100644
index 4447a0ac02..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/ast/SecureCustomizerFactory.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox.ast;
-
-import org.apache.streampipes.connect.transformer.groovy.sandbox.SandboxPolicy;
-
-import org.codehaus.groovy.control.customizers.SecureASTCustomizer;
-
-import java.util.List;
-
-public final class SecureCustomizerFactory {
-
-  private SecureCustomizerFactory() {
-  }
-
-  public static SecureASTCustomizer create() {
-    SecureASTCustomizer customizer = new SecureASTCustomizer();
-    customizer.setClosuresAllowed(true);
-    customizer.setMethodDefinitionAllowed(false);
-    customizer.setPackageAllowed(false);
-    customizer.setIndirectImportCheckEnabled(true);
-    customizer.setDisallowedImports(SandboxPolicy.disallowedImports());
-    customizer.setDisallowedStarImports(SandboxPolicy.disallowedStarImports());
-    
customizer.setDisallowedStaticImports(SandboxPolicy.disallowedStaticImports());
-    
customizer.setDisallowedStaticStarImports(SandboxPolicy.disallowedStaticImports());
-    customizer.setDisallowedReceiversClasses(List.of(
-        java.io.File.class,
-        java.lang.Class.class,
-        java.lang.ClassLoader.class,
-        java.lang.Process.class,
-        java.lang.ProcessBuilder.class,
-        java.lang.Runtime.class,
-        java.lang.System.class,
-        java.lang.Thread.class,
-        java.net.InetAddress.class,
-        java.net.ServerSocket.class,
-        java.net.Socket.class,
-        java.net.URI.class,
-        java.net.URL.class
-    ));
-    return customizer;
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxCompilationMessageResolver.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxCompilationMessageResolver.java
deleted file mode 100644
index 75de065cef..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxCompilationMessageResolver.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox.error;
-
-import org.apache.streampipes.connect.transformer.groovy.sandbox.SandboxPolicy;
-
-import java.util.Optional;
-
-public final class SandboxCompilationMessageResolver {
-
-  private SandboxCompilationMessageResolver() {
-  }
-
-  public static String resolve(Exception error) {
-    Optional<SandboxViolationException> sandboxViolation = 
findSandboxViolation(error);
-    if (sandboxViolation.isPresent()) {
-      return sandboxViolation.get().getMessage();
-    }
-
-    return extractViolationMessage(error.getMessage())
-        .or(() -> extractAllowedError(error.getMessage()))
-        .orElse("Failed to compile Groovy template");
-  }
-
-  private static Optional<SandboxViolationException> 
findSandboxViolation(Throwable error) {
-    Throwable current = error;
-    while (current != null) {
-      if (current instanceof SandboxViolationException sandboxViolation) {
-        return Optional.of(sandboxViolation);
-      } else if (current instanceof SandboxViolationClassNotFoundException 
sandboxViolation) {
-        return Optional.of(new 
SandboxViolationException(sandboxViolation.getMessage()));
-      } else if (current instanceof SecurityException securityException) {
-        return toSandboxViolation(securityException.getMessage());
-      }
-      current = current.getCause();
-    }
-
-    return Optional.empty();
-  }
-
-  private static Optional<SandboxViolationException> toSandboxViolation(String 
message) {
-    if (message == null || message.isBlank()) {
-      return Optional.empty();
-    }
-
-    if (message.contains(SandboxPolicy.VIOLATION_MESSAGE)) {
-      return Optional.of(new SandboxViolationException(message));
-    }
-
-    if (message.contains("is not allowed")) {
-      return Optional.of(new 
SandboxViolationException(SandboxPolicy.VIOLATION_MESSAGE + ": " + message));
-    }
-
-    return Optional.empty();
-  }
-
-  private static Optional<String> extractViolationMessage(String message) {
-    if (message == null) {
-      return Optional.empty();
-    }
-
-    int messageIndex = message.indexOf(SandboxPolicy.VIOLATION_MESSAGE);
-    if (messageIndex < 0) {
-      return Optional.empty();
-    }
-
-    int lineBreakIndex = message.indexOf('\n', messageIndex);
-    if (lineBreakIndex < 0) {
-      return Optional.of(message.substring(messageIndex).trim());
-    }
-
-    return Optional.of(message.substring(messageIndex, lineBreakIndex).trim());
-  }
-
-  private static Optional<String> extractAllowedError(String message) {
-    if (message == null) {
-      return Optional.empty();
-    }
-
-    int messageIndex = message.indexOf("is not allowed");
-    if (messageIndex < 0) {
-      return Optional.empty();
-    }
-
-    int lineStartIndex = message.lastIndexOf('\n', messageIndex);
-    int start = lineStartIndex < 0 ? 0 : lineStartIndex + 1;
-    int lineBreakIndex = message.indexOf('\n', messageIndex);
-    String extracted = (lineBreakIndex < 0 ? message.substring(start) : 
message.substring(start, lineBreakIndex)).trim();
-
-    if (extracted.isEmpty()) {
-      return Optional.empty();
-    }
-
-    return Optional.of(SandboxPolicy.VIOLATION_MESSAGE + ": " + extracted);
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxViolationClassNotFoundException.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxViolationClassNotFoundException.java
deleted file mode 100644
index af7cab2a3f..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxViolationClassNotFoundException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox.error;
-
-public final class SandboxViolationClassNotFoundException extends 
ClassNotFoundException {
-
-  public SandboxViolationClassNotFoundException(String message) {
-    super(message);
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxViolationException.java
 
b/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxViolationException.java
deleted file mode 100644
index 765e1a901e..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/main/java/org/apache/streampipes/connect/transformer/groovy/sandbox/error/SandboxViolationException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy.sandbox.error;
-
-public final class SandboxViolationException extends SecurityException {
-
-  public SandboxViolationException(String message) {
-    super(message);
-  }
-}
diff --git 
a/streampipes-connect-transformer-groovy/src/test/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptEngineTest.java
 
b/streampipes-connect-transformer-groovy/src/test/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptEngineTest.java
deleted file mode 100644
index fa321b24c7..0000000000
--- 
a/streampipes-connect-transformer-groovy/src/test/java/org/apache/streampipes/connect/transformer/groovy/GroovyScriptEngineTest.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.connect.transformer.groovy;
-
-import org.apache.streampipes.client.StreamPipesClient;
-import org.apache.streampipes.client.api.IAdapterApi;
-import org.apache.streampipes.client.api.IStreamPipesClient;
-import org.apache.streampipes.client.api.credentials.CredentialsProvider;
-import org.apache.streampipes.connect.transformer.api.Context;
-import 
org.apache.streampipes.connect.transformer.api.exception.ScriptCompilationException;
-import 
org.apache.streampipes.connect.transformer.api.exception.ScriptExecutionException;
-import org.apache.streampipes.model.connect.adapter.AdapterDescription;
-
-import org.junit.jupiter.api.Test;
-
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertInstanceOf;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class GroovyScriptEngineTest {
-
-  private final GroovyScriptEngine engine = new GroovyScriptEngine();
-
-  @Test
-  void compileAndExecuteSimplePassThroughScript() throws 
ScriptCompilationException, ScriptExecutionException {
-    var transformer = engine.compile("out.collect(input)");
-    var output = new ArrayList<Map<String, Object>>();
-
-    transformer.transform(
-        new LinkedHashMap<>(Map.of("sensor", "machine-1", "value", 42)),
-        output::add,
-        null
-    );
-
-    assertEquals(1, output.size());
-    assertEquals("machine-1", output.get(0).get("sensor"));
-    assertEquals(42, output.get(0).get("value"));
-  }
-
-  @Test
-  void compileAndExecuteFieldReshapingScript() throws 
ScriptCompilationException, ScriptExecutionException {
-    var transformer = engine.compile("""
-        out.collect([
-            reading: [
-                sensor: input.sensor,
-                value: input.value + 1
-            ],
-            tags: [input.tag, "processed"]
-        ])
-        """);
-
-    var output = new ArrayList<Map<String, Object>>();
-    transformer.transform(
-        new LinkedHashMap<>(Map.of("sensor", "machine-2", "value", 9, "tag", 
"lab")),
-        output::add,
-        null
-    );
-
-    assertEquals(1, output.size());
-    assertEquals(Map.of("sensor", "machine-2", "value", 10), 
output.get(0).get("reading"));
-    assertEquals(java.util.List.of("lab", "processed"), 
output.get(0).get("tags"));
-  }
-
-  @Test
-  void executeProvidesOfflineClientThroughContext() throws 
ScriptCompilationException, ScriptExecutionException {
-    var transformer = engine.compile("""
-        out.collect([
-            hasClient: ctx.client() != null
-        ])
-        """);
-
-    var output = new ArrayList<Map<String, Object>>();
-    transformer.transform(
-        Map.of("value", 1),
-        output::add,
-        new GroovyScriptContext(offlineClient())
-    );
-
-    assertEquals(1, output.size());
-    assertEquals(true, output.get(0).get("hasClient"));
-  }
-
-  @Test
-  void executeProvidesContextClientCompatibility() throws 
ScriptCompilationException, ScriptExecutionException {
-    var transformer = engine.compile("""
-        out.collect([
-            ping: ctx.client().ping()
-        ])
-        """);
-
-    var output = new ArrayList<Map<String, Object>>();
-    transformer.transform(
-        Map.of("value", 1),
-        output::add,
-        new ScriptContext(new ScriptClient())
-    );
-
-    assertEquals(1, output.size());
-    assertEquals("pong", output.get(0).get("ping"));
-  }
-
-  @Test
-  void executeCanReadClientResultsInsideVm() throws 
ScriptCompilationException, ScriptExecutionException {
-    var transformer = engine.compile("""
-        def adapters = ctx.client().adapters().all()
-        out.collect([
-            adapterId: adapters[0].elementId,
-            adapterName: adapters[0].name
-        ])
-        """);
-
-    var output = executeSingleEvent(
-        transformer,
-        Map.of("input", "value"),
-        new GroovyScriptContext(scriptClientWithAdapters("adapter-groovy", 
"Groovy Adapter"))
-    );
-
-    assertEquals("adapter-groovy", output.get("adapterId"));
-    assertEquals("Groovy Adapter", output.get("adapterName"));
-  }
-
-  @Test
-  void executeCanSendGuestObjectToClient() throws ScriptCompilationException, 
ScriptExecutionException {
-    var createdAdapters = new ArrayList<AdapterDescription>();
-    var transformer = engine.compile("""
-        def adapter = new 
org.apache.streampipes.model.connect.adapter.AdapterDescription()
-        adapter.elementId = "created-groovy"
-        adapter.name = "Created From Groovy"
-        adapter.running = false
-        ctx.client().adapters().create(adapter)
-        out.collect([created: adapter.elementId])
-        """);
-
-    var output = executeSingleEvent(
-        transformer,
-        Map.of("input", "value"),
-        new 
GroovyScriptContext(scriptClientWithCreateRecorder(createdAdapters))
-    );
-
-    assertEquals("created-groovy", output.get("created"));
-    assertEquals(1, createdAdapters.size());
-    assertEquals("created-groovy", createdAdapters.get(0).getElementId());
-    assertEquals("Created From Groovy", createdAdapters.get(0).getName());
-    assertFalse(createdAdapters.get(0).isRunning());
-  }
-
-  @Test
-  void compileRejectsFileAccess() {
-    assertSandboxViolation("new File('/tmp/blocked').text");
-  }
-
-  @Test
-  void compileRejectsNioFileAccess() {
-    assertSandboxViolation("Files.readString(Paths.get('/tmp/blocked'))");
-  }
-
-  @Test
-  void compileRejectsEnvironmentAccess() {
-    assertSandboxViolation("System.getenv('HOME')");
-  }
-
-  @Test
-  void compileRejectsSystemExit() {
-    assertSandboxViolation("System.exit(0)");
-  }
-
-  @Test
-  void compileRejectsProcessExecution() {
-    assertSandboxViolation("Runtime.getRuntime().exec('id')");
-  }
-
-  @Test
-  void compileRejectsNetworkAccess() {
-    assertSandboxViolation("new Socket('localhost', 80)");
-  }
-
-  @Test
-  void compileRejectsExplicitDangerousImports() {
-    assertSandboxViolation("""
-        import java.lang.reflect.Method
-        out.collect(input)
-        """);
-  }
-
-  @Test
-  void executeWrapsGroovyRuntimeErrors() throws ScriptCompilationException {
-    var transformer = engine.compile("throw new 
IllegalStateException('boom')");
-
-    var exception = assertThrows(
-        ScriptExecutionException.class,
-        () -> transformer.transform(Map.of("value", 1), event -> {
-        }, null)
-    );
-
-    assertEquals("Groovy template execution failed", exception.getMessage());
-    assertInstanceOf(Exception.class, exception.getCause());
-  }
-
-  private void assertSandboxViolation(String script) {
-    var exception = assertThrows(
-        ScriptCompilationException.class,
-        () -> engine.compile(script)
-    );
-
-    assertTrue(exception.getMessage().contains("sandbox restrictions"));
-  }
-
-  private static Map<String, Object> executeSingleEvent(
-      org.apache.streampipes.connect.transformer.api.ScriptTransformer 
transformer,
-      Map<String, Object> input,
-      Context context
-  ) throws ScriptExecutionException {
-    var output = new ArrayList<Map<String, Object>>();
-    transformer.transform(new LinkedHashMap<>(input), output::add, context);
-    return output.get(0);
-  }
-
-  private static CredentialsProvider emptyCredentials() {
-    return List::of;
-  }
-
-  private static StreamPipesClient offlineClient() {
-    return StreamPipesClient.create("localhost", 1, emptyCredentials(), true);
-  }
-
-  private static IStreamPipesClient scriptClientWithAdapters(String elementId, 
String name) {
-    var adapter = new AdapterDescription();
-    adapter.setElementId(elementId);
-    adapter.setName(name);
-    return scriptClient(adapterApi(List.of(adapter), null));
-  }
-
-  private static IStreamPipesClient 
scriptClientWithCreateRecorder(List<AdapterDescription> createdAdapters) {
-    return scriptClient(adapterApi(List.of(), createdAdapters));
-  }
-
-  private static IStreamPipesClient scriptClient(IAdapterApi adapterApi) {
-    return (IStreamPipesClient) Proxy.newProxyInstance(
-        GroovyScriptEngineTest.class.getClassLoader(),
-        new Class<?>[]{IStreamPipesClient.class},
-        (proxy, method, args) -> switch (method.getName()) {
-          case "adapters" -> adapterApi;
-          case "getCredentials" -> emptyCredentials();
-          case "getConfig", "getConnectionConfig" -> null;
-          case "toString" -> "ScriptClientProxy";
-          case "hashCode" -> System.identityHashCode(proxy);
-          case "equals" -> proxy == args[0];
-          default -> throw new UnsupportedOperationException("Unsupported 
client method: " + method.getName());
-        }
-    );
-  }
-
-  private static IAdapterApi adapterApi(List<AdapterDescription> adapters, 
List<AdapterDescription> createdAdapters) {
-    return (IAdapterApi) Proxy.newProxyInstance(
-        GroovyScriptEngineTest.class.getClassLoader(),
-        new Class<?>[]{IAdapterApi.class},
-        (proxy, method, args) -> switch (method.getName()) {
-          case "all" -> adapters;
-          case "create" -> {
-            if (createdAdapters != null) {
-              createdAdapters.add(new AdapterDescription((AdapterDescription) 
args[0]));
-            }
-            yield null;
-          }
-          case "get" -> java.util.Optional.empty();
-          case "delete", "update" -> null;
-          case "toString" -> "AdapterApiProxy";
-          case "hashCode" -> System.identityHashCode(proxy);
-          case "equals" -> proxy == args[0];
-          default -> throw new UnsupportedOperationException("Unsupported 
adapter method: " + method.getName());
-        }
-    );
-  }
-
-  private static final class ScriptContext implements Context {
-
-    private final ScriptClient client;
-
-    private ScriptContext(ScriptClient client) {
-      this.client = client;
-    }
-
-    public ScriptClient client() {
-      return client;
-    }
-  }
-
-  private static final class ScriptClient {
-
-    public String ping() {
-      return "pong";
-    }
-  }
-}
diff --git a/streampipes-extensions-management/pom.xml 
b/streampipes-extensions-management/pom.xml
index 685223d0f0..5227780aa5 100644
--- a/streampipes-extensions-management/pom.xml
+++ b/streampipes-extensions-management/pom.xml
@@ -89,11 +89,6 @@
             <artifactId>streampipes-vocabulary</artifactId>
             <version>0.99.0-SNAPSHOT</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.streampipes</groupId>
-            <artifactId>streampipes-connect-transformer-groovy</artifactId>
-            <version>0.99.0-SNAPSHOT</version>
-        </dependency>
 
 
         <!-- External dependencies -->
diff --git 
a/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/AdapterWorkerManagement.java
 
b/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/AdapterWorkerManagement.java
index 4df5066ff1..ea0df9a89d 100644
--- 
a/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/AdapterWorkerManagement.java
+++ 
b/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/AdapterWorkerManagement.java
@@ -19,6 +19,7 @@
 package org.apache.streampipes.extensions.management.connect;
 
 import org.apache.streampipes.commons.exceptions.connect.AdapterException;
+import org.apache.streampipes.connect.transformer.api.TransformationEngines;
 import org.apache.streampipes.extensions.api.connect.StreamPipesAdapter;
 import 
org.apache.streampipes.extensions.api.connect.context.IAdapterRuntimeContext;
 import org.apache.streampipes.extensions.api.monitoring.SpMonitoringManager;
@@ -63,6 +64,7 @@ public class AdapterWorkerManagement {
 
       if (adapter.isPresent()) {
         var newAdapterInstance = 
adapter.get().declareConfig().getSupplier().get();
+        validateScriptLanguage(adapterDescription);
         runningAdapterInstances.addAdapter(
             adapterDescription.getElementId(),
             newAdapterInstance,
@@ -115,6 +117,17 @@ public class AdapterWorkerManagement {
     return new AdapterContextGenerator().makeRuntimeContext(adapterInstanceId);
   }
 
+  private void validateScriptLanguage(AdapterDescription adapterDescription) 
throws AdapterException {
+    var transformationConfig = adapterDescription.getTransformationConfig();
+    if (transformationConfig != null && transformationConfig.isScriptActive()) 
{
+      try {
+        
TransformationEngines.INSTANCE.validateSupportedLanguage(transformationConfig.getLanguage());
+      } catch (IllegalArgumentException e) {
+        throw new AdapterException(e.getMessage(), e);
+      }
+    }
+  }
+
   private void resetMonitoring(String elementId) {
     SpMonitoringManager.INSTANCE.reset(elementId);
   }
diff --git 
a/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/adapter/ScriptContextResolver.java
 
b/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/adapter/ScriptContextResolver.java
index a61f311a96..338fe6aeec 100644
--- 
a/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/adapter/ScriptContextResolver.java
+++ 
b/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/adapter/ScriptContextResolver.java
@@ -20,7 +20,6 @@ package 
org.apache.streampipes.extensions.management.connect.adapter;
 
 import org.apache.streampipes.client.api.IStreamPipesClient;
 import org.apache.streampipes.connect.transformer.api.Context;
-import org.apache.streampipes.connect.transformer.groovy.GroovyScriptContext;
 import org.apache.streampipes.connect.transformer.js.GraalJsScriptContext;
 import 
org.apache.streampipes.extensions.management.client.StreamPipesClientResolver;
 
@@ -40,9 +39,6 @@ public class ScriptContextResolver {
       case "javascript" -> {
         return new GraalJsScriptContext(client);
       }
-      case "groovy" -> {
-        return new GroovyScriptContext(client);
-      }
       default -> throw new UnsupportedOperationException("Unsupported 
language: " + language);
     }
   }
diff --git 
a/streampipes-service-core-minimal/src/main/java/org/apache/streampipes/service/core/minimal/StreamPipesCoreApplicationMinimal.java
 
b/streampipes-service-core-minimal/src/main/java/org/apache/streampipes/service/core/minimal/StreamPipesCoreApplicationMinimal.java
index 467be87746..fa44840899 100644
--- 
a/streampipes-service-core-minimal/src/main/java/org/apache/streampipes/service/core/minimal/StreamPipesCoreApplicationMinimal.java
+++ 
b/streampipes-service-core-minimal/src/main/java/org/apache/streampipes/service/core/minimal/StreamPipesCoreApplicationMinimal.java
@@ -18,7 +18,6 @@
 
 package org.apache.streampipes.service.core.minimal;
 
-import org.apache.streampipes.connect.transformer.groovy.GroovyScriptEngine;
 import org.apache.streampipes.connect.transformer.js.GraalJsScriptEngine;
 import org.apache.streampipes.messaging.mqtt.SpMqttProtocolFactory;
 import org.apache.streampipes.messaging.nats.SpNatsProtocolFactory;
@@ -59,7 +58,6 @@ public class StreamPipesCoreApplicationMinimal extends 
StreamPipesCoreApplicatio
         new SpMqttProtocolFactory()
     ),
         List.of(
-            () -> new GroovyScriptEngine(),
             () -> new GraalJsScriptEngine()
         ));
   }
diff --git a/streampipes-service-core/pom.xml b/streampipes-service-core/pom.xml
index 62a2a2f4aa..0dec99dba5 100644
--- a/streampipes-service-core/pom.xml
+++ b/streampipes-service-core/pom.xml
@@ -52,11 +52,6 @@
             <artifactId>streampipes-service-base</artifactId>
             <version>0.99.0-SNAPSHOT</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.streampipes</groupId>
-            <artifactId>streampipes-connect-transformer-groovy</artifactId>
-            <version>0.99.0-SNAPSHOT</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.streampipes</groupId>
             <artifactId>streampipes-connect-transformer-js</artifactId>
diff --git 
a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/StreamPipesCoreApplication.java
 
b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/StreamPipesCoreApplication.java
index c563d1f2b3..ab3570a0ea 100644
--- 
a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/StreamPipesCoreApplication.java
+++ 
b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/StreamPipesCoreApplication.java
@@ -23,7 +23,6 @@ import 
org.apache.streampipes.connect.management.management.AdapterMasterManagem
 import org.apache.streampipes.connect.management.management.WorkerRestClient;
 import org.apache.streampipes.connect.transformer.api.TransformationEngine;
 import org.apache.streampipes.connect.transformer.api.TransformationEngines;
-import org.apache.streampipes.connect.transformer.groovy.GroovyScriptEngine;
 import org.apache.streampipes.connect.transformer.js.GraalJsScriptEngine;
 import org.apache.streampipes.health.monitoring.ExtensionHealthCheck;
 import org.apache.streampipes.health.monitoring.ResourceProvider;
@@ -129,7 +128,6 @@ public class StreamPipesCoreApplication extends 
StreamPipesServiceBase {
             new SpMqttProtocolFactory(),
             new SpPulsarProtocolFactory()),
         List.of(
-            GroovyScriptEngine::new,
             GraalJsScriptEngine::new
         )
     );
diff --git a/streampipes-service-extensions/pom.xml 
b/streampipes-service-extensions/pom.xml
index 4d07bc7c9c..982d017749 100644
--- a/streampipes-service-extensions/pom.xml
+++ b/streampipes-service-extensions/pom.xml
@@ -39,11 +39,6 @@
             <artifactId>streampipes-connect-transformer-api</artifactId>
             <version>0.99.0-SNAPSHOT</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.streampipes</groupId>
-            <artifactId>streampipes-connect-transformer-groovy</artifactId>
-            <version>0.99.0-SNAPSHOT</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.streampipes</groupId>
             <artifactId>streampipes-connect-transformer-js</artifactId>
diff --git 
a/streampipes-service-extensions/src/main/java/org/apache/streampipes/service/extensions/StreamPipesExtensionsServiceBase.java
 
b/streampipes-service-extensions/src/main/java/org/apache/streampipes/service/extensions/StreamPipesExtensionsServiceBase.java
index dc4681a204..e09c2871e7 100644
--- 
a/streampipes-service-extensions/src/main/java/org/apache/streampipes/service/extensions/StreamPipesExtensionsServiceBase.java
+++ 
b/streampipes-service-extensions/src/main/java/org/apache/streampipes/service/extensions/StreamPipesExtensionsServiceBase.java
@@ -22,7 +22,6 @@ import org.apache.streampipes.client.StreamPipesClient;
 import org.apache.streampipes.commons.environment.Environments;
 import org.apache.streampipes.connect.transformer.api.TransformationEngine;
 import org.apache.streampipes.connect.transformer.api.TransformationEngines;
-import org.apache.streampipes.connect.transformer.groovy.GroovyScriptEngine;
 import org.apache.streampipes.connect.transformer.js.GraalJsScriptEngine;
 import org.apache.streampipes.extensions.api.limiter.SpRateLimiter;
 import org.apache.streampipes.extensions.api.migration.IModelMigrator;
@@ -98,7 +97,6 @@ public abstract class StreamPipesExtensionsServiceBase 
extends StreamPipesServic
       SpRateLimiter.INSTANCE.createRateLimiter();
 
       registerTransformationEngines(List.of(
-          GroovyScriptEngine::new,
           GraalJsScriptEngine::new
       ));
 

Reply via email to