Can you help me out if the following code will work in a multi-threaded application.
Here is my Java Script that will be evaluated by Nashorn
var Thread = Java.type("java.lang.Thread");
var referenceNumberValid = "0000";
var referenceNumberInvalid = "0001";
function validate (parameters) {
var isValid = false;
var statusCode;
var referenceNumber = parameters.referenceNumber;
var validateNumber = referenceNumber.substr(0, 7);
var sum = 0;
for (ctr = 0; ctr < validateNumber.length; ctr++) {
sum += parseInt(validateNumber.substr(ctr, 1));
}
var checkDigit = sum % 10;
isValid = parseInt(referenceNumber.substr(7, 1)) == checkDigit;
statusCode = isValid ? referenceNumberValid : referenceNumberInvalid;
print("Thread: " + Thread.currentThread().getId() + ", isValid: " + isValid + ", referenceNumber: " + referenceNumber + ", validateNumber: " + validateNumber + ", sum: " + sum + ", checkDigit: " + checkDigit + ", statusCode" + statusCode);
return statusCode;
}
This is how I create my script engine
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(myScript);
While Testing using Testng this works without any errors
@Test(dataProvider = "validReferenceNumbers", timeOut = 3000)
public final void testValidReferenceNumber(String referenceNumber) throws NoSuchMethodException, ScriptException {
Map<String, String> parameters = new HashMap<>();
parameters.put("referenceNumber", referenceNumber);
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("validate", parameters);
Assert.assertEquals(statusCode, "000");
}
@DataProvider(name = "validReferenceNumbers")
private Iterator<Object[]> validReferenceNumbers() throws FileNotFoundException {
Iterator<Object[]> testData = null;
// please assume that will be initilized correctly
return testData;
}
Test Results1 - note that some data are repeated
Thread: 10, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 11, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 12, isValid: true, referenceNumber: 17028884, validateNumber: 1702888, sum: 34, checkDigit: 4, statusCode0000
Thread: 13, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 14, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 15, isValid: true, referenceNumber: 17098881, validateNumber: 1709888, sum: 41, checkDigit: 1, statusCode0000
Thread: 16, isValid: true, referenceNumber: 17098881, validateNumber: 1709888, sum: 41, checkDigit: 1, statusCode0000
Thread: 17, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 18, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 19, isValid: true, referenceNumber: 17058887, validateNumber: 1705888, sum: 37, checkDigit: 7, statusCode0000
Thread: 20, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 21, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 22, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 23, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 24, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 25, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 26, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 27, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 28, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 29, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 30, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 31, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 32, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 33, isValid: true, referenceNumber: 17058887, validateNumber: 1705888, sum: 37, checkDigit: 7, statusCode0000
Thread: 34, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 35, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 36, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 37, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 38, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 39, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 40, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 41, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 42, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 43, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 44, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 45, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 46, isValid: true, referenceNumber: 07034880, validateNumber: 0703488, sum: 30, checkDigit: 0, statusCode0000
Thread: 47, isValid: true, referenceNumber: 07034880, validateNumber: 0703488, sum: 30, checkDigit: 0, statusCode0000
Thread: 48, isValid: true, referenceNumber: 07009882, validateNumber: 0700988, sum: 32, checkDigit: 2, statusCode0000
But if I add "parallel=true" to the @DataProvider my scripts starts to fail
@Test(dataProvider = "validReferenceNumbers", timeOut = 3000)
public final void testValidReferenceNumber(String referenceNumber) throws NoSuchMethodException, ScriptException {
Map<String, String> parameters = new HashMap<>();
parameters.put("referenceNumber", referenceNumber);
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("validate", parameters);
Assert.assertEquals(statusCode, "000");
}
@DataProvider(name = "validReferenceNumbers", parallel=true)
private Iterator<Object[]> validReferenceNumbers() throws FileNotFoundException {
Iterator<Object[]> testData = null;
// please assume that will be initilized correctly
return testData;
}
Test Results2 - note that some data are repeated to show that the same reference number could fail randomly during the test
Thread: 29, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 22, isValid: false, referenceNumber: 18058888, validateNumber: 1805888, sum: 1, checkDigit: 1, statusCode0001
Thread: 25, isValid: false, referenceNumber: 18058888, validateNumber: 1805888, sum: 1, checkDigit: 1, statusCode0001
Thread: 21, isValid: true, referenceNumber: 17098881, validateNumber: 1709888, sum: 41, checkDigit: 1, statusCode0000
Thread: 27, isValid: false, referenceNumber: 18028885, validateNumber: 1802888, sum: 1, checkDigit: 1, statusCode0001
Thread: 20, isValid: true, referenceNumber: 17098881, validateNumber: 1709888, sum: 41, checkDigit: 1, statusCode0000
Thread: 26, isValid: true, referenceNumber: 17058887, validateNumber: 1705888, sum: 37, checkDigit: 7, statusCode0000
Thread: 24, isValid: true, referenceNumber: 17028884, validateNumber: 1702888, sum: 34, checkDigit: 4, statusCode0000
Thread: 23, isValid: false, referenceNumber: 18028885, validateNumber: 1802888, sum: 1, checkDigit: 1, statusCode0001
Thread: 28, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 30, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 32, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 34, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 31, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 36, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 38, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 40, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 42, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 44, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 33, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 46, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 48, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 35, isValid: false, referenceNumber: 18058888, validateNumber: 1805888, sum: 30, checkDigit: 0, statusCode0001
Thread: 50, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 37, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 39, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 41, isValid: true, referenceNumber: 17058887, validateNumber: 1705888, sum: 37, checkDigit: 7, statusCode0000
Thread: 52, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 54, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 43, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 45, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 56, isValid: true, referenceNumber: 07009882, validateNumber: 0700988, sum: 32, checkDigit: 2, statusCode0000
Thread: 58, isValid: true, referenceNumber: 07034880, validateNumber: 0703488, sum: 30, checkDigit: 0, statusCode0000
Thread: 47, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 49, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 51, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 53, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 55, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 57, isValid: true, referenceNumber: 07034880, validateNumber: 0703488, sum: 30, checkDigit: 0, statusCode0000
Can anyone confirm if I can Initialize the ScriptEngine and allow it to be used in a multithreaded application. As you can see I use global script variables but those will not be modified during its execution. As our design revolves around a web service that calls this script internally.
P.S. In my understanding @DataProvider(parallel=true) is the proper way to test the multithreading, so If I am wrong please point it out.
Edit Can anyone tell me how I can modify my code/script so that I can initialize the ScriptEngine and allow it to be used in a multi-threaded application. As I do not want to parse the script files over and over again.
As I previously thought that if the script does not use global variables to keep state it would be OK, but apparently that is not enough.
Thanks
Can you help me out if the following code will work in a multi-threaded application.
Here is my Java Script that will be evaluated by Nashorn
var Thread = Java.type("java.lang.Thread");
var referenceNumberValid = "0000";
var referenceNumberInvalid = "0001";
function validate (parameters) {
var isValid = false;
var statusCode;
var referenceNumber = parameters.referenceNumber;
var validateNumber = referenceNumber.substr(0, 7);
var sum = 0;
for (ctr = 0; ctr < validateNumber.length; ctr++) {
sum += parseInt(validateNumber.substr(ctr, 1));
}
var checkDigit = sum % 10;
isValid = parseInt(referenceNumber.substr(7, 1)) == checkDigit;
statusCode = isValid ? referenceNumberValid : referenceNumberInvalid;
print("Thread: " + Thread.currentThread().getId() + ", isValid: " + isValid + ", referenceNumber: " + referenceNumber + ", validateNumber: " + validateNumber + ", sum: " + sum + ", checkDigit: " + checkDigit + ", statusCode" + statusCode);
return statusCode;
}
This is how I create my script engine
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(myScript);
While Testing using Testng this works without any errors
@Test(dataProvider = "validReferenceNumbers", timeOut = 3000)
public final void testValidReferenceNumber(String referenceNumber) throws NoSuchMethodException, ScriptException {
Map<String, String> parameters = new HashMap<>();
parameters.put("referenceNumber", referenceNumber);
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("validate", parameters);
Assert.assertEquals(statusCode, "000");
}
@DataProvider(name = "validReferenceNumbers")
private Iterator<Object[]> validReferenceNumbers() throws FileNotFoundException {
Iterator<Object[]> testData = null;
// please assume that will be initilized correctly
return testData;
}
Test Results1 - note that some data are repeated
Thread: 10, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 11, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 12, isValid: true, referenceNumber: 17028884, validateNumber: 1702888, sum: 34, checkDigit: 4, statusCode0000
Thread: 13, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 14, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 15, isValid: true, referenceNumber: 17098881, validateNumber: 1709888, sum: 41, checkDigit: 1, statusCode0000
Thread: 16, isValid: true, referenceNumber: 17098881, validateNumber: 1709888, sum: 41, checkDigit: 1, statusCode0000
Thread: 17, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 18, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 19, isValid: true, referenceNumber: 17058887, validateNumber: 1705888, sum: 37, checkDigit: 7, statusCode0000
Thread: 20, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 21, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 22, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 23, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 24, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 25, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 26, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 27, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 28, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 29, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 30, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 31, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 32, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 33, isValid: true, referenceNumber: 17058887, validateNumber: 1705888, sum: 37, checkDigit: 7, statusCode0000
Thread: 34, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 35, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 36, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 37, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 38, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 39, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 40, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 41, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 42, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 43, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 44, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 45, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 46, isValid: true, referenceNumber: 07034880, validateNumber: 0703488, sum: 30, checkDigit: 0, statusCode0000
Thread: 47, isValid: true, referenceNumber: 07034880, validateNumber: 0703488, sum: 30, checkDigit: 0, statusCode0000
Thread: 48, isValid: true, referenceNumber: 07009882, validateNumber: 0700988, sum: 32, checkDigit: 2, statusCode0000
But if I add "parallel=true" to the @DataProvider my scripts starts to fail
@Test(dataProvider = "validReferenceNumbers", timeOut = 3000)
public final void testValidReferenceNumber(String referenceNumber) throws NoSuchMethodException, ScriptException {
Map<String, String> parameters = new HashMap<>();
parameters.put("referenceNumber", referenceNumber);
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("validate", parameters);
Assert.assertEquals(statusCode, "000");
}
@DataProvider(name = "validReferenceNumbers", parallel=true)
private Iterator<Object[]> validReferenceNumbers() throws FileNotFoundException {
Iterator<Object[]> testData = null;
// please assume that will be initilized correctly
return testData;
}
Test Results2 - note that some data are repeated to show that the same reference number could fail randomly during the test
Thread: 29, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 22, isValid: false, referenceNumber: 18058888, validateNumber: 1805888, sum: 1, checkDigit: 1, statusCode0001
Thread: 25, isValid: false, referenceNumber: 18058888, validateNumber: 1805888, sum: 1, checkDigit: 1, statusCode0001
Thread: 21, isValid: true, referenceNumber: 17098881, validateNumber: 1709888, sum: 41, checkDigit: 1, statusCode0000
Thread: 27, isValid: false, referenceNumber: 18028885, validateNumber: 1802888, sum: 1, checkDigit: 1, statusCode0001
Thread: 20, isValid: true, referenceNumber: 17098881, validateNumber: 1709888, sum: 41, checkDigit: 1, statusCode0000
Thread: 26, isValid: true, referenceNumber: 17058887, validateNumber: 1705888, sum: 37, checkDigit: 7, statusCode0000
Thread: 24, isValid: true, referenceNumber: 17028884, validateNumber: 1702888, sum: 34, checkDigit: 4, statusCode0000
Thread: 23, isValid: false, referenceNumber: 18028885, validateNumber: 1802888, sum: 1, checkDigit: 1, statusCode0001
Thread: 28, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 30, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 32, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 34, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 31, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 36, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 38, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 40, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 42, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 44, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 33, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 46, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 48, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 35, isValid: false, referenceNumber: 18058888, validateNumber: 1805888, sum: 30, checkDigit: 0, statusCode0001
Thread: 50, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 37, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 39, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 41, isValid: true, referenceNumber: 17058887, validateNumber: 1705888, sum: 37, checkDigit: 7, statusCode0000
Thread: 52, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 54, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 43, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 45, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 56, isValid: true, referenceNumber: 07009882, validateNumber: 0700988, sum: 32, checkDigit: 2, statusCode0000
Thread: 58, isValid: true, referenceNumber: 07034880, validateNumber: 0703488, sum: 30, checkDigit: 0, statusCode0000
Thread: 47, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 49, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 51, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 53, isValid: true, referenceNumber: 18028885, validateNumber: 1802888, sum: 35, checkDigit: 5, statusCode0000
Thread: 55, isValid: true, referenceNumber: 18058888, validateNumber: 1805888, sum: 38, checkDigit: 8, statusCode0000
Thread: 57, isValid: true, referenceNumber: 07034880, validateNumber: 0703488, sum: 30, checkDigit: 0, statusCode0000
Can anyone confirm if I can Initialize the ScriptEngine and allow it to be used in a multithreaded application. As you can see I use global script variables but those will not be modified during its execution. As our design revolves around a web service that calls this script internally.
P.S. In my understanding @DataProvider(parallel=true) is the proper way to test the multithreading, so If I am wrong please point it out.
Edit Can anyone tell me how I can modify my code/script so that I can initialize the ScriptEngine and allow it to be used in a multi-threaded application. As I do not want to parse the script files over and over again.
As I previously thought that if the script does not use global variables to keep state it would be OK, but apparently that is not enough.
Thanks
Share Improve this question edited Mar 15, 2016 at 16:26 Jefrey Valencia asked Mar 15, 2016 at 12:56 Jefrey ValenciaJefrey Valencia 7133 gold badges13 silver badges30 bronze badges 2- Nashorn is not thread-safe. Is that what you are asking? – user21926 Commented Mar 15, 2016 at 14:43
- 1 Hi, thanks for the ment. Actually what I am asking is what is the proper approach so that I can pile my script in and use it a multi-threaded application if it is even possible. As I previously thought that if I put all my data manipulation inside the function and not use global variables to keep state that would be enough. – Jefrey Valencia Commented Mar 15, 2016 at 16:11
1 Answer
Reset to default 7You can initialize a ScriptEngine
and use it in a multithreaded application.
Instead of engine.eval(myScript);
you'll want to create a CompiledScript
instance that you can later evaluate into Bindings
instances:
Compilable pilable = (Compilable) engine;
CompiledScript script = pilable.pile(myScript);
And instead of using your engine
as an Invocable
you'll need to create a Bindings
instance for each thread/test, evaluate the piled script into it, get the script object mirror that wraps the function, and then call the function:
@Test(dataProvider = "validReferenceNumbers", timeOut = 3000)
public final void testValidReferenceNumber(String referenceNumber) throws ScriptException {
Map<String, String> parameters = new HashMap<>();
parameters.put("referenceNumber", referenceNumber);
Bindings bindings = engine.createBindings();
script.eval(bindings);
ScriptObjectMirror scriptObjectMirror = (ScriptObjectMirror) bindings.get("validate");
Object result = scriptObjectMirror.call(null, parameters);
/* insert result assertions here */
}
Sources:
- https://stackoverflow./a/30159424/3255152
- Reuse Nashorn ScriptEngine in Servlet
- https://stackoverflow./a/32252478/3255152