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

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new 5b32a6311e Rest connection not working in hop server, fixes #8115 
(#8116)
5b32a6311e is described below

commit 5b32a6311e51fe1ab206ec9c16a54208654085b6
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Thu Aug 27 09:00:35 2026 +0200

    Rest connection not working in hop server, fixes #8115 (#8116)
---
 .../main/java/org/apache/hop/metadata/api/HopMetadata.java   | 10 ++++++++++
 .../org/apache/hop/metadata/plugin/MetadataPluginType.java   |  2 +-
 .../java/org/apache/hop/metadata/rest/RestConnection.java    |  3 ++-
 .../java/org/apache/hop/pipeline/transforms/rest/Rest.java   | 12 +++++++++---
 .../org/apache/hop/pipeline/transforms/rest/RestMeta.java    |  3 ++-
 5 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/core/src/main/java/org/apache/hop/metadata/api/HopMetadata.java 
b/core/src/main/java/org/apache/hop/metadata/api/HopMetadata.java
index 3cf6f87de4..d8bf843869 100644
--- a/core/src/main/java/org/apache/hop/metadata/api/HopMetadata.java
+++ b/core/src/main/java/org/apache/hop/metadata/api/HopMetadata.java
@@ -68,4 +68,14 @@ public @interface HopMetadata {
    * @return true if global replace is supported
    */
   boolean supportsGlobalReplace() default false;
+
+  /**
+   * The class loader group this metadata type belongs to. Plugins sharing a 
group share a single
+   * class loader. Set this when transforms or actions in another plugin 
folder use this metadata
+   * class directly: without it the metadata class gets loaded twice (once by 
the metadata plugin,
+   * once by the consumer's class loader) and the two copies are not 
assignment compatible.
+   *
+   * @return the class loader group, empty for the default 
one-class-loader-per-plugin-folder
+   */
+  String classLoaderGroup() default "";
 }
diff --git 
a/core/src/main/java/org/apache/hop/metadata/plugin/MetadataPluginType.java 
b/core/src/main/java/org/apache/hop/metadata/plugin/MetadataPluginType.java
index 490daca1e2..e7f963f3fa 100644
--- a/core/src/main/java/org/apache/hop/metadata/plugin/MetadataPluginType.java
+++ b/core/src/main/java/org/apache/hop/metadata/plugin/MetadataPluginType.java
@@ -104,6 +104,6 @@ public class MetadataPluginType extends 
BasePluginType<HopMetadata> {
 
   @Override
   protected String extractClassLoaderGroup(HopMetadata annotation) {
-    return null;
+    return annotation.classLoaderGroup();
   }
 }
diff --git 
a/plugins/misc/rest/src/main/java/org/apache/hop/metadata/rest/RestConnection.java
 
b/plugins/misc/rest/src/main/java/org/apache/hop/metadata/rest/RestConnection.java
index 5d7012c327..4e3f9e71b4 100644
--- 
a/plugins/misc/rest/src/main/java/org/apache/hop/metadata/rest/RestConnection.java
+++ 
b/plugins/misc/rest/src/main/java/org/apache/hop/metadata/rest/RestConnection.java
@@ -67,7 +67,8 @@ import org.apache.hop.metadata.rest.client.RestOAuth2Grant;
     category = HopMetadataCategory.CONNECTIONS,
     documentationUrl = "/metadata-types/rest-connection.html",
     hopMetadataPropertyType = HopMetadataPropertyType.REST_CONNECTION,
-    supportsGlobalReplace = true)
+    supportsGlobalReplace = true,
+    classLoaderGroup = "rest")
 // It is optional to disable SSL/TLS
 @SuppressWarnings({"java:S5527", "java:S4830", "java:S4423"})
 public class RestConnection extends HopMetadataBase implements IHopMetadata {
diff --git 
a/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/Rest.java
 
b/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/Rest.java
index 531f68e407..72fb743a1e 100644
--- 
a/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/Rest.java
+++ 
b/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/Rest.java
@@ -2203,14 +2203,20 @@ public class Rest extends BaseTransform<RestMeta, 
RestData> {
         try {
           this.connection =
               
metadataProvider.getSerializer(RestConnection.class).load(data.connectionName);
-          if (this.connection != null) {
-            this.connection.setVariables(this);
+          if (this.connection == null) {
+            throw new HopRuntimeException(
+                "REST connection " + data.connectionName + " could not be 
found");
           }
+          this.connection.setVariables(this);
           baseUrl = resolve(connection.getBaseUrl());
 
+        } catch (HopRuntimeException e) {
+          throw e;
         } catch (Exception e) {
+          // Keep the cause: a class loader split between the metadata plugin 
and this transform
+          // surfaces here as a ClassCastException, which is not a missing 
connection at all.
           throw new HopRuntimeException(
-              "REST connection " + meta.getConnectionName() + " could not be 
found");
+              "REST connection " + data.connectionName + " could not be 
loaded", e);
         }
       }
 
diff --git 
a/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
 
b/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
index 3c70ab749a..b67fc2f98b 100644
--- 
a/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
+++ 
b/plugins/transforms/rest/src/main/java/org/apache/hop/pipeline/transforms/rest/RestMeta.java
@@ -55,7 +55,8 @@ import 
org.apache.hop.pipeline.transforms.rest.fields.ResultField;
     description = "i18n::Rest.Description",
     categoryDescription = 
"i18n:org.apache.hop.pipeline.transform:BaseTransform.Category.Utility",
     keywords = "i18n::RestMeta.keyword",
-    documentationUrl = "/pipeline/transforms/rest.html")
+    documentationUrl = "/pipeline/transforms/rest.html",
+    classLoaderGroup = "rest")
 public class RestMeta extends BaseTransformMeta<Rest, RestData> {
   private static final Class<?> PKG = RestMeta.class;
 

Reply via email to