Addition operation in Nashorn javascript engine -java8 - nashorn

I have 2 variables to add using engine.eval()- nashorn javascript engine in java8.?
I've used code like this:
ScriptEngineManager sem=new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("nashorn");
Integer sum = 20;
Integer var2=30;
try {
sum=(Integer)engine.eval("sum+var2");
} catch(Exception e) {
System.out.println("Error executing script: "+ e.getMessage());
}
The eval function takes only string parameter. So it shows error.how to perform this operation?

Nashorn ScriptEngine is a separate runtime. It doesn't have knowledge of data outside it's scope unless explicitly specified.
Here sum and var2 are outside the scope of Nashorn. You can pass this data to Nashorn via multiple methods. One of them is using bindings.
Sample code :
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("nashorn");
Integer sum = 20;
Integer var2 = 30;
try {
Bindings bindings = engine.createBindings();
bindings.put("sum", 20);
bindings.put("var2", 30);
double result = (double) engine.eval("sum+var2", bindings);
System.out.println(result);
} catch (Exception e) {
System.out.println("Error executing script: " + e.getMessage());
}
The type conversion from integer to double is a nuance explained here.
But this kind of script evaluation is rather limiting. You can use Invocable api to invoke javascript functions. This tutorial is a good starting point.

Related

how to check which constraints would be violated by a presumed solution?

In some cases the solver fails to find a solution for my model, which I think is there.
So I would like to populate a solution, and then check which constraint is violated.
How to do that with choco-solver?
Using choco-solver 4.10.6.
Forcing a solution
I ended up adding constraints to force variables to values of my presumed solution:
e.g.
// constraints to force given solution
vehicle2FirstStop[0].eq(model.intVar(4)).post();
vehicle2FirstStop[1].eq(model.intVar(3)).post();
nextStop[1].eq(model.intVar(0)).post();
nextStop[2].eq(model.intVar(1)).post();
...
and then
model.getSolver().showContradiction();
if (model.getSolver().solve()) { ....
Shows the first contradiction of the presumed solution, e.g.
/!\ CONTRADICTION (PropXplusYeqZ(sum_exp_49, mul_exp_51, ...
So the next step is to find out where terms such as sum_exp_49 come from.
Matching the contradiction terms with the code
Here is a simple fix for constraints which will hopefully provide enough information. We can override the post() and associates() methods of model, so that it dumps the java source filename and line number when a constraint is posted/variable is created.
Model model = new Model("Vrp1RpV") {
/**
* retrieve the filename and line number of first caller outside of choco-solver from stacktrace
*/
String getSource() {
String source = null;
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
// starts from 3: thread.getStackTrace() + this.getSource() + caller (post() or associates())
for (int i = 3; i < stackTraceElements.length; i++) {
// keep rewinding until we get out of choco-solver packages
if (!stackTraceElements[i].getClassName().toString().startsWith("org.chocosolver")) {
source = stackTraceElements[i].getFileName() + ":" + stackTraceElements[i].getLineNumber();
break;
}
}
return source;
}
#Override
public void post(Constraint... cs) throws SolverException {
String source=getSource();
// dump each constraint along source location
for (Constraint c : cs) {
System.err.println(source + " post: " + c);
}
super.post(cs);
}
#Override
public void associates(Variable variable) {
System.err.println(getSource() + " associates: " + variable.getName());
super.associates(variable);
}
};
This will dump things like:
Vrp1RpV2.java:182 post: ARITHM ([prop(EQ_exp_47.EQ.mul_exp_48)])
Vrp1RpV2.java:182 associates: sum_exp_49
Vrp1RpV2.java:182 post: ARITHM ([prop(mul_exp_48.EQ.sum_exp_49)])
Vrp1RpV2.java:182 associates: EQ_exp_50
Vrp1RpV2.java:182 post: BASIC_REIF ([(stop2vehicle[2] = 1) <=> EQ_exp_50])
...
From there it is possible to see where sum_exp_49 comes from.
EDIT: added associates() thanks to #cprudhom suggestion on https://gitter.im/chocoteam/choco-solver

Is it possable to call a method that takes this.Handle as an argument inside a background worker in C#

I am working on a stand-alone WinForm program in C# that uses the Solidworks EPDM api. The program takes a top level assembly and finds all the referenced and referencing files in the assembly. e.g. all sub-assemblies, part files, and drawings. The program then checks out all the files from EPDM, updates the data cards, and checks in all the files back to the EPDM.
I have successfully implemented the portion of the code that finds all the referenced and referencing files and updates the data card information using a background worker. This portion of the code does not require access the the UI thread. I would like to be able to add the code that checks out the files and checks them back in within a background worker. The problem is that the methods used to do the checkout and check-in take this.Handle as an argument. I know that accessing the UI thread from within a background worker will throw a cross thread exception. The code does not access any of the UI controls. It only need access to this.Handle. Is it possible to pass this.Handle to a background worker in a thread safe way that will not throw a cross thread exception?
This is my first use of background workers so my knowledge is limited. Below is the code that I would like to run in a background worker.
private void BatchCheckout(Dictionary<string, string> SelectedFiles)
{
try
{
IEdmBatchGet batchGetter = (IEdmBatchGet)vault.CreateUtility(EdmUtility.EdmUtil_BatchGet);
EdmSelItem[] ppoSelection = new EdmSelItem[SelectedFiles.Count];
IEdmFile5 aFile;
IEdmFolder5 aFolder;
IEdmFolder5 ppoRetParentFolder;
IEdmPos5 aPos;
int i = 0;
foreach (KeyValuePair<string, string> kvp in SelectedFiles)
{
aFile = vault1.GetFileFromPath(kvp.Key, out ppoRetParentFolder);
aPos = aFile.GetFirstFolderPosition();
aFolder = aFile.GetNextFolder(aPos);
ppoSelection[i] = new EdmSelItem();
ppoSelection[i].mlDocID = aFile.ID;
ppoSelection[i].mlProjID = aFolder.ID;
i = i + 1;
}
batchGetter.AddSelection((EdmVault5)vault1, ref ppoSelection);
batchGetter.CreateTree(this.Handle.ToInt32(), (int)EdmGetCmdFlags.Egcf_Lock);
batchGetter.GetFiles(this.Handle.ToInt32(), null);
}
catch (System.Runtime.InteropServices.COMException ex)
{
MessageBox.Show("HRESULT = 0x" + ex.ErrorCode.ToString("X") + " " + ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\n" + GetStackTrace(ex));
}
}
I have been a reader of StackOverflow for many years and have found answers to just about every question I have ever had. This is my first ever question on StackOverflow. I am really hoping that someone will have an answer to this problem.
EDIT:
I have successfully test AndrewK's suggestion and am happy to report that it did work for my batch checkout method. When I run my batch check-in method in a background worker I'm getting the following COM exception:
Unable to cast COM object of type 'System.__ComObject' to interface type 'EPDM.Interop.epdm.IEdmBatchUnlock2'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{F0970446-4CBB-4F0F-BAF5-F9CD2E09A5B3}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
I only get this exception if I run the code from a background worker.
Here is the code from my BatchCheckin method:
private void BatchCheckin(Dictionary<string, string> SelectedFiles)
{
try
{
int i = 0;
IEdmFolder5 ppoRetParentFolder;
IEdmFile5 aFile;
IEdmFolder5 aFolder;
IEdmPos5 aPos;
EdmSelItem[] ppoSelection = new EdmSelItem[SelectedFiles.Count];
IEdmBatchUnlock2 batchUnlock;
foreach (KeyValuePair<string, string> kvp in SelectedFiles)
{
aFile = vault5.GetFileFromPath(kvp.Key, out ppoRetParentFolder);
aPos = aFile.GetFirstFolderPosition();
aFolder = aFile.GetNextFolder(aPos);
ppoSelection[i] = new EdmSelItem();
ppoSelection[i].mlDocID = aFile.ID;
ppoSelection[i].mlProjID = aFolder.ID;
i = i + 1;
}
batchUnlock = (IEdmBatchUnlock2)vault7.CreateUtility(EdmUtility.EdmUtil_BatchUnlock);
batchUnlock.AddSelection((EdmVault5)vault5, ref ppoSelection);
batchUnlock.CreateTree(0, (int)EdmUnlockBuildTreeFlags.Eubtf_ShowCloseAfterCheckinOption + (int)EdmUnlockBuildTreeFlags.Eubtf_MayUnlock);
batchUnlock.Comment = "Updates";
batchUnlock.UnlockFiles(0, null);
}
catch (System.Runtime.InteropServices.COMException ex)
{
MessageBox.Show("HRESULT = 0x" + ex.ErrorCode.ToString("X") + " " + ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\n" + GetStackTrace(ex));
}
}
I am getting the exception when I make the call to vault7.CreateUtility. The BatchCheckin code is nearly identical to the BatchCheckout. I'm making the same call to vault7.CreateUtility in both methods. The only difference is the EdmUtility flag is set to EdmUtil_BatchUnlock in the BatchCheckin method. Any clue on this one AndrewK?
UPDATE:
I was able to resolve the COM exception by changing batchUpdate from the IEdmBatchUnlock2 interface to the IEdmBatchUnlock interface. Here is the code change:
private void BatchCheckin(Dictionary<string, string> SelectedFiles)
{
int i = 0;
IEdmFolder5 ppoRetParentFolder;
IEdmFile5 aFile;
IEdmFolder5 aFolder;
IEdmPos5 aPos;
EdmSelItem[] ppoSelection = new EdmSelItem[SelectedFiles.Count];
IEdmBatchUnlock batchUnlock = (IEdmBatchUnlock)vault7.CreateUtility(EdmUtility.EdmUtil_BatchUnlock);
try
{
foreach (KeyValuePair<string, string> kvp in SelectedFiles)
{
aFile = vault5.GetFileFromPath(kvp.Key, out ppoRetParentFolder);
aPos = aFile.GetFirstFolderPosition();
aFolder = aFile.GetNextFolder(aPos);
ppoSelection[i] = new EdmSelItem();
ppoSelection[i].mlDocID = aFile.ID;
ppoSelection[i].mlProjID = aFolder.ID;
i = i + 1;
}
batchUnlock.AddSelection((EdmVault5)vault5, ref ppoSelection);
batchUnlock.CreateTree(0, (int)EdmUnlockBuildTreeFlags.Eubtf_ShowCloseAfterCheckinOption + (int)EdmUnlockBuildTreeFlags.Eubtf_MayUnlock);
batchUnlock.Comment = "Release to Production ECO";
batchUnlock.UnlockFiles(0, null);
}
catch (System.Runtime.InteropServices.COMException ex)
{
MessageBox.Show("HRESULT = 0x" + ex.ErrorCode.ToString("X") + " " + ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\n" + GetStackTrace(ex));
}
}
I am guessing that this is a bug in the IEdmBatchUnlock2 interface. The IEdmBatchUnlock2 will cause a COM exception if called from a background worker but will not cause a COM exception if called from the UI thread. The IEdmBatchUnlock interface will not cause a COM exception when called from a background worker.
Just put a 0 in there for the handle. As long as your code will not require user input, it will work. I do it often.
batchGetter.AddSelection((EdmVault5)vault1, ref ppoSelection);
batchGetter.CreateTree(0, (int)EdmGetCmdFlags.Egcf_Lock);
batchGetter.GetFiles(0, null);

get result from multithread for the same method

I would like to parallelize my program to be fast, so my program is like that:
Sim1 sim1 = new Sim1();
for(Entry<Integer, HashSet<String>> entry : map_topics_words.entrySet()) {
Integer k = entry.getKey();
Double sim = sim1.prob(word_m, entry.getValue());
sim_avg.put(k, sim);
score += sim;
}
and prob in the method in class Sim1 like that
public double prob(String w_i, HashSet<String> set_i){
Similarity sim = new Similarity();
double score = 1;
Iterator<String> it = set_i.iterator();
while (it.hasNext()) {
score += sim.computeSim(w_i, it.next());
}
score = score/set_i.size();
return score;
}
and computeSim in the method in classe Similarity like that :
public double computeSim(String w_1, String w_2){
return cmp(w_1,w_2);
}
So I would like to use thread for the first method and thread for the second method, I tried different ways but I failed
Any help, please
Thank you
You can change the first method code as below. We can try this by using Executor framework by submitting the work of prob() method as Callable task so that It can be executed in different thread, and then by using Future we can get the result for that particular call, for this we need to maintain one more map of key and corresponding Future object, Please see below code to understand it better, hope it may help you.
Sim1 sim1 = new Sim1();
Map<Integer, Future<Double>> workerMap = new HashMap<>();
ExecutorService exe = Executors.newCachedThreadPool();
for(Map.Entry<Integer, HashSet<String>> entry : map_topics_words.entrySet()) {
Integer k = entry.getKey();
workerMap.put(k, exe.submit(()->{ //Java 8 lamda
return sim1.prob(word_m, entry.getValue());
}));
}
//This loop is to get the result of prob() method for all the keys and process them further
for(Map.Entry<Integer, HashSet<String>> entry : map_topics_words.entrySet()) {
Integer k = entry.getKey();
try {
Double sim = workerMap.get(k).get();
sim_avg.put(k, sim);
score += sim;
} catch (Exception e) {
e.printStackTrace();
}
}
I will suggest you to google the working of Callable and Future in java, You can see this link also.

How to continue data driven coded UI test even after fail

I am doing data driven coded UI test. I have given 10 sets of data. It is failing at 5th data set and is stopping. I need Coded UI tests to continue data driven even after failure.
Please suggest me some way to do this.
in your test please use this
Playback.PlaybackSettings.ContinueOnError = true;
Put each set of data in a try-catch block. Catch the error and ignore it or handle it manually, then continue. I assume you pass your data to the UIMap. If so, then something like this:
[TestMethod]
public void Test_Transaction_ID_67890_Test()
{
for (int i = 0; i < testCaseList.Count; i++)
{
try
{
this.UIMap.ClickonManage(testCaseList);
this.UIMap.ClickonAdd(testCaseList);
this.UIMap.SelectAssigned(testCaseList);
this.UIMap.SelectTransactionDateTime(testCaseList);
}
catch (Exception e)
{
TestContext.WriteLine(Got An Error On Iteration " + i.ToString() + ".";
TestContext.WriteLine(e.ToString());
}
}

how to convert object into string?

I have this problem converting object into string... I make use of the toString() function... and since the conversion of object into string were inside the try{}catch(exception e){}, i keep on receiving an output error: For input string: ""
What should be the problem if i keep on receiving an error message like that?
More elaboration:
the Object came from a jComboBox
which consists of items from a
database.
I am using a JFrame Form instead of
a Java Class.
All i want to do is to capture the selected Item from the JComboBox which happens to be an object. And then after capturing it. I'll use the value for my query in the database.
Here's my code(partial):
private void SUBMITActionPerformed(java.awt.event.ActionEvent evt) {
try {
Class.forName(Connect.DRIVER);
Connection con = DriverManager.getConnection(Connect.CONNECTION_STRING,
Connect.USERNAME, Connect.PASSWORD);
Object obj = jComboBox1.getSelectedItem();
String item_name = obj.toString();
int month = jMonthChooser.getMonth();
int q_box = Integer.parseInt(quantity_box_txtbox.getText());
double unit_price_box = 0;
int q_pc = Integer.parseInt(quantity_pc_txtbox.getText());
double unit_price_pc = 0;
double sub_total_box = 0;
double sub_total_pc = 0;
double grand_total = 0;
//Testing
System.out.println(jMonthChooser.getMonth());
System.out.println(item_name);
} catch (Exception e) {
System.out.println("Error: "+e.getMessage());
}
}
If you have anything you don't understand regarding with the way I explain my question please tell me... i'll try my best to elaborate further.
Thanks in advance.
:)
here's the complete error:
Error: java.lang.NumberFormatException : For input string: ""
Well, to start with:
Don't catch just Exception; catch specific subclasses
Don't just catch the exception; you almost certainly want to propagate it up to the caller
Don't log just the message - log the whole exception, including the stack trace and exception type.
The exception looks like it's trying to parse a string - not trying to convert an object to a string. I strongly suspect that the problem is one of these lines:
int q_box = Integer.parseInt(quantity_box_txtbox.getText());
int q_pc = Integer.parseInt(quantity_pc_txtbox.getText());
My guess is that one of the textboxes is empty - so you're effectively calling Integer.parseInt("") which is failing.

Resources