我有一个使用名为Geometry的自定义数据类型的Kettle步骤。我有以下几行代码从第一行获取元信息:
geometryInterface = data.prevRowMeta.getValueMeta(meta.getGeomSelectedCol());
然后以下来获取Geometry值:
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是自定义数据类型。我猜它是一个类加载器问题。您对此的意见表示赞赏。
答案 0 :(得分:2)
是的,它是一个类加载器问题。当两个不同的插件尝试加载和使用相同的类(即重复的JAR,每个插件中有一个)然后尝试相互通信,或者两个类正在从不同的类加载器解析ValueMetaGeometry类时,就会发生这种情况。如果在父类加载器中加载类(例如,如果JAR在data-integration / lib中),并且也由插件类加载(如果JAR在插件的lib /中),则可能发生后一种情况。夹)。插件类将在插件的类加载器中找到它,其他使用者将在父类加载器中找到ValueMetaGeometry类。
我需要更多地了解您的转换和步骤以帮助解决问题,但一种可能的解决方案是使用PluginRegistry获取ValueMetaGeometry类并将线程上下文类加载器设置为ValueMetaGeometry.class .getClassLoader()。您也可以使用反射来调用ValueMetaGeometry对象上的方法。
请注意,通常是引入此类问题的脚本步骤。我的建议是创建在内部使用ValueMetaGeometry方法的步骤插件,但生成其他核心Kettle数据类型(如String,Integer等)。例如,我有一个ValueMetaMap类型以及Fields to Map和Map to Fields的步骤插件:
https://github.com/mattyb149/pdi-valuemeta-map
这些步骤将ValueMetaMap类的使用黑盒子插入到可以"说"的插件中。它。
答案 1 :(得分:1)
这确实是一个类加载器问题。数据类型是核心分布,而步骤是使用反射加载的。一旦我将数据类型代码拉入步骤代码,它就可以正常工作。