This question already has answers here:
Calling Python in Java?
(12 answers)
Closed 9 years ago.
I know jython allows us to call a java method from any java's classfile as if they were written for python, but is the reverse possible ???
I already have so many algorithms that written in python, they work pretty well with python and jython but they lack a proper GUI. I am planing to bring the GUI with the java and to keep the python library intact. I am not able to write a good GUI with jython or python and I cannot write a good algorithm with python. So the solution I found was to merge java's GUI and python's library. Is this possible. Can I call python's library from java.
Yes, that can be done . Normally this will be done by creating a PythonInterpreter object and then calling the python class using that .
Consider the following example :
Java :
import org.python.core.PyInstance;
import org.python.util.PythonInterpreter;
public class InterpreterExample
{
PythonInterpreter interpreter = null;
public InterpreterExample()
{
PythonInterpreter.initialize(System.getProperties(),
System.getProperties(), new String[0]);
this.interpreter = new PythonInterpreter();
}
void execfile( final String fileName )
{
this.interpreter.execfile(fileName);
}
PyInstance createClass( final String className, final String opts )
{
return (PyInstance) this.interpreter.eval(className + "(" + opts + ")");
}
public static void main( String gargs[] )
{
InterpreterExample ie = new InterpreterExample();
ie.execfile("hello.py");
PyInstance hello = ie.createClass("Hello", "None");
hello.invoke("run");
}
}
Python :
class Hello:
__gui = None
def __init__(self, gui):
self.__gui = gui
def run(self):
print 'Hello world!'
Related
In my end product, I provide the ability to extend the application code at runtime using small Groovy scripts that are edited via a form and whose code are persisted in the SQL database.
The scheme that these "custom code" snippets follow is generally returning a value based on input parameters. For example, during the invoicing of a service, the rating system might use a published schedule of predetermined rates, or values defined in a contract in the application, through custom groovy code, if an "overridden" value is returned, then it should be used.
In the logic that would determine the "override" value of the rate, I've incorporated something like these groovy code snippets that return a value, or if they return null, then the default value is used. E.g.
class GroovyRunner {
static final GroovyClassLoader classLoader = new GroovyClassLoader()
static final String GROOVY_CODE = MyDatabase().loadCustomCode()
static final String GROOVY_CLASS = MyDatabase().loadCustomClassName()
static final String TEMPDIR = System.getProperty("java.io.tmpdir")
double getOverrideRate(Object inParameters) {
def file = new File(TEMPDIR+GROOVY_CLASS+".groovy")
BufferedWriter bw = new BufferedWriter(new FileWriter(file))
bw.write(GROOVY_CODE)
bw.close()
Class gvy = classLoader.parseClass(file)
GroovyObject obj = (GroovyObject) gvy.getDeclaredConstructor().newInstance()
return Double.valueOf(obj.invokeMethod("getRate",inParameters)
}
}
And then, in the user-created custom groovy code:
class RateInterceptor {
def getRate(Object inParameters) {
def businessEntity = (SomeClass) inParameters
return businessEntity.getDiscount() == .5 ? .5 : null
}
}
The problem with this is that these "custom code" bits in GROOVY_CODE above, are pulled from a database during runtime, and contain an intricate groovy class. Since this method will be called numerous times in succession, it is impractical to create a new File object each time it is run.
Whether I use GroovyScriptEngine, or the GroovyClassLoader, these both involve the need of a java.io.File object. This makes the code execute extremely slowly, as the File will have to be created after the custom groovy code is retrieved from the database. Is there any way to run groovy code that can return a value without creating a temporary file to execute it?
The straight solution for your case would be using GroovyClassLoader.parseClass​(String text)
http://docs.groovy-lang.org/latest/html/api/groovy/lang/GroovyClassLoader.html#parseClass(java.lang.String)
The class caching should not be a problem because you are creating each time a new GroovyClassLoader
However think about using groovy scripts instead of classes
your rate interceptor code could be like this:
def businessEntity = (SomeClass) context
return businessEntity.getDiscount() == .5 ? .5 : null
or even like this:
context.getDiscount() == .5 ? .5 : null
in script you could declare functions, inner classes, etc
so, if you need the following script will work also:
class RateInterceptor {
def getRate(SomeClass businessEntity) {
return businessEntity.getDiscount() == .5 ? .5 : null
}
}
return new RateInterceptor().getRate(context)
The java code to execute those kind of scripts:
import groovy.lang.*;
...
GroovyShell gs = new GroovyShell();
Script script = gs.parse(GROOVY_CODE);
// bind variables
Binding binding = new Binding();
binding.setVariable("context", inParams);
script.setBinding(binding);
// run script
Object ret = script.run();
Note that parsing of groovy code (class or script) is a heavy operation. And if you need to speedup your code think about caching of parsed class into some in-memory cache or even into a map
Map<String, Class<groovy.lang.Script>>
Straight-forward would be also:
GroovyShell groovyShell = new GroovyShell()
Closure groovy = { String name, String code ->
String script = "{ Map params -> $code }"
groovyShell.evaluate( script, name ) as Closure
}
def closure = groovy( 'SomeName', 'params.someVal.toFloat() * 2' )
def res = closure someVal:21
assert 42.0f == res
I am prototyping an interface to our application to allow other people to use python, our application is written in java. I would like to pass some of our data from the java app to the python code but I am unsure how to pass an object to python. I have done a simple java->python function call using simple parameters using Jython and found it very useful for what I am trying to do. Given the class below, how can I then use it in Python/Jython as an input to a function/class:
public class TestObject
{
private double[] values;
private int length;
private int anotherVariable;
//getters, setters
}
One solution. You could use some sort of message system, queue, or broker of some sort to serialize/deserialize, or pass messages between python and java. Then create some sort workers/producer/consumers to put work on the queues to be processed in python, or java.
Also consider checking out for inspiration: https://www.py4j.org/
py4j is used heavily by/for pyspark and hadoop type stuff.
To answer your question more immediately.
Example using json-simple.:
import org.apache.commons.io.FileUtils;
import org.json.simple.JSONObject;
//import org.json.simple.JSONObject;
public class TestObject
{
private double[] values;
private int length;
private int anotherVariable;
private boolean someBool;
private String someString;
//getters, setters
public String toJSON() {
JSONObject obj=new JSONObject();
obj.put("values",new Double(this.values));
obj.put("length",new Integer(this.length));
obj.put("bool_val",new Boolean(this.SomeBool));
obj.put("string_key",this.someString);
StringWriter out = new StringWriter();
obj.writeJSONString(out);
return out.toString();
}
public void writeObject(){
Writer writer = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("anObject.json"), "utf-8")
)
)
writer.write(this.toJSON());
}
public static void setObject(){
values = 100.134;
length = 12;
anotherVariable = 15;
someString = "spam";
}
}
And in python:
class DoStuffWithObject(object):
def __init__(self,obj):
self.obj = obj
self.changeObj()
self.writeObj()
def changeObj(self):
self.obj['values'] = 100.134;
self.obj['length'] = 12;
self.obj['anotherVariable'] = 15;
self.obj['someString'] = "spam";
def writeObj(self):
''' write back to file '''
with open('anObject.json', 'w') as f:
json.dump(self.obj, f)
def someOtherMethod(self, s):
''' do something else '''
print('hello {}'.format(s))
import json
with open('anObject.json','r') as f:
obj = json.loads(f.read())
# print out obj['values'] obj['someBool'] ...
for key in obj:
print(key, obj[key])
aThing = DoStuffWithObject(obj)
aThing.someOtherMethod('there')
And then in java read back the object. There are solutions that exist implementing this idea (JSON-RPC, XML-RPC, and variants). Depending, you may may also want to consider using something like ( http://docs.mongodb.org/ecosystem/drivers/java/ ) the benefit being that mongo does json.
See:
https://spring.io/guides/gs/messaging-reactor/
http://spring.io/guides/gs/messaging-rabbitmq/
http://spring.io/guides/gs/scheduling-tasks/
Celery like Java projects
Jedis
RabbitMQ
ZeroMQ
A more comprehensive list of queues:
http://queues.io/
Resources referenced:
http://www.oracle.com/technetwork/articles/java/json-1973242.html
How do I create a file and write to it in Java?
https://code.google.com/p/json-simple/wiki/EncodingExamples
Agree with the answer below. I think that the bottom line is that "Python and Java are separate interpreter-environments." You therefore shouldn't expect to transfer "an object" from one to the other. You shouldn't expect to "call methods." But it is reasonable to pass data from one to another, by serializing and de-serializing it through some intermediate data format (e.g. JSON) as you would do with any other program.
In some environments, such as Microsoft Windows, it's possible that a technology like OLE (dot-Net) might be usable to allow environments to be linked-together "actively," where the various systems implement and provide OLE-objects. But I don't have any personal experience with whether, nor how, this might be done.
Therefore, the safest thing to do is to treat them as "records," and to use serialization techniques on both sides. (Or, if you got very adventurous, run (say) Java in a child-thread.) An "adventurous" design could get out-of-hand very quickly, with little return on investment.
You need to make the python file to exe using py2exe , Refer the link : https://www.youtube.com/watch?v=kyoGfnLm4LA. Then use the program in java and pass arguements:
Please refer this link it will be having the details:
Calling fortran90 exe program from java is not executing
This question already has answers here:
StringTemplate list of attributes defined for a given template
(2 answers)
Closed 4 years ago.
I'm attempting to use StringTemplate.v4 for simplistic templates, meaning only simple gaps names like %body%--I'm not using any other features, such as if-logic, sub-templates, or expressions.
(To be honest, it's API is poorly documented, and at this point I'm considering abandoning it completely. It would be nice if there were JavaDoc source code links, so at least I could dig around and figure things out myself. Really frustrated.)
I'm trying to determine the gaps that exist in an anonymous template, to verify it has the required gaps before attempting to use it.
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.compiler.FormalArgument;
public class GapsInAnST {
public static final void main(String[] ignored) {
ST tmpl = new ST("Hello %name%. You are %age% years old.", '%', '%');
Map<String,Object> gapMap = tmpl.getAttributes();
System.out.println("gapMap=" + gapMap);
if(gapMap != null) {
System.out.println("getAttributes()=" + Arrays.toString(gapMap.keySet().toArray()));
}
System.out.println("tmpl.impl.hasFormalArgs=" + tmpl.impl.hasFormalArgs);
Map<String,FormalArgument> formalArgMap = tmpl.impl.formalArguments;
if(formalArgMap != null) {
System.out.println("getAttributes()=" + Arrays.toString(formalArgMap.keySet().toArray()));
}
tmpl.add("name", "Seymour");
tmpl.add("age", "43");
System.out.println(tmpl.render());
}
}
Output:
gapMap=null
tmpl.impl.hasFormalArgs=false
Hello Seymour. You are 43 years old.
I found out why getAttributes() returns null in this google groups thread, and about formalArguments in this question: StringTemplate list of attributes defined for a given template).
So how do I get all gaps actually existing in an anonymous template before filling any gaps? I realize I could do it with regex, but I am hoping there is a built in way of doing this.
Thanks.
I've decided to give up on StringTemplate4. In fact, I just rolled my own, as pretty much all the "lightweight" Java templating solutions all have advanced features (like looping, expressions, logic, template "groups"), and I don't want any of it. I just want gaps (Hi %name%).
It's called Template Featherweight (GitHub link).
Here are two examples:
First, a basic use that renders the completely filled template into a string:
import com.github.aliteralmind.templatefeather.FeatherTemplate;
public class HelloFeather {
public static final void main(String[] ignored) {
String origText = "Hello %name%. I like you, %name%, %pct_num%__PCT__ guaranteed.";
String rendered = (new FeatherTemplate(origText,
null)). //debug on=System.out, off=null
fill("name", "Ralph").
fill("pct_num", 45).
getFilled();
System.out.println(rendered);
}
}
Output:
Hello Ralph. I like you, Ralph, 45% guaranteed.
The second example demonstrates "auto-rendering", which renders the template as its filled, into something other than a string, such as a file or stream--or anything you can wrap into an Appendable:
import com.github.aliteralmind.templatefeather.FeatherTemplate;
public class FeatherAutoRenderDemo {
public static final void main(String[] ignored) {
String origText = "Hello %name%. I like you, %name%, %pct_num%__PCT__ guaranteed.";
FeatherTemplate tmpl = new FeatherTemplate(origText,
null); //debug on=System.out, off=null
tmpl.setAutoRenderer(System.out);
System.out.println("<--Auto renderer set.");
tmpl.fill("name", "Ralph");
System.out.println("<--Filled first gap");
tmpl.fill("pct_num", 45);
System.out.println("<--Filled second-and-final gap");
}
}
Output:
Hello <--Auto renderer set.
Ralph. I like you, Ralph, <--Filled first gap
45% guaranteed.<--Filled second-and-final gap
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
On-the-fly, in-memory java code compilation for Java 5 and Java 6
Compiling Java file with code from within a Java file
i have a hello world class available in the string of a program as given in the example below,
public class CompileJavaString {
public static void main(String arg[]) {
String s="public class HelloWorld{ public static void main(String arg[]) ";
s=s+" { System.out.println(\"Hello World\"); } } ";
// this is the complete code of Hello World class taken as an example
// code to compile the class Hello World available in string and
// generate the HelloWorld.class file required here
}
}
can someone help to compile the code in a memory string available in example given above
You want to have a look at javax.tools.JavaCompiler and related classes.
The documentation contains examples of how to use them.
Note that the java compiler will only work if you have a JDK installed. A JRE is not enough.
Save as HelloWorld.java and do following:
String fileToCompile = "HelloWorld.java";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int compilationResult = compiler.run(null, null, null, fileToCompile);
if(compilationResult == 0){
System.out.println("Compilation is successful");
}else{
System.out.println("Compilation Failed");
}
Edit
Can have a look at detailed example :
http://www.java2s.com/Code/Java/JDK-6/CompilingfromMemory.htm
I have 3 questions regarding using Groovy in java. They are all related together so I'm only creating one question here.
1) There are: GroovyClassLoader, GroovyShell, GroovyScriptEngine. But what is the difference between using them?
For example for this code:
static void runWithGroovyShell() throws Exception {
new GroovyShell().parse(new File("test.groovy")).invokeMethod("hello_world", null);
}
static void runWithGroovyClassLoader() throws Exception {
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 {
Class scriptClass = new GroovyScriptEngine(".").loadScriptByName("test.groovy");
Object scriptInstance = scriptClass.newInstance();
scriptClass.getDeclaredMethod("hello_world", new Class[]{}).invoke(scriptInstance, new Object[]{});
}
2) What is the best way to load groovy script so it remains in memory in compiled form, and then I can call a function in that script when I need to.
3) How do I expose my java methods/classes to groovy script so that it can call them when needed?
Methods 2 and 3 both return the parsed class in return. So you can use a map to keep them in memory once they are parsed and successfully loaded.
Class scriptClass = new GroovyClassLoader().parseClass(new File("test.groovy"));
map.put("test.groovy",scriptClass);
UPDATE:
GroovyObject link to the groovy object docs.
Also this is possible to cast the object directly as GroovyObject and other java classes are indistinguishable.
Object aScript = clazz.newInstance();
MyInterface myObject = (MyInterface) aScript;
myObject.interfaceMethod();
//now here you can also cache the object if you want to
Cannot comment on efficiency. But I guess if you keep the loaded classes in memory, one time parsing would not hurt much.
UPDATE For efficiency:
You should use GroovyScriptEngine, it uses script caching internally.
Here is the link: Groovy Script Engine
Otherwise you can always test it using some performance benchmarks yourself and you would get rough idea. For example: Compiling groovy scripts with all three methods in three different loops and see which performs better. Try using same and different scripts, to see if caching kicks in, in some way.
UPDATE FOR PASSING PARAMS TO AND FROM SCRIPT
Binding class will help you sending the params to and from the script.
Example Link
// setup binding
def binding = new Binding()
binding.a = 1
binding.setVariable('b', 2)
binding.c = 3
println binding.variables
// setup to capture standard out
def content = new StringWriter()
binding.out = new PrintWriter(content)
// evaluate the script
def ret = new GroovyShell(binding).evaluate('''
def c = 9
println 'a='+a
println 'b='+b
println 'c='+c
retVal = a+b+c
a=3
b=2
c=1
''')
// validate the values
assert binding.a == 3
assert binding.getVariable('b') == 2
assert binding.c == 3 // binding does NOT apply to def'd variable
assert binding.retVal == 12 // local def of c applied NOT the binding!
println 'retVal='+binding.retVal
println binding.variables
println content.toString()