Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Qlik Open Lakehouse is Now Generally Available! Discover the key highlights and partner resources here.
cancel
Showing results for 
Search instead for 
Did you mean: 
Anonymous
Not applicable

[resolved] Passing custom object through parent and children jobs

Hi community! 
In my work we have a process platform (postgresql+php) where all process are registrered with id, name, frecuency, dependencies, log, live execution status, etc. 

Now we are migrating every process to TOS, so I'm trying to figure out how to "initiate" a Talend Job with the parameters of our process platform.

We build a routine with our common functions (set parameters, verify if it's time to run, etc.), so we have an object with all that we need.

Now, the problem is that we use "Prejob" component with "tRunJob" to call a childJob for initiate our object... the childJob use tBufferOutput to pass the object to the parent, but it doesn't work. The parent Job don't recieve the object correctly.


If I print (on the parent Job) "objProc.getClass().getName()" I get "java.lang.String"
If I do the same in the childJob, I get "routines.Procesos" (that's correct).


Any clue?

Labels (2)
1 Solution

Accepted Solutions
Anonymous
Not applicable
Author

Thanks Richand.
We finally solved, and it was easier than we thought:
1)Parent Job: tJava, Make an instance of our custom object

Integer idProc = 10000;
String val = "";

context.objProc = new routines.Procesos(idProc, val);

2) Parent Job: tRunJob with "Transmit whole context"
3) Child Job: use "set" to change a field of our instance (tBufferOutput is not necessary):
context.objProc.getClass().getFields()[0].set(context.objProc, 20000); //Field[0] is idProc

4) Back on Parent Job: the field seted is changed 

Hope this can help other people 0683p000009MA9p.png

View solution in original post

7 Replies
Anonymous
Not applicable
Author

Hi Jorge
Please send snapshots of your job.    I would like to look at the components : tRunJob, Schema tRunJob
Best regards,

Alfonso Borré
skype: alfonso.borre
Anonymous
Not applicable
Author

Is the childjob outputting the object as an Object or a String? By that I mean how is the column class configured?

I believe (if I understand your problem correctly) you need to output your object as an instance of the Object class (in your tBufferOutput component). Then, in the parent job, you will need to cast it to the correct class (routines.Procesos). If you output your childjob to a tJavaFlex you can cast to the correct class there. An example is below (assuming the row from the childjob is called "out1")...

routines.Procesos proc = (routines.Procesos)out1.object; 
Anonymous
Not applicable
Author

Thanks guys for response.
You understand the problem correctly. I need to output (from the childJob) as an instance. I always use 'Object' as a datatype.
Here are more info:
childJob -> tJava:
context.objProceso = new routines.Procesos(idProceso, valorClave);
row1.objProceso = context.objProceso;
System.out.println("sJob: " + context.objProceso);


parentJob -> tJavaRow:
System.out.println("++++->" + input_row.objProceso.getClass().getFields()[0].getName());
System.out.println("++++->" + input_row.objProceso.getClass().getFields()[0].get(input_row.objProceso));


routines.Procesos proc = (Procesos)input_row.objProceso;
System.out.println("----> " + proc.idProceso);


Console output:
Starting job testJob at 09:07 29/09/2016.
[statistics] connecting to socket on port 3905
[statistics] connected
sJob: routines.Procesos@6f539caf
Exception in component tJavaRow_1
++++->CASE_INSENSITIVE_ORDER
++++->java.lang.String$CaseInsensitiveComparator@4783da3f
java.lang.ClassCastException: java.lang.String cannot be cast to routines.Procesos
at capa_adquisicion_ps.testjob_0_1.testJob.tRunJob_1Process(testJob.java:603)
at capa_adquisicion_ps.testjob_0_1.testJob.runJobInTOS(testJob.java:901)
at capa_adquisicion_ps.testjob_0_1.testJob.main(testJob.java:739)
[statistics] disconnected
Job testJob ended at 09:07 29/09/2016. [exit code=1]


Here are screenshot of a demo Jobs:



0683p000009MFni.png 0683p000009MFnn.png
Anonymous
Not applicable
Author

Ah I remember what I did with this issue (.....does it still exist Talend?!?). You need to use a static ConcurrentHashMap to solve this. Add one to your routine and ensure that all values are stored in the ConcurrentHashMap. Then you do not need to worry about passing the values back to the parent. As they are changed/added/removed by the child, they will be available to the parent.
Anonymous
Not applicable
Author

Thank you Richard,
I think the main problem is because tBufferOutput cannot return my Object (the instance). If I return a String or Integer it works OK, but no with Object datatype. Maybe is because tBufferOutput can only return a value... So, what about the Object datatype?, can be a Talend bug?.
But I don't really understand the solution (I'm a basic Java user :-/).. our routine is something like this:
public class Procesos {
public Integer idProceso;
public String valorClave;
public Integer statusGlobal;
...
}

public Procesos(int idProceso, String valorClave) {
this.idProceso = idProceso;
this.valorClave = valorClave;

this.creaProceso();
}
public void creaProceso(){
....
}
Anonymous
Not applicable
Author

It really depends on how this will be used. Basically a static variable will hold the same values for all instantiations of the class. So if you have a static String variable called "myVal". No matter how many objects based on that class you create, they will all hold the same value for that variable. 

Take a look here https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html for information about the ConcurrentHashMap. 

This site may also help you out.....
http://www.talendbyexample.com/talend-returning-values-from-subjobs.html
Anonymous
Not applicable
Author

Thanks Richand.
We finally solved, and it was easier than we thought:
1)Parent Job: tJava, Make an instance of our custom object

Integer idProc = 10000;
String val = "";

context.objProc = new routines.Procesos(idProc, val);

2) Parent Job: tRunJob with "Transmit whole context"
3) Child Job: use "set" to change a field of our instance (tBufferOutput is not necessary):
context.objProc.getClass().getFields()[0].set(context.objProc, 20000); //Field[0] is idProc

4) Back on Parent Job: the field seted is changed 

Hope this can help other people 0683p000009MA9p.png