Search code examples
javapentahokettle

How to obtain the errors from a Pentaho job using the Java API?


I'm executing some Pentaho jobs using the following code (not mine, just from a legacy app. I must change the code if needed):

JobMeta jobMeta = new JobMeta(jobName, null);
Job job = new Job(null, jobMeta);
job.start();
job.waitUntilFinished();

if (job.getErrors() != 0) {
    logger.error("Error encountered!");
    throw new RuntimeException(getTrace(job.getStackTrace()));
}

//...

private String getTrace(StackTraceElement[] elements) {
    StringBuilder sb = new StringBuilder();
    for (StackTraceElement element : elements) {
        sb.append(element.toString());
    }
    return sb.toString();
}

Everything seems to be fine but the if statement returns true and I get a crappy non-sensical message like this:

2015-03-29 16:30:43,658 INFO  [com.foo.bar.component.ETLComponent] ERROR on job /home/path/to/pentaho/jobs/main_job.kjb
java.lang.RuntimeException:
        at com.foo.barpentaho.KettleService.executeJob(KettleService.java:48)  //my class
        at com.foo.bar.component.ETLComponent.process(ETLComponent.java:64)    //my class
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.mule.model.resolvers.AbstractEntryPointResolver.invokeMethod(AbstractEntryPointResolver.java:151)
        at org.mule.model.resolvers.ExplicitMethodEntryPointResolver.invoke(ExplicitMethodEntryPointResolver.java:93)
        at org.mule.model.resolvers.DefaultEntryPointResolverSet.invoke(DefaultEntryPointResolverSet.java:39)
        at org.mule.component.DefaultComponentLifecycleAdapter.invoke(DefaultComponentLifecycleAdapter.java:350)
        at org.mule.component.AbstractJavaComponent.invokeComponentInstance(AbstractJavaComponent.java:86)
        at org.mule.component.AbstractJavaComponent.doInvoke(AbstractJavaComponent.java:77)
        at org.mule.component.AbstractComponent.invokeInternal(AbstractComponent.java:126)
        at org.mule.component.AbstractComponent.access$000(AbstractComponent.java:61)
        at org.mule.component.AbstractComponent$1$1.process(AbstractComponent.java:242)
        at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:99)
        at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:66)
        at org.mule.processor.chain.InterceptingChainLifecycleWrapper.doProcess(InterceptingChainLifecycleWrapper.java:56)
        at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:66)
        at org.mule.processor.chain.InterceptingChainLifecycleWrapper.process(InterceptingChainLifecycleWrapper.java:87)
        at org.mule.component.AbstractComponent.process(AbstractComponent.java:160)
        at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:99)
        at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:66)
        at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:105)
        at org.mule.interceptor.AbstractEnvelopeInterceptor.process(AbstractEnvelopeInterceptor.java:55)
        at org.mule.processor.AsyncInterceptingMessageProcessor.processNextTimed(AsyncInterceptingMessageProcessor.java:111)
        at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker.doRun(AsyncInterceptingMessageProcessor.java:158)
        at org.mule.work.AbstractMuleEventWork.run(AbstractMuleEventWork.java:43)
        at org.mule.work.WorkerContext.run(WorkerContext.java:310)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)

Searching on the net, I find this code from the Pentaho API examples (uses Pentaho 5 but the idea remains the same):

String filename = "..."; //path for the job to execute
TransMeta transMeta = new TransMeta(filename);
Trans trans = new Trans(transMeta);

trans.execute(null); // You can pass arguments instead of null.
trans.waitUntilFinished();
if ( trans.getErrors() > 0 )
{
  throw new RuntimeException( "There were errors during transformation execution." );
}

So I will get a non-sensical message again. I've searched into the javadoc and there's no useful info obtain the results with errors.

How can I obtain the proper error messages from the results of the Pentaho job executed?

I'm using Pentaho 4.3.


Solution

  • CentralLogStore can be used to get proper error messages from Job execution step. I am using following code for the same purpose in Custom Java Api:

        job.waitUntilFinished();
        if (job.getErrors() > 0) {
          Log4jBufferAppender appender = CentralLogStore.getAppender();
          appender.removeGeneralMessages();
          String logText = appender.getBuffer(job.getLogChannelId(), false).toString();
          CentralLogStore.discardLines(job.getLogChannelId(), false);
          throw new RuntimeException(logText);
        } 
    

    And the error messages look like:

    Job-62001 Error in [Processes/SubProcesses/ETL Report Transformation Process.process/Get Record Count]
    Running Get_Number_Of_Records Transformation occurred error.
    caused by: org.pentaho.di.core.exception.KettleException: 
    We failed to initialize at least one step.  Execution can not begin!
        at org.pentaho.di.trans.Trans.prepareExecution(Trans.java:823)
        ...
    

    More details can be found on the wiki here.