Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a function inside a python script and pass parameters while using ScriptEngine to run python script from Java

I am using below code to execute a python script from within a Java class:

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleScriptContext;

StringWriter writer = new StringWriter();
ScriptEngineManager manager = new ScriptEngineManager();
ScriptContext context = new SimpleScriptContext();
context.setWriter(writer);
ScriptEngine engine = manager.getEngineByName("python");
engine.eval(new FileReader("test.py"), context);

I want to know how can I call a function inside test.py with above method and also pass some parameters to that function?

Note: I know a better way to execute the python script is through using Process but due to system requirements I do not want to use Process approach as it spawns a new process with each execution.

like image 264
Jason Donnald Avatar asked Jul 14 '26 17:07

Jason Donnald


1 Answers

You need to change it a little to invoke a function.

ScriptContext context = new SimpleScriptContext();
context.setWriter(writer);
ScriptEngine engine = manager.getEngineByName("python");

// CHANGE: Set the context in the engine, so that invoking functions
// is done in the same scope as evaluating the script.
engine.setContext(context);

engine.eval(new FileReader("test.py"));

Invocable inv = (Invocable)engine;
inv.invokeFunction("func_name", param1, param2);

Basically, the Jython engine (which I assume you are using for scripting python) allows you to use its ScriptEngine as an Invocable. This means you can use it to call functions, provided that you are in the same "scope" as the script you have ran. This is achieved by setting the context in the engine instead of passing it as a parameter to eval.


Note: in your question, you say that you know that running the python in a separate process would probably be better. That's not necessarily true. For example, calling a function from it (and getting its returned value!) would be a lot harder if you ran it from a different process. The scripting extension allows you to do that.

Another option would be to use Jython directly, not through the standard Java scripting platform. But I don't have the knowledge to expand on that.

like image 90
RealSkeptic Avatar answered Jul 17 '26 16:07

RealSkeptic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!