admin管理员组

文章数量:1794759

Flink报org.objenesis.strategy.InstantiatorStrategy原因及解决方案

Flink报org.objenesis.strategy.InstantiatorStrategy原因及解决方案

一.场景

当在Flink中使用POJO时,经常会出现该异常,代码如下: 1.POJO类:

class WordWithCount(word : String, count : Int){ def this(){ this(null, 0) } }

2.逻辑代码

val input = execution.fromElements( new WordWithCount("hello", 1), new WordWithCount("word", 2)) val result = input .groupBy("word") .sum("count") // 分组求和 .setParallelism(1) // 设置并行度 .sortPartition("count", Order.DESCENDING) // 降序排序 result.print()

3.报错信

Exception in thread "main" java.lang.NoClassDefFoundError: org/objenesis/strategy/InstantiatorStrategy at org.apache.flink.api.java.typeutils.GenericTypeInfo.createSerializer(GenericTypeInfo.java:90) at org.apache.flink.api.scala.ExecutionEnvironment.fromCollection(ExecutionEnvironment.scala:421) at org.apache.flink.api.scala.ExecutionEnvironment.fromElements(ExecutionEnvironment.scala:455) at cn.demo.SZTest$.main(SZTest.scala:36) at cn.demo.SZTest.main(SZTest.scala) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) Caused by: java.lang.ClassNotFoundException: org.objenesis.strategy.InstantiatorStrategy at java.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 10 more 二.原因分析

1.objenesis简介 objenesis是一个小型Java类库用来实例化一个特定class的对象。

2.使用场合 Java已经支持使用Class.newInstance()动态实例化类的实例。但是类必须拥有一个合适的构造器。有很多场景下不能使用这种方式实例化类,比如:

  • 构造器需要参数
  • 构造器有side effects
  • 构造器会抛异常

因此,在类库中经常会有类必须拥有一个默认构造器的限制。Objenesis通过绕开对象实例构造器来克服这个限制。但是在Scala中不支持!

3.典型使用 实例化一个对象而不调用构造器是一个特殊的任务,然而在一些特定的场合是有用的:

  • 序列化,远程调用和持久化 -对象需要实例化并存储为到一个特殊的状态,而没有调用代码。
  • 代理,AOP库和Mock对象 -类可以被子类继承而子类不用担心父类的构造器。
  • 容器框架 -对象可以以非标准的方式被动态实例化。
三.解决方案

对于使用Scala作为编程语言的程序来说,Scala对objenesis不支持,因此,不建议使用POJO类而改用样例类!

case class WordWithCount(word : String, count : Int){ def this(){ this(null, 0) } }

执行结果:

本文标签: 解决方案原因orgFlinkobjenesis