Search code examples
javapentahokettlepdi

ClassCastException in Kettle Step


I have a Kettle step that uses a custom data type called Geometry. I have the following lines of code that gets the meta information from the first row:

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

And then the following to get the Geometry value:

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

When I run the step, I get the following exception:

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

where ValueMetaGeometry is the custom datatype. I am guessing its a class loader issue. Your inputs on the same would be appreciated.


Solution

  • Yep it's a classloader issue. This can happen when two different plugins try to load and use the same class (i.e. duplicate JARs, one in each plugin) and then try to talk to each other, or if two classes are resolving the ValueMetaGeometry class from different classloaders. The latter case can happen if the class is loaded in the parent classloader (if the JAR is in data-integration/lib, for example) and also loaded by a plugin class (if the JAR is in the plugin's lib/ folder). The plugin class will find it in the plugin's classloader, where the other consumer will find the ValueMetaGeometry class in the parent classloader.

    I'd need to know more about your transformation and step(s) to help fix the problem, but one possible solution is to use PluginRegistry to get at your ValueMetaGeometry class and set your thread context classloader to ValueMetaGeometry.class.getClassLoader(). Also you may be able to use reflection to call methods on the ValueMetaGeometry objects.

    Note that it is usually the scripting steps that introduce this kind of issue. My advice is to create step plugins that use the ValueMetaGeometry methods internally, but produce other core Kettle datatypes (like String, Integer, etc.). For example, I have a ValueMetaMap type along with step plugins for Fields to Map and Map to Fields:

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

    The steps black-box the use of the ValueMetaMap class to the plugins that can "speak" to it.