1

我有一个使用名为 Geometry 的自定义数据类型的 Kettle 步骤。我有以下代码行从第一行获取元信息:

geometryInterface = data.prevRowMeta.getValueMeta(meta.getGeomSelectedCol());

然后如下获取几何值:

geometry = ((ValueMetaGeometry)geometryInterface).getGeometry(r[meta.getGeomSelectedCol()]);

当我运行该步骤时,出现以下异常:

 java.lang.ClassCastException: org.pentaho.di.core.row.value.ValueMetaGeometry cannot be cast to org.pentaho.di.core.row.value.ValueMetaGeometry

其中 ValueMetaGeometry 是自定义数据类型。我猜它是一个类加载器问题。您对此的意见将不胜感激。

4

2 回答 2

2

是的,这是一个类加载器问题。当两个不同的插件尝试加载和使用同一个类(即重复的 JAR,每个插件中都有一个)然后尝试相互通信,或者如果两个类从不同的类加载器解析 ValueMetaGeometry 类时,就会发生这种情况。如果类在父类加载器中加载(例如,如果 JAR 在 data-integration/lib 中)并且还由插件类加载(如果 JAR 在插件的 lib/ 文件夹中),则可能会发生后一种情况。插件类将在插件的类加载器中找到它,而其他使用者将在父类加载器中找到 ValueMetaGeometry 类。

我需要更多地了解您的转换和步骤以帮助解决问题,但一种可能的解决方案是使用 PluginRegistry 获取您的 ValueMetaGeometry 类并将您的线程上下文类加载器设置为 ValueMetaGeometry.class.getClassLoader()。您也可以使用反射来调用 ValueMetaGeometry 对象的方法。

请注意,通常是脚本步骤会引入此类问题。我的建议是创建在内部使用 ValueMetaGeometry 方法的步骤插件,但生成其他核心 Kettle 数据类型(如字符串、整数等)。例如,我有一个 ValueMetaMap 类型以及 Fields to Map 和 Map to Fields 的步骤插件:

https://github.com/mattyb149/pdi-valuemeta-map

这些步骤将 ValueMetaMap 类的使用黑盒化到可以与之“对话”的插件。

于 2014-12-30T16:40:00.060 回答
1

这确实是一个类加载器问题。数据类型是核心分布,而步骤是使用反射加载的。一旦我将数据类型代码提取到步骤代码中,它就可以正常工作了。

于 2014-12-30T16:21:07.710 回答