[resolved] The correct way to assign the value of context variables in Java

One Star

[resolved] The correct way to assign the value of context variables in Java

Hi there,
I can't see anywhere in the documentation here in any of the 4.4.x pages where it covers setting context variables from java code.
https://help.talend.com/search/all?query=Using+contexts+and+variables&content-lang=en
I have read it on this forum being said that setting context variables using tJava/tJavaRow using the following syntax is only temporary:
context.TestVar = "Test Value";


"The location context.<var_name> is not permanent and it just holds the value for you to access it easily."
And that you should instead use the following syntax to assign values to context variables from java:
context.setProperty("TestVar ", "Test Value");


I have also read other posts like this one:
https://www.talendforge.org/forum/viewtopic.php?id=10965
Saying:
"...context values are stored in more than one place and tContextDump picks up only those values defined when the job begins so if you set context values dynamically using tJava you need to follow with the following statement so that tContextDump will use the new values:"
context.synchronizeContext();


I can't see this topic discussed anywhere in the Talend documentation.
context.setProperty is a pain to use because it only accepts strings.  So if you want to assigned values to context variables of any other type from tJava or tJavaRow you need to convert them.  Especially painful for dates.
So can we please get an official word from Talend on this?  (or anyone that can point out some documentation that gives a clear answer to the following questions)
QUESTION 1:
Has there been some confusion here in the developer community due to the undocumented need to call context.synchronizeContext() to get updated context variable values to show in tContextDump that has made people thing that the use of context.setProperty is needed for the assignment of context variables and that values set in java are not permanent?

Excluding the obvious nature of tJavaRow (eg; variables assigned in tJavaRow get overwritten for every iteration), is there an issue with just using:
context.TestDateVar = TalendDate.getCurrentDate();

to assign a variable?

QUESTION 2:
Is there a difference between using:
context.TestVar = "Test Value";

and
context.setProperty("TestVar ", "Test Value");

in regard to the scope and permanency of the value assigned?

QUESTION 3:
If you are not using tContextDump but only using updated context variable values in other components, do you need to use context.synchronizeContext(); to ensure these values will be available, or is this only needed for tContextDump?
-------------------------------------------------
For what it's worth, the Talend Open Studio Cookbook has a page on: "Setting the context and globalMap variables
using tJava".  In their examples they set the value of context variables using the following:
context.testValue ="testValue is now initialized";

And make no mention of an issue with scope or permanency of the value assigned.
https://www.packtpub.com/big-data-and-business-intelligence/talend-open-studio-cookbook
Thank you for your time,
Scott

Accepted Solutions
Community Manager

Re: [resolved] The correct way to assign the value of context variables in Java

Hi 
Question1 & Question2: We only use the following format to assign a new value to context variable. 
context.varName=value
You can assign a new value to context variable for every row or iteration, the variable always has the new value as long as you assign a new value.
Question3: context.synchronizeContext() is only needed for tContextDump.
Best regards
Shong
----------------------------------------------------------
Talend | Data Agility for Modern Business

All Replies
Community Manager

Re: [resolved] The correct way to assign the value of context variables in Java

Hi 
Question1 & Question2: We only use the following format to assign a new value to context variable. 
context.varName=value
You can assign a new value to context variable for every row or iteration, the variable always has the new value as long as you assign a new value.
Question3: context.synchronizeContext() is only needed for tContextDump.
Best regards
Shong
----------------------------------------------------------
Talend | Data Agility for Modern Business
One Star

Re: [resolved] The correct way to assign the value of context variables in Java

Shong,
Brilliant mate.  Thanks heaps for clearing that up.  I think I will change the subject of this post to make it easier for others to find.
Great work mate!
Thanks for your time,
Scott
Sixteen Stars

Re: [resolved] The correct way to assign the value of context variables in Java

Has there been a change since v5.5? There are occasions when using ....
context.myVar  = value;
....does not work very well at all. I have found situations where the above format resulted in returning null when calling the context variable in a subsequent tJava (linked by a RunIf), but when I used this method....
context.setProperty("myVar", value);
....it worked.
If a fix has been put in for this, great. If not, it should not be hidden as it can cause hours of debugging issues.
One Star

Re: [resolved] The correct way to assign the value of context variables in Java

rhall,
Thanks for your feedback mate.  Are you able to provide details for steps to replicate the issue?
It may have been a timing issue, depending on the way the components were connected, although strange that setProperty would work in that case....
Regards,
Scott
One Star

Re: [resolved] The correct way to assign the value of context variables in Java

rhall,
I just did a search of the Talend Bugtracker for the phrase "context variable" and found the following issue:
https://jira.talendforge.org/browse/TDI-14419
Have a look and see if it was like your scenario mate.
The Talend response was:
"This is a job design problem. We upload an example to help you to achieve your need."
Regards,
Scott
Sixteen Stars

Re: [resolved] The correct way to assign the value of context variables in Java

I don't believe it was a timing issue since a simple change from one method to the other fixed it. To be honest, I would have to work at an example that shows it (and I don't really have a great deal of time at the moment), but *believe* one of the times I have experienced it was when writing this tutorial. The tutorial is not really related to this problem. I now make sure that I use the setProperty method to be on the safe side. This problem can also be experienced when using ESB.
One Star

Re: [resolved] The correct way to assign the value of context variables in Java

rhall,
Thanks again for your feedback mate.  
Ok so let's put it out there.  
Can anyone give us replication steps to demonstrate a scenario where using the direct assignment a context variable does not work, and using setProperty does?
Direct Assignment:
context.myVar  = "value";

Set Property:
context.setProperty("myVar", "value");

Let's work it out once and for all ;-)
Regards,
Scott
Sixteen Stars

Re: [resolved] The correct way to assign the value of context variables in Java

I use the tContextLoad and tContextDump components in the tutorial. I suspect it may be to do with the synchronize code used with those since I can't recall having the problem without making use of those components. Anyway, it is something to be aware of.
One Star

Re: [resolved] The correct way to assign the value of context variables in Java

rhall,
Ok thanks for that mate.  Yes once I read that:
context.synchronizeContext();

was required for tContextDump to show current values I suspected that this, due to the fact it is not documented anywhere, could be the cause of people having this perception that setProperty was required, as they would have, like I did, used tDumpContext to check what the values were at a certain point.  That is why I started this thread ;-)
Regards,
Scott
Sixteen Stars

Re: [resolved] The correct way to assign the value of context variables in Java

OK, I have recreated the issue and demonstrated it in the attached Job. You will need Talend v6.0 or higher to test this. I am using the ESB version, but it shouldn't stop you from loading this DI Job. A link to the file is here.
Basically I have some context variables set inside the Job (Check the contexts tab to see the values). The first thing I do is change the values. Two of them using the "context.new1 = " method and one using the "context.setProperty(" method. I then dump them to a parameter file. If you check the parameter file you will see that only the context variable that has been set using the "context.setProperty(" method has been changed in time to be sent to the file.
One Star

Re: [resolved] The correct way to assign the value of context variables in Java

rhall,
Thanks for putting in the effort to do this mate.  Unfortunately I am running Jaspersoft ETL Express (Talend 5.6).
Can you post a screen shot of the job and maybe I can recreate it.
Regards,
Scott
Sixteen Stars

Re: [resolved] The correct way to assign the value of context variables in Java

This will look a little different to what you have (UI update), but you should be able to extrapolate....
Context Tab

Code in tJava

Layout

Edit: Oops, the images didn't upload properly first time. 
I have created a Jira for this: https://jira.talendforge.org/browse/TDI-34112
One Star

Re: [resolved] The correct way to assign the value of context variables in Java

rhall,
Ok great I see what you mean now mate.  So to make this work you just need to put:
context.synchronizeContext();

after you set the variables in the tJava, and you should then get all the updated values.
So it may not be a bug, just poor documentation...
Regards,
Scott
Sixteen Stars

Re: [resolved] The correct way to assign the value of context variables in Java

The overhead of using synchronizeContext() every time you change a context variable if you have many variables (some of my jobs have almost 50), will be quite high. Particularly if you make a change for every row and you are processing millions of rows. Since synchronizeContext actually performs a "context.setProperty(" on all context variables that are not null, it arguably makes sense to use the setProperty method. 
Since you are not supposed to have to be a Java expert in order to use Talend, I believe that this is a bug. Thanks for bringing this up. I just coded around it without thinking about it in the past.
One Star

Re: [resolved] The correct way to assign the value of context variables in Java

rhall,
Yes  mate you make some really good points there and I am inclined to agree with you.
Let's hope the team get onto this one and get it sorted for us.
Thanks again for your effort in this discussion mate  ;-)
Regards,
Scott

Re: [resolved] The correct way to assign the value of context variables in Java

I have another doubt.. How to apply "ALL in One" property in tWriteJSONField.. I know about tXMLMap but I want to perform this property with tWriteJSONField.. so please explain with example. I am beginner in Talend
Community Manager

Re: [resolved] The correct way to assign the value of context variables in Java

Hi amolkhandekar92
Before tWriteJSONField,add a new column and set a fixed value such as 1 to it, this column will be group element on tWriteJSONField.

Shong
----------------------------------------------------------
Talend | Data Agility for Modern Business
Five Stars

Re: [resolved] The correct way to assign the value of context variables in Java

My findings

 

context.setProperty("mailFileName", "rejected.xlsx");
context.filePath="talend_files_0.1/out/";

 

//access variable set using setProperty method with getProperty
System.out.println("method1="+context.getProperty("mailFileName"));
System.out.println("method2="+context.filePath);
System.out.println("method3="+context.getProperty("filePath"));
System.out.println("method4="+context.mailFileName);

 

 

// after synchronization it outputs right values set without setPropperty and accessed with getProperty. But it //wipes out value set with setProperty after synchronization.
context.synchronizeContext();


System.out.println("method5="+context.getProperty("mailFileName"));
System.out.println("method6="+context.filePath);
System.out.println("method7="+context.getProperty("filePath"));

 

 

output

------

method1=rejected.xlsx
method2=talend_files_0.1/out/
method3=
method4=
method5=
method6=talend_files_0.1/out/
method7=talend_files_0.1/out/
method8=

 

 

From above scenario i understand that Synchronization sets the values of variables to the latest change made using methos

context.<variable> = value

Four Stars

Re: [resolved] The correct way to assign the value of context variables in Java

How do I include the value of contexts in tjavarow?

For Example:

This is my job tFileInputDelimited==Main==>tjavarow==main==>tFileOutputJSON

I'm trying to convert a normal text file into a JSON file, this is my text input:

Document,Files (Header)
doc_1, 2 (values)

And my output should be like this:

[{"Document":"doc_1 20180914","Files":1}]

So, My issue is when I try to include the date value through context it projects me a null value like this:

[{"Document":"doc_1 null","Files":1}]

This is the code I'm following in tjavarow to implement it:

output_row.Document = input_row.Document+" "+context.date;
output_row.Files = Integer.parseInt(input_row.Files);

Can Anyone help me with this?