Jobs written in Talend Open Studio communicate with child jobs using Context Variables. To return data from a child job using a Context Variable, define an Object variable that is a java.util.Map.
Off-the-shelf, Talend Open Studio's Context Variable facility supports passing parameters from a parent job into a child job. However, because of Java's language semantics, the reverse (return values out of the child job) needs extra code.
Something like 'context.MYVAR="newvalue"' works within a job, but if done in a child job, the setting isn't retained. globalMap doesn't help. Every job has its own globalMap, including child jobs.
To overcome this, use a Map which gets around the Java language limitation. You can't set a variable in a child job, but you can manipulate an Object.
Consider the following job.
The Job uses three components: 2 tJavas and a tRunJob. The first tJava creates a java.util.Map object and sets it to a context variable defined as an Object.
Set Child Job Context
In the first tMap, "Set Subjob Param", add the following Java code to the Basic setting. You'll also need to import java.util.Map and java.util.HashMap in the Advanced tab.
context.SUBJOB_CONTEXT = new HashMap<String, String>();
((Map<String, String>)context.SUBJOB_CONTEXT).put("param", "value1");
This will create a Map object that can be accessed throughout the job and its child jobs. This code block sets a single entry "param" which will be an input parameter for the child job. Note that only "param" was set here; other components and child jobs can add to this.
tRunJob
The tRunJob component is configured to "Transmit whole context". It must NOT use an independent process for this technique to work. I believe that all separate process params must be strings. (Look for a future post on this.)
The Child Job
The Child Job is defined as a single tJava. It is configured with an identical Context View as the parent. See the "Context Variable Defined as Object" screenshot.
The tJava component prints the input parameter, unpacks the context.SUBJOB_CONTEXT map, and puts its own return value on it. Remember to also import java.util.Map on the Advanced tab.
// print input param
System.out.println("param=" + ((Map<String, String>)context.SUBJOB_CONTEXT).get("param"));
// set ret val
((Map<String, String>)context.SUBJOB_CONTEXT).put("retVal", "Ok");
Using an indirect approach, you can create a context for your child jobs. This introduces a global scope for all your jobs so watch for side effects.
Off-the-shelf, Talend Open Studio's Context Variable facility supports passing parameters from a parent job into a child job. However, because of Java's language semantics, the reverse (return values out of the child job) needs extra code.
Something like 'context.MYVAR="newvalue"' works within a job, but if done in a child job, the setting isn't retained. globalMap doesn't help. Every job has its own globalMap, including child jobs.
To overcome this, use a Map which gets around the Java language limitation. You can't set a variable in a child job, but you can manipulate an Object.
Consider the following job.
Job Creating Subjob Context Used in Child Job |
Context Variable Defined as Object |
In the first tMap, "Set Subjob Param", add the following Java code to the Basic setting. You'll also need to import java.util.Map and java.util.HashMap in the Advanced tab.
context.SUBJOB_CONTEXT = new HashMap<String, String>();
((Map<String, String>)context.SUBJOB_CONTEXT).put("param", "value1");
This will create a Map object that can be accessed throughout the job and its child jobs. This code block sets a single entry "param" which will be an input parameter for the child job. Note that only "param" was set here; other components and child jobs can add to this.
tRunJob
The tRunJob component is configured to "Transmit whole context". It must NOT use an independent process for this technique to work. I believe that all separate process params must be strings. (Look for a future post on this.)
tRunJob Config |
The Child Job
The Child Job is defined as a single tJava. It is configured with an identical Context View as the parent. See the "Context Variable Defined as Object" screenshot.
Child Job |
The tJava component prints the input parameter, unpacks the context.SUBJOB_CONTEXT map, and puts its own return value on it. Remember to also import java.util.Map on the Advanced tab.
// print input param
System.out.println("param=" + ((Map<String, String>)context.SUBJOB_CONTEXT).get("param"));
// set ret val
((Map<String, String>)context.SUBJOB_CONTEXT).put("retVal", "Ok");
Using an indirect approach, you can create a context for your child jobs. This introduces a global scope for all your jobs so watch for side effects.
Comments
Post a Comment