I have same custom functions with the same names on different script files written in python, groovy and javascript. User can choose one of the scripts that want to use. I want to call functions from these scripts in generic way.
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("python");
Bindings bindings = engine.createBindings();
engine.eval(new FileReader("C:/Users/Cgr/Desktop/CustomPython.py");
Invocable inv = (Invocable) engine;
System.out.println(inv.invokeFunction("customConcatFunc", "str1", "str2"));
With this way I can call my functions even change ScriptEngineManager parameter as "javascript" or "groovy" with changing reader files with "CustomJs.js" or "Customgroovy.groovy".
However, I wonder that is there a way to call functions without using invokeFunction like below:
First, evaluate script and put the result on binding then calling function on this object.
bindings.put("x", "str1");
bindings.put("y", "str2");
bindings.put("script", engine.eval(new FileReader("C:/Users/Cgr/Desktop/CustomgrPython.py")));
engine.eval("script.customConcatFunc(x,y)", bindings);
So, this is the most generic way for me if there is way like this or are there any other suggestions?
The method below might be helpful avoiding call invokeFunction:
#Test
public void test60_ScriptEngineTest()
throws URISyntaxException, ScriptException, NoSuchMethodException, FileNotFoundException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("groovy");
Compilable compilable = (Compilable) engine;
Bindings bindings = engine.createBindings();
URL url=getClass().getResource("/data-encoder-dir/testFunc.groovy");
File script =new File(url.toURI());
Reader reader = new FileReader(script);
CompiledScript compiledScript = compilable.compile(reader);
bindings.put("x", 5011);
String result = (String) compiledScript.eval(bindings);
assertEquals(result, "5011");
}
a groovy file attached (in /data-encoder-dir/testFunc.groovy):
public String testFunc(Integer bd) {
return bd.toString();
}
testFunc(x)
PS: I'm using groovy, the javascript scenario or other java script engine compatible would follow the same route.
Related
Hello I want to pass argument to python script in Java with Jython i have this code:
public static void pyCode(String argumentOne) throws FileNotFoundException, ScriptException {
StringWriter writer = new StringWriter(); //ouput will be stored here
ScriptEngineManager manager = new ScriptEngineManager();
ScriptContext context = new SimpleScriptContext();
context.setWriter(writer); //configures output redirection
ScriptEngine engine = manager.getEngineByName("python");
engine.eval(new FileReader("main.py"), context);
System.out.println(writer.toString());
}
I need to execute the python script like main.py arg1 or to pass the String input to the main.py file with will be used in the file.
I just found Jython and I can't see proper example in the documentation.
I'm trying to get which line is generating an error when calling a kotlin script from java.
The following code gives line number -1.
try
{
String scriptcode = "\n\nthrow Exception()";
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByExtension("kts");
engine.eval(scriptcode);
}
catch(ScriptException se)
{
System.out.println(se.getLineNumber());
}
Am I missing something?
Could please try something like this. se.getStackTrace()[0].getLineNumber();
I would like to use a function to read from a properties file and than use the object of that file at various places.here is what I have tried so far with no luck.
public class all_the_functions
{
public FileInputStream loadPropertiesFile(FileInputStream obj2) throws IOException
{
//reading from the properties file
Properties obj = new Properties();
FileInputStream fileobj = new FileInputStream("//Users//macuser//Desktop//selenium//project_Mat//input_properties.properties");
obj.load(fileobj);
return fileobj;
}
}
And than in my main function I am using the following code
public class searchdynamic();
{
FileInputStream Obj;
all_the_functions func = new all_the_functions();
func.loadPropertiesFile(Obj);
WebDriver driver = new FirefoxDriver();
driver.navigate().to(Obj.getproperty("valid URL");
}
The end goal is to read from. The input file by using the function and stroung the properties file so that I can always call the same function when I need to read from the file. Can someone please point me to what I am doing wrong here.
Thanks.
Can u try this
public class searchdynamic();
{
FileInputStream Obj;
all_the_functions func = new all_the_functions();
Obj=func.loadPropertiesFile(Obj);
WebDriver driver = new FirefoxDriver();
driver.navigate().to(Obj.getproperty("valid URL");
}
What is the string that your property is returning? "http://www..."
In theory, this should work (although I'm used to webdriver being navigate().GoToUrl(string url). Give that a shot...
Also, friendly warning about this being not oop or compiling. Might be a good idea to tie your properties to values somehow. I understand this is a keyword driven framework, but it is better practice to have a user input "Google" and have your code digest that into something like
driver.Navigate().GoToUrl("http://google.com"); // (c#)
This way, you can count on correct input and handle incorrect input appropriately.
Regardless, try .Navigate().GoToUrl()
I have problems accessing Java classes in JavaScript. Calling a code snippet
var String = Java.type("java.lang.String");
from Java via javax.script.ScriptEngine, yields follwing Error
Exception in thread "main" javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "Java" is not defined. (path/to/string.js#1) in path/to/string.js at line number 1
at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:156)
at main.JsTest.main(JsTest.java:55)
Using non-Java classes in the script works fine, e.g. var value = a + b, where a and b are defined in a javax.script.ScriptContext.
This is the Java class that executes the script.
JsTest.java
public class JsTest
{
public static void main(String[] args) throws Exception
{
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine se = sem.getEngineByExtension("js");
String script = "path/to/string.js";
File scriptFile = new File(script);
FileReader fr = new FileReader(scriptFile);
se.put(ScriptEngine.FILENAME, script);
ScriptContext sc = new SimpleScriptContext();
se.eval(fr, sc);
}
}
I have no idea where your Java.type is coming from, but the official documentation uses Packages.java or just java.
So your line should probably look like
var String = Packages.java.lang.String;
I have a code in Java that opens a excel template by aspose library (it runs perfectly):
import com.aspose.cells.*;
import java.io.*;
public class test
{
public static void main(String[] args) throws Exception
{
System.setProperty("java.awt.headless", "true");
FileInputStream fstream = new FileInputStream("/home/vmlellis/Testes/aspose-cells/template.xlsx");
Workbook workbook = new Workbook(fstream);
workbook.save("final.xlsx");
}
}
After I run this on Ruby with RJB (Ruby Java Bridge):
require 'rjb'
#RJM Loading
JARS = Dir.glob('./jars/*.jar').join(':')
print JARS
Rjb::load(JARS, ['-Xmx512M'])
system = Rjb::import('java.lang.System')
file_input = Rjb::import('java.io.File')
file_input_stream = Rjb::import('java.io.FileInputStream')
workbook = Rjb::import('com.aspose.cells.Workbook')
system.setProperty("java.awt.headless", "true")
file_path = "/home/vmlellis/Testes/aspose-cells/template.xlsx"
file = file_input.new(file_path)
fin = file_input_stream.new(file)
wb = workbook.new(fin)
I get this error:
test.rb:57:in `new': Can't find file: java.io.FileInputStream#693a317a. (FileNotFoundException)
from aspose-test.rb:57:in `<main>'
Why? I run the same code... but in Ruby is not working! How do I fix this?
Update:
In documentation there is the the initializer: Workbook(java.io.InputStreamstream)... but it's not working in RJB. (How is this possible?)
Your program should have worked, but I could not find any reason why it didn't and I am looking into it.
Now the alternate approaches.
Approach 1
Use Workbook(String) constructor instead of Workbook(FileInputStream). This worked flawlessly at my end. The sample code is
require 'rjb'
#RJM Loading
JARS = Dir.glob('/home/saqib/cellslib/*.jar').join(':')
print JARS
Rjb::load(JARS, ['-Xmx512M'])
system = Rjb::import('java.lang.System')
workbook = Rjb::import('com.aspose.cells.Workbook')
system.setProperty("java.awt.headless", "true")
file_path = "/home/saqib/rjb/template.xlsx"
save_path = "/home/saqib/rjb/final.xlsx"
wb = workbook.new(file_path)
wb.save(save_path)
Approach 2
Write a new Java class library. Write all your Aspose.Cells related code in it. Expose very simple and basic methods that needs to be called from Ruby (RJB).
Why?
It is easy to write program in native Java language. If you use RJB, you need to perform a lot of code conversions
It is easy to debug and test in Java.
Usage of RJB will only be limited to calling methods from your own Java library. The RJB code will be small and basic.
Similar Example using own library
Create a new Java project, lets say "cellstest". Add a new public class in it.
package cellstest;
import com.aspose.cells.Workbook;
public class AsposeCellsUtil
{
public String doSomeOpOnWorkbook(String inFile, String outFile)
{
String result = "";
try
{
// Load the workbook
Workbook wb = new Workbook(inFile);
// Do some operation with this workbook
// ..................
// Save the workbook
wb.save(outFile);
// everything ok.
result = "ok";
}
catch(Exception ex)
{
// Return the exception to calling program
result = ex.toString();
}
return result;
}
}
Like this, add as many methods as you like, for each operation.
Build the project and copy the "cellstest.jar" in same folder where you copied Aspose.Cells jar files. You can return a String from your methods and check the return value in Ruby program for success or error code. The Ruby program will now be like
require 'rjb'
#RJM Loading
JARS = Dir.glob('/home/saqib/cellslib/*.jar').join(':')
print JARS
Rjb::load(JARS, ['-Xmx512M'])
system = Rjb::import('java.lang.System')
AsposeCellsUtil = Rjb::import('cellstest.AsposeCellsUtil')
system.setProperty("java.awt.headless", "true")
file_path = "/home/saqib/rjb/template.xlsx"
save_path = "/home/saqib/rjb/final.xlsx"
# initialize instance
asposeCellsUtil = AsposeCellsUtil.new()
# call methods
result = asposeCellsUtil.doSomeOpOnWorkbook(file_path, save_path)
puts result
PS. I work for Aspose as Developer Evangelist.
In your Java code, you pass a file name string into FileInputStream() constructor:
FileInputStream fstream = new FileInputStream("/home/vmlellis/Testes/aspose-cells/template.xlsx");
In your Ruby code, you pass a file object:
file = file_input.new(file_path)
fin = file_input_stream.new(file)
Have you tried to do the same thing as in Java?
fin = file_input_stream.new(file_path)