Running groovy script in Java code - java

Hello I am looking to run a groovy script inside Java code but I didn't find many tutorial about that.
I have a String that contain a groovy script :
private String processingCode = "def hello_world() { println \"Hello, world!\" }";
I have also downloaded the Groovy SDK.
Which groovy jar should I include in java project ? And how to execute the script in Java ?

What you need is a groovy-all dependency and GroovyShell.
Main class will be:
package lol;
import groovy.lang.GroovyShell;
public class Lol {
public static void main(String[] args) {
String processingCode = "def hello_world() { println 'Hello, world!' }; hello_world();";
GroovyShell shell = new GroovyShell();
shell.evaluate(processingCode);
}
}
Here is a demo.
Use gradle run to run it.

Related

Cannot see print and println statements in Eclipse using JEP/Pydev

I'm learning JEP and PyDev plugin eclipse and new to Python.
I cannot see my python print and java println statements on Eclipse console tab.
As I'm just trying things out I create a simple python script by creating a new PyDev module and it just has one line (greetings.py):
print("Hello from python");
When I run this I see it in the console when I run it both the PyDev and Jave EE perspective.
Next as the intent of this exercise is to look into JEP to see if it's adequate for my project so I created another Java project with this code:
package my.sand.box;
import jep.Interpreter;
import jep.Jep;
import jep.JepException;
import jep.SharedInterpreter;
public class JepTest {
public static void main(String[] args) throws JepException {
// TODO Auto-generated method stub
System.out.println("hey");
try (Interpreter interp = new SharedInterpreter()) {
//interp.exec("import example_package");
// any of the following work, these are just pseudo-examples
interp.runScript("full/path/to/greetings.py");
interp.eval("import sys");
interp.eval("s = 'Hello World'");
interp.eval("print s");
String java_string = interp.getValue("s").toString();
System.out.println("Java String:" + java_string);
}
}
}
I don't see anyting on the console. Not even the java println statements.
I also recreated both projects in a new workspace and could see the output. What's different between both workspaces is that in the one that's not workign I have other java projects and pydev projects open.
Would appreciate any advice.
I've faced a similar issue working with Jep before, the trick is you need to redirect Python's output stream in your IDE by calling the correct method.
Take a look at https://github.com/ninia/jep/issues/298
As Klodovsky mentioned, you need to redirect Python's output to the stream used by the IDE. I've adapted your example to do this. The key line is the call to SharedInterpreter.setConfig:
package my.sand.box;
import jep.Interpreter;
import jep.JepConfig;
import jep.JepException;
import jep.SharedInterpreter;
public class JepTest {
public static void main(String[] args) throws JepException {
System.out.println("hey");
// Eclipse doesn't use stdout & stderr, so use the streams from Java.
SharedInterpreter.setConfig(new JepConfig()
.redirectStdErr(System.err)
.redirectStdout(System.out));
try (Interpreter interp = new SharedInterpreter()) {
// interp.exec("import example_package");
// any of the following work, these are just pseudo-examples
// Uncomment if you've created a greetings.py script.
// interp.runScript("full/path/to/greetings.py");
interp.eval("import sys");
interp.eval("s = 'Hello World'");
interp.eval("print(s)");
String java_string = interp.getValue("s").toString();
System.out.println("Java String:" + java_string);
}
}
}

How to build a .jar out of scala in eclipse?

I am trying to run a scala code using spark-submit. I have to convert the scala code into a .jar and then execute. I tried to convert .scala file to .jar directly but I got "NoClassFoundException".
Then I tried to call scala class from java file and convert java file to a .jar and execute using spark-submit. But this time java class is found but scala class is not found. When I run this in my eclipse it is giving expected output
java class
package com.connect.cassandra;
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
MainScalaClass app = new MainScalaClass();
app.main(args);
}
}
Scala class
package com.connect.cassandra
import com.datastax.driver.core.Cluster
class MainScalaClass {
def main(args: Array[String]): Unit = {
simpleCassConnector.foo()
}
}
object simpleCassConnector {
def foo(){
println("inside object")
val cluster = Cluster.builder()
.addContactPoint("localhost")
.withPort(9042)
.build()
val session = cluster.connect()
val p = session.execute("Select * from persons.user limit 2")
println(p.all())
}
}
Error
Exception in thread "main" java.lang.NoClassDefFoundError: com/connect/cassandra/MainScalaClass
where am I going wrong and is there any way to directly convert scala file to .jar and execute without "NoClassFound" exception?

How do I call Java Methods from Jython that is executed by the Java class?

I am a novice programmer in (Java/C++/C#) and I also know Python. I am trying to create a GameEngine in Java that can call Jython scripts, that have access to methods in the Java engine.
I am clueless as to how to approach this. I have already done weeks of research and nothing has answered my question ; that is:
How can I call methods in my Parent class, from my JythonScript, which is executed by my Parent class?
-----------------------------------UPDATE---------------------------------------------------
Okay, The answer here helped me understand some things, but it didn't solve my problem.
What I was wondering if something such as this would work:
class MyJavaClass
{
Public MyJavaClass()
{
PythonInterpreter interp = new PythonInterpreter;
interp.execfile("MyJythonScript.py");
interp.exec("InGameCommand");
}
public void SpawnPlayer()
{}
public void KillPlayer()
{}
}
MyJythonScript.py
Def InGameCommand():
SpawnPlayer()
KillPlayer()
Is this even possible? There a way to do this?
-----------------------------------UPDATE---------------------------------------------------
Location to Jython: "C:\jython2.7a2\jython.jar"
Location to my work: "C:\Documents and Settings\PC\Desktop\Jython*.java"
Location to my local JtyhonJar: "C:\Documents and Settings\PC\Desktop\Jython\jython.jar"
my compiler I wrote:
"#echo off"
"javac -classpath C:\jython2.7a2\jython.jar *.java"
"echo done"
"pause >nul"
now it doesn't even compile... (I've changed little things in my code to see if it changed and it hasn't!)
Yes, this way is fine, but you can not run python script in constructor method, if so, it will be dead recursive at your code. please see the following code. you run PythonScriptTest class, it will run python script first, then python script will invoke PythonScriptTest.SpawnPlayer() method.
java code:
package com.xxx.jython;
import org.python.core.PyFunction;
import org.python.util.PythonInterpreter;
public class PythonScriptTest {
public static void main(String[] args) {
PythonScriptTest f = new PythonScriptTest();
f.executePythonScript();
}
public PythonScriptTest(){
}
public void executePythonScript() {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("/home/XXX/XXX/util.py");
PyFunction pyFuntion = (PyFunction) interpreter.get("InGameCommand", PyFunction.class);
pyFuntion.__call__();
}
public void SpawnPlayer() {
System.out.println("Run SpawnPlayer method ##################");
}
}
Python scripts, named util.py:
import sys.path as path
# the following path is eclipse output class dir
# does not contain java class package path.
path.append("/home/XXX/XXX/Test/bin")
from com.xxx.jython import PythonScriptTest
def add(a, b):
return a + b
def InGameCommand():
myJava = PythonScriptTest()
myJava.SpawnPlayer()
need to jython.jar
execute python code in java.
import org.python.util.PythonInterpreter;
public class PythonScript{
public static void main(String args[]){
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("days=('One','Two','Three','Four'); ");
interpreter.exec("print days[1];");
}
}
invoke python script method in java.
python script file, named test.py
def add(a, b):
return a + b
java code:
import org.python.core.PyFunction;
import org.python.core.PyInteger;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
public class PythonScript {
public static void main(String args[]) {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("/home/XXX/XXX/test.py");
PyFunction pyFuntion = (PyFunction)interpreter.get("add",PyFunction.class);
int a = 10, b = 20 ;
PyObject pyobj = pyFuntion.__call__(new PyInteger(a), new PyInteger(b));
System.out.println("result = " + pyobj.toString());
}
}
run python script in java
python script file, named test.py:
number=[1,10,4,30,7,8,40]
print number
number.sort()
print number
java code:
import org.python.util.PythonInterpreter;
public class FirstJavaScript {
public static void main(String args[]) {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile("/home/XXX/XXX/test.py");
}
}

Calling a Groovy function from Java

How do you call a function defined in a Groovy script file from Java?
Example groovy script:
def hello_world() {
println "Hello, world!"
}
I've looked at the GroovyShell, GroovyClassLoader, and GroovyScriptEngine.
Assuming you have a file called test.groovy, which contains (as in your example):
def hello_world() {
println "Hello, world!"
}
Then you can create a file Runner.java like this:
import groovy.lang.GroovyShell ;
import groovy.lang.GroovyClassLoader ;
import groovy.util.GroovyScriptEngine ;
import java.io.File ;
class Runner {
static void runWithGroovyShell() throws Exception {
new GroovyShell().parse( new File( "test.groovy" ) ).invokeMethod( "hello_world", null ) ;
}
static void runWithGroovyClassLoader() throws Exception {
// Declaring a class to conform to a java interface class would get rid of
// a lot of the reflection here
Class scriptClass = new GroovyClassLoader().parseClass( new File( "test.groovy" ) ) ;
Object scriptInstance = scriptClass.newInstance() ;
scriptClass.getDeclaredMethod( "hello_world", new Class[] {} ).invoke( scriptInstance, new Object[] {} ) ;
}
static void runWithGroovyScriptEngine() throws Exception {
// Declaring a class to conform to a java interface class would get rid of
// a lot of the reflection here
Class scriptClass = new GroovyScriptEngine( "." ).loadScriptByName( "test.groovy" ) ;
Object scriptInstance = scriptClass.newInstance() ;
scriptClass.getDeclaredMethod( "hello_world", new Class[] {} ).invoke( scriptInstance, new Object[] {} ) ;
}
public static void main( String[] args ) throws Exception {
runWithGroovyShell() ;
runWithGroovyClassLoader() ;
runWithGroovyScriptEngine() ;
}
}
compile it with:
$ javac -cp groovy-all-1.7.5.jar Runner.java
Note: Runner.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
(Note: The warnings are left as an exercise to the reader) ;-)
Then, you can run this Runner.class with:
$ java -cp .:groovy-all-1.7.5.jar Runner
Hello, world!
Hello, world!
Hello, world!
The simplest way is to compile the script into a java class file and just call it directly. Example:
// Script.groovy
def hello_world() {
println "Hello, World!"
}
// Main.java
public class Main {
public static void main(String[] args) {
Script script = new Script();
script.hello_world();
}
}
$ groovyc Script.groovy
$ javac -classpath .:$GROOVY_HOME/embeddable/groovy-all-1.7.5.jar Main.java
$ java -classpath .:$GROOVY_HOME/embeddable/groovy-all-1.7.5.jar Main
Hello, World!
Either
Compile as ataylor suggests
Use JSR-223 as explained here
If you are using Spring, have a groovy class that implements a Java interface, and inject into your code with:
<lang:groovy id="messenger" script-source="classpath:Messenger.groovy">
<lang:property name="message" value="I Can Do The Frug" />
</lang:groovy>
One advantage of the spring approach is the concept of 'refreshable beans'. That is, Spring can be configured to monitor your script file for modifications, and replace at runtime.
You too can use the Bean Scripting Framework to embed any scripting language into your Java code. BSF give you the opportunity of integrate other languages, but is not native integration.
If you are clearly focused to use Groovy the GroovyScriptEngine is the most complete solution.
=)
One simple example:
import groovy.lang.GroovyClassLoader;
import groovy.lang.Script;
public class GroovyEmbedder {
static public final String GROOVY_SCRIPT=
"println ('Hello World !')";
static public void main(String[] args) throws Exception {
((Script) new GroovyClassLoader().parseClass(GROOVY_SCRIPT).newInstance()).run();
}
}
Testing
> javac -cp groovy-all-2.4.10.jar GroovyEmbedder.java
> java -cp groovy-all-2.4.10.jar:. GroovyEmbedder
Hello World !
Just more elegant ways:
GroovyScriptEngine engine = new GroovyScriptEngine( "." )
Object instance = engine
.loadScriptByName(scriptName)
.newInstance()
Object result = InvokerHelper.invokeMethod(instance, methodName, args)
And if script class extends groovy.lang.Script:
Object result = engine
.createScript(scriptName, new Binding())
.invokeMethod(methodName, args)
No need to extend groovy.lang.Script if you just want call main method of your groovy class:
Object result = engine
.createScript(scriptName, new Binding())
.run()

Executing script inside method with BeanShell

I'm not really sure how I can explain this, but here goes:
I want to be able to "insert" some commands into parts of my code which will be loaded from external files. To parse and execute these commands, I presumably have to use some scripting like BeanShell's eval method. The problem is that it doesn't seem to recognize the instance/method it's inside of. As a very basic example, I want to do something like
public void somethingHappens()
{
Foo foo = new Foo();
Interpreter i = new Interpreter();
i.eval("print(foo.getName());");
}
Is this possible? Should I use other scripting tools?
If you're using 1.6, you can use the built in JavaScript support.
The Java Scripting Programmer's Guide explains how to import Java classes into your script.
Code example 9 in this article explains how to pass objects into the script's scope.
Using beanshell, this is something you can try
package beanshell;
import bsh.EvalError;
import bsh.Interpreter;
public class DemoExample {
public static void main( String [] args ) throws EvalError {
Interpreter i = new bsh.Interpreter();
String usrIp = "if(\"abc\".equals(\"abc\")){"
+ "demoExmp.printValue(\"Rohit\");"
+ "}";
i.eval(""
+ "import beanshell.DemoExample;"
+ "DemoExample demoExmp = new beanshell.DemoExample();"
+ ""+usrIp);
}
public static void printValue(String strVal){
System.out.println("Printing Value "+strVal);
}
}

Categories