Pass more dynamic run time arguments to NodeJS child process - java

I want to run a Java program using NodeJS child process.
const util = require('util');
const exec = util.promisify(require('child_process').exec);
let dir = `${__dirname}/runtime/java/main`;
await exec(`javac Test.java`, {cwd: dir});
const { stdout, stderr } = await exec(`java Test`, {cwd: dir});
My Java code is taking multiple scanner run time arguments dynamically:
import java.util.Scanner;
class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter number of test cases");
int count = scanner.nextInt();
for(int i=0; i<count; i++){
String testCaseDescription = scanner.nextLine();
System.out.println("Test case " + i + " is "+testCaseDescription);
}
}
}
How do I pass dynamic run-time parameters to the child process?

As per the documentation of child_process.exec(), the first parameter given to the function is "the command to run, with space-separated arguments".
So, we need to get the command line arguments given to your Node.js script and pass them along to exec().
In Node.js, we can get these arguments via the process.argv property (more about it here).
process.argv is an array, and you will want to exclude the first element (which is the path of the Node.js runtime executing your file) as well as the second element (which is the path to your Node.js script).
You can use the slice() method to get only the portion of the array you want.
Then, you will want to transform the array (minus the first two elements) in a space-separated string.
You can do this by using the join() method.
The final result would look like this:
const util = require('util');
const exec = util.promisify(require('child_process').exec);
async function run() {
const dir = `${__dirname}/runtime/java/main`;
await exec(`javac Test.java`, {cwd: dir});
// Transforming the CLI arguments into a comma-separated string
const cliArguments = process.argv.slice(2).join(' ');
// Executing and passing the CLI arguments
const { stdout, stderr } = await exec(`java Test ${cliArguments}`, {cwd: dir});
}
run();

Related

how to compile and execute java code file in c# dynamically by passing params [duplicate]

This question already has answers here:
How to call Java code from C#?
(4 answers)
Closed 1 year ago.
I have a requirement to compile and run java programs from C# dynamically by passing parameters.
Ex: below is java code i have to execute this code from c# by passing parameters num1, num2. How to do in c#?
import java.util.Scanner;
public class AddTwoNumbers2 {
public int CalAdd(int num1, int num2) {
return num1 + num2;
}
}
I am looking for calling Java code file in c# like below, python code called in c# example code
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
//try
//{
var compilerOptions = (PythonCompilerOptions)engine.GetCompilerOptions();
ErrorSinkProxyListener(errorSink);
var scriptSource = engine.CreateScriptSourceFromFile(#"C:\Nidec\PythonScript\download_nrlist.py", Encoding.UTF8, Microsoft.Scripting.SourceCodeKind.File);
var compiledCode = scriptSource.Compile();
compiledCode.Execute(scope);
engine.ExecuteFile(#"C:\Nidec\PythonScript\download_nrlist.py", scope);
//get function and dynamically invoke
var calcAdd = scope.GetVariable("CalcAdd");
result = calcAdd(34, 8); // returns 42 (Int32)
You can put the java run commands inside a .sh or .bat file and then use System.Diagnostics.ProcessStartInfo in your C# method to execute that shell script/batch file.
Code snippet:
class MyProcess {
// Opens urls and .html documents using Internet Explorer.
void OpenWithArguments()
{
// url's are not considered documents. They can only be opened
// by passing them as arguments.
Process.Start("IExplore.exe", "www.northwindtraders.com");
// Start a Web page using a browser associated with .html and .asp files.
Process.Start("IExplore.exe", "C:\\myPath\\myFile.htm");
Process.Start("IExplore.exe", "C:\\myPath\\myFile.asp");
}
static void Main()
{
MyProcess myProcess = new MyProcess();
myProcess.OpenWithArguments();
}
}
Refer this

How to store function handles from ScriptManager for later usage?

tl;dr:
How do/can I store the function-handles of multiple js-functions in java for using them later? Currently I have two ideas:
Create multipe ScriptEngine instances, each containing one loaded function. Store them in a map by column, multiple entries per column in a list. Looks like a big overhead depending on how 'heavy' a ScriptEngine instance is...
Some Javascript solution to append methods of the same target field to an array. Dont know yet how to access that from the java-side, but also dont like it. Would like to keep the script files as stupid as possible.
var test1 = test1 || [];
test1.push(function(input) { return ""; });
???
Ideas or suggestions?
Tell me more:
I have a project where I have a directory containing script files (javascript, expecting more than hundred files, will grow in future). Those script files are named like: test1;toupper.js, test1;trim.js and test2;capitalize.js. The name before the semicolon is the column/field that the script will be process and the part after the semicolon is a human readable description what the file does (simplified example). So in this example there are two scripts that will be assigned to the "test1" column and one script to the "test2" column. The js-function template basically looks like:
function process(input) { return ""; };
My idea is, to load (and evaluate/compile) all script files at server-startup and then use the loaded functions by column when they are needed. So far, so good.
I can load/evaluate a single function with the following code. Example uses GraalVM, but should be reproducable with other languages too.
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js");
final Invocable invocable = (Invocable) engine;
engine.eval("function process(arg) { return arg.toUpperCase(); };");
var rr0 = invocable.invokeFunction("process", "abc123xyz"); // rr0 = ABC123XYZ
But when I load/evaluate the next function with the same name, the previous one will be overwritten - logically, since its the same function name.
engine.eval("function process(arg) { return arg + 'test'; };");
var rr1 = invocable.invokeFunction("process", "abc123xyz"); // rr1 = abc123xyztest
This is how I would do it.
The recommended way to use Graal.js is via the polyglot API: https://www.graalvm.org/reference-manual/embed-languages/
Not the same probably would work with the ScriptEngine API, but here's the example using the polyglot API.
Wrap the function definition in ()
return the functions to Java
Not pictured, but you probably build a map from the column name to a list of functions to invoke on it.
Call the functions on the data.
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.proxy.*;
public class HelloPolyglot {
public static void main(String[] args) {
System.out.println("Hello Java!");
try (Context context = Context.create()) {
Value toUpperCase = context.eval("js", "(function process(arg) { return arg.toUpperCase(); })");
Value concatTest = context.eval("js", "(function process(arg) { return arg + 'test'; })");
String text = "HelloWorld";
text = toUpperCase.execute(text).asString();
text = concatTest.execute(text).asString();
System.out.println(text);
}
}
}
Now, Value.execute() returns a Value, which I for simplicity coerce to a Java String with asString(), but you don't have to do that and you can operate on Value (here's the API for Value: https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Value.html).

How to use function defined in a groovy script using the "evaluate" method from Java

I just discover Groovy call from Java and have problem with this case :
I have a groovy file : "test.groovy"
a = 1.0
def mul2( x ) { 2.0 * x }
And I want to use it from Java code like this
GroovyShell gs = new GroovyShell();
gs.parse( new File( ".../test.groovy" ) ).run();
System.out.printf( "a = %s%n", gs.evaluate("a") ); // ok
System.out.printf( "mul2(a) = %s%n", gs.evaluate( "mul2(a)" ) ); // error
The error is :
groovy.lang.MissingMethodException: No signature of method: Script1.mul2() is applicable for argument types: (BigDecimal) values: [1.0]
What I have to do to have access to function defined in groovy script, using evaluate() method ?
I need to use "evaluate" method because I want finally to evaluate something like Math.sin( a * mul2(Math.Pi) ).
Now I have 4 solutions (the forth is what I searched for) :
use closure as in answer of 'Szymon Stepniak'
use import static as in answer of 'daggett'
extends the script that contains Java functions with the script that evaluate the expression :
...the class (in Java, not Groovy)...
public static abstract class ScriptClass extends Script
{
double mul2( double x )
{
return x * 2;
}
}
...the code...
CompilerConfiguration config = new CompilerConfiguration();
config.setScriptBaseClass(ScriptClass.class.getName());
GroovyShell gs = new GroovyShell(config);
System.out.printf( "result = %s%n", gs.evaluate("mul2(5.05)") );
That works but the code is in Java, not what I want, but I note it here for ones need to do that
And finally extends groovy script :
the groovy file :
double mul2( x ) { x * 2 }
a=mul2(3.33)
the java code that use it
GroovyClassLoader gcl = new GroovyClassLoader();
Class<?> r = gcl.parseClass( resourceToFile("/testx.groovy") );
CompilerConfiguration config = new CompilerConfiguration();
config.setScriptBaseClass(r.getName());
GroovyShell gs = new GroovyShell(gcl, config);
System.out.printf( "mul2(5.05) = %s%n", gs.evaluate("mul2(5.05)") );
// WARNING : call super.run() in evaluate expression to have access to variables defined in script
System.out.printf( "result = %s%n", gs.evaluate("super.run(); mul2(a) / 123.0") );
It's exactly what I wanted :-)
There are two things worth explaining to understand what is happening here. There are two different scopes in the script you have provided.
The variable a gets stored in GroovyShell binding object and that is why it is available in every gs.evaluate() call. Take a look at this example:
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
final class ExecuteGroovyScriptExample {
public static void main(String[] args) {
final String script = "a = 1.0 \n" +
"def mul2(x) { 2.0 * x }\n";
final Binding binding = new Binding();
final GroovyShell gs = new GroovyShell(binding);
final Script sc = gs.parse(script);
sc.run();
System.out.printf("binding.getVariable(\"a\") == %s\n", binding.getVariable("a"));
}
}
Running this example produces following output:
binding.getVariable("a") == 1.0
The second thing is that every gs.evaluate() call generates a new groovy.lang.Script class which has a completely different context. This is why calling:
gs.evaluate("mul2(a)")
throws something like this:
Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: Script2.mul2() is applicable for argument types: (BigDecimal) values: [1.0]
because the script class that gets generated from gs.evaluate("mul2(a)") invocation does not contain mul2(x) method. The class that gets generated by this call looks something like this:
class Script2 extends groovy.lang.Script {
void run() {
mul2(a)
}
}
However, the script class returned from gs.parse(script) contains mul2(x) method, so you can invoke it, but not as gs.evaluate() call, but Script.invokeMethod(name, args) instead. Something like this:
import groovy.lang.GroovyShell;
import groovy.lang.Script;
final class ExecuteGroovyScriptExample {
public static void main(String[] args) {
final String script = "a = 1.0 \n" +
"def mul2(x) { 2.0 * x }\n";
final GroovyShell gs = new GroovyShell();
final Script sc = gs.parse(script);
sc.run();
System.out.printf("mul2(a) = %s%n", sc.invokeMethod("mul2", gs.evaluate("a")));
}
}
This example produces following output:
mul2(a) = 2.00
Take a look how mul2(x) method got invoked. Firstly, we store script returned by gs.parse(script) in sc variable and it allows us to invoke method defined in this script by following call:
sc.invokeMethod("mul2", gs.evaluate("a"));
In this example we take value of a variable simply by gs.evaluate("a"), but you can also use binding object from the first example as well. And keep in mind that if a variable was defined like:
def a = 1.0
or
#groovy.transform.Field
def a = 1.0
it would not get stored in the binding object anymore and in the first case it defines script's local variable a and in the second case it defines script class field a.
Alternatively, if you want to execute following invocation:
gs.evaluate("mul2(a)")
or even
gs.evaluate("Math.sin( a * mul2(Math.PI))")
you would have to modify input Groovy script file and replace function mul2(x) definition with a closure in the same scope as the a variable, so it gets stored in the binding object:
a = 1.0
mul2 = { x -> 2.0 * x }
let you have /my/groovy/classes/Test.groovy:
static mul2( x ) { 2.0 * x }
def mul3( x ) { 3.0 * x }
then you can use class loader to load it as a class and use this class in expressions:
GroovyShell gs = new GroovyShell();
gs.getClassLoader().addClasspath("/my/groovy/classes");
System.out.println( gs.evaluate( "import static Test.*; mul2(5)" ) );
System.out.println( gs.evaluate( "new Test().mul3(6)" ) );

Run CLI with arguments as params to a main method

I have written a CLIInterface in java that takes the necessary flags from the user as a String[].
Here is some sample code:
public static void call(String[] args)
{
try
{
Map<String, Object> cliOptions = new HashMap<>();
for (int i = 0; i < args.length; ++i) {
// override the db directory
if (args[i].equals("--help")) {
printHelp();
System.exit(1);
}
..........
}
I know that you can invoke the method in the command line using something like this:
java -Dexec.mainClass=org.bitcoinj.examples.ForwardingService -Dexec.args=""
but I want to be able to use it like a CLI and have something like this:
ethj --help whereby --help would be args[0] and then from there I could handle it in the call method.
How would one go about doing this?
the easiest way is to write a starter script ethj for your operation system passing the arguments to the java executable.
btw:
you don't need the -Dexec.args="" form, just list the parameters after the main class name...

Dynamic calling of JBehave steps from inside Java

In Java I have a String object that has the text that I wish to be matched and executed by JBehave as a step. How can this be done? Can it be done?
What I am really trying to do is to have a wrapper JBehave step that instruments another arbitrary JBehave step. It does a few things before and after calling on the "inner" step.
So lets say that I already have the following
When I say Hello World
and
#When("I say $text")
public void iSay(final String text)
{
System.out.println(text);
}
I want to be able to do the following :
When I repeat 4 times I say Hello World
it will call :
#When("I repeat $count times $subStepString")
public void repeat(final int repeatCount, final String subStepString)
{
// prep code here
for (int i = 0; i < repeatCount; i++)
{
howDoIdoThisBitHere(subStepString);
}
// post process code here
}
The part that says howDoIdoThisBitHere(...) should end up having JBehave match the value of subStepString as if it was encountered in the case above. This way I can use this method to call other arbitrary things.
I'm not sure this is a great idea since the step classes shouldn't have any dependency on the core configuration (StepMatchers, Runners etc.), but is this solution kind of what you're looking for?
#When("I repeat $count times $subStepString")
public void repeat(final int repeatCount, final String subStepString)
{
// prep code here
for (int i = 0; i < repeatCount; i++)
{
StoryParser sp = configuration().storyParser();
Story s = sp.parseStory(subStepString);
StoryRunner e = configuredEmbedder().storyRunner();
e.run(configuration(), configuredEmbedder().candidateSteps(), s);
}
}

Categories

Resources