java:从XML文件读取转换Unable to load step info from XML step nodejava.util.ConcurrentModificationException

问题现象

java 调用Kettle时候,提示

错误从XML文件读取转换
Unable to load step info from XML step nodejava.util.ConcurrentModificationException
	at java.lang.Thread.run (Thread.java:748)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
	at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
	at java.util.concurrent.FutureTask.run (FutureTask.java:266)
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0 (AsyncExecutionInterceptor.java:115)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint (CglibAopProxy.java:749)
	at org.springframework.cglib.proxy.MethodProxy.invoke (MethodProxy.java:218)
	at com.transino.EtlService.EtlDoSubTask$$FastClassBySpringCGLIB$$bc13f8b4.invoke (<generated>:-1)
	at com.transino.EtlService.EtlDoSubTask.enterSubTask (EtlDoSubTask.java:89)
	at com.transino.EtlService.EtlDoSubTask.doSubTask (EtlDoSubTask.java:154)
	at com.transino.EtlService.EtlDoSubTask.executeSubTask (EtlDoSubTask.java:361)
	at com.transino.EtlService.EtlDoSubTask.dataFileMonitoringDownload (EtlDoSubTask.java:319)
	at com.transino.UtileFile.KettleTool.runTransfer (KettleTool.java:53)
	at org.pentaho.di.trans.TransMeta.<init> (TransMeta.java:2690)
	at org.pentaho.di.trans.TransMeta.<init> (TransMeta.java:2718)
	at org.pentaho.di.trans.TransMeta.<init> (TransMeta.java:2744)
	at org.pentaho.di.trans.TransMeta.<init> (TransMeta.java:2759)
	at org.pentaho.di.trans.TransMeta.<init> (TransMeta.java:2774)
	at org.pentaho.di.trans.TransMeta.<init> (TransMeta.java:2813)
	at org.pentaho.di.trans.TransMeta.loadXML (TransMeta.java:3028)
	at org.pentaho.di.trans.step.StepMeta.<init> (StepMeta.java:280)
	at org.pentaho.di.core.plugins.PluginRegistry.findPluginWithId (PluginRegistry.java:677)
	at org.pentaho.di.core.plugins.PluginRegistry.getPlugins (PluginRegistry.java:230)
	at java.util.ArrayList$Itr.next (ArrayList.java:851)
	at java.util.ArrayList$Itr.checkForComodification (ArrayList.java:901)

模拟复现

首先,你要保证kettle文件没有问题,本机上可以运行,只是java调用有问题。
本项目是多线程产品,多线程调用kettle,传递了kettle文件路径和kettle参数,然后多线程调用时候,偶尔会出现次问题,出现概率随机,DEBUG也无法进行复现。

大多数是:第一次项目启动运行,没有问题,第二次关闭项目再启动,kettle执行一半时候,强行关闭项目,第三次项目启动,复发概率在80%以上。

猜想原因:

1.可能资源没有释放,由于java 调用的是kettleApi,调用一半资源没有释放,导致这个问题。
2.多线程调用初始化代码时线称冲突,由于我们的多线程是并发执行,看执行时间是在同一秒执行的,怀疑代码对多线程有冲突。

解决方案(临时解决方案)

1.使用线称休眠策略解决;

        long i=new Random().nextInt(5000-1000+1)+1000;  //随机1000-5000之间的数值,也就是每个线称延迟1-5秒钟
        Thread.sleep(i);

本策略主要考虑两点:资源释放和代码冲突,通过随机数来控制多线程同时调用kettle中间间隔时差,本次控制在5秒内,是可以接收的范围内,经过多次测试,解决了代码异常的问题。

2.使用try catch 异常捕获
经过测试发现,该异常并不会导致kettle不执行,kettle依旧执行,但是会返回一个错误信息,而kettle中的数据执行没有因此打断,数据也正常加载和处理,所以采用拦截Unable to load step info from XML step nodejava.util.ConcurrentModificationException异常,进行屏蔽即可。

try{
//异常信息
}catch (Exception ex){
//捕获异常即可
}

最后

这是我总结的经验,如果大家有更好的,希望能进行下方留言,谢谢

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页