Calling python module from Java - java

I want to call a function from a python module from Java using "PythonInterpreter" and here's my Java code
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("import sys\nsys.path.append('C:\\Python27\\Lib\\site-packages')\nimport helloworld");
PyObject someFunc = interpreter.get("helloworld.getName");
PyObject result = someFunc.__call__();
String realResult = (String) result.__tojava__(String.class);
System.out.println(realResult);
and the Python code (helloworld.py) is below:
from faker import Factory
fake = Factory.create()
def getName():
name = fake.name()
return name
The problem I'm facing is while I'm calling interpreter.get when it returns a null PyObject.
Any idea what's going wrong? The python code runs fine from IDLE
EDIT
I just did a bit of change in the code as below
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("import sys\nsys.path.append('C:\\Python27\\Lib\\site-packages')\nimport helloworld");
PyInstance wrapper = (PyInstance)interpreter.eval("helloworld" + "(" + ")");
PyObject result = wrapper.invoke("getName()");
String realResult = (String) result.__tojava__(String.class);
System.out.println(realResult);
and I introduced a class in my python module
from faker import Factory
class helloworld:
def init(self):
fake = Factory.create()
def getName():
name = fake.name()
return name
Now am getting the error below
Exception in thread "main" Traceback (innermost last):
File "<string>", line 1, in ?
TypeError: call of non-function (java package 'helloworld')

You cannot use python attribute access in PythonInterpreter.get. Just use attribute name to get the module, and retrieve attribute from it.
(EDIT PART) Python code is totally broken. Please see the proper example below. And, of course, www.python.org.
(EDIT PART) First parameter of PyInstance.invoke should be method name.
Below you can find working code sample for both cases
Main.java
import org.python.core.*;
import org.python.util.PythonInterpreter;
public class Main {
public static void main(String[] args) {
test1();
test2();
}
private static void test1() {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("import hello_world1");
PyObject func = interpreter.get("hello_world1").__getattr__("get_name");
System.out.println(func.__call__().__tojava__(String.class));
}
private static void test2() {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("from hello_world2 import HelloWorld");
PyInstance obj = (PyInstance)interpreter.eval("HelloWorld()");
System.out.println(obj.invoke("get_name").__tojava__(String.class));
}
}
hello_world1.py
def get_name():
return "world"
hello_world2.py
class HelloWorld:
def __init__(self):
self.world = "world"
def get_name(self):
return self.world

Related

Jython - Calling Python Class in Java

I want to call my Python class in Java, but I get the error message:
Manifest
com.atlassian.tutorial:myConfluenceMacro:atlassian-plugin:1.0.0-SNAPSHOT
: Classes found in the wrong directory
I installed Jython on my pc via jar. And added it in my pom (because I am using a Maven Project). What am I doing wrong? How can I call a python method inside my java class?
I am using python3.
POM
<!-- https://mvnrepository.com/artifact/org.python/jython-standalone -->
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.1</version>
</dependency>
JAVA CLASS
package com.atlassian.tutorial.javapy;
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
class Hello:
__gui = None
def __init__(self, gui):
self.__gui = gui
def run(self):
print ('Hello world!')
Thank you!
You have wrong indentation in your Python class. Correct code is:
class Hello:
__gui = None
def __init__(self, gui):
self.__gui = gui
def run(self):
print ('Hello world!')
so that __init__() and run() are methods of your Hello class, not global functions. Otherwise your code works nicely.
And please remember that the latest version of Jython is 2.7.1 - it is not Python3 compatible.

ImportError: No Module named demiso in Jython

I'm new to the Jython and I'm trying to run a python class using Jython in Java. But I'm running into some issues.
The Java class that I've defined:
public class DemistoCalls {
PythonInterpreter interpreter = null;
public DemistoCalls()
{
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[] args) {
DemistoCalls demistoCalls = new DemistoCalls();
demistoCalls.execfile("C:\\Users\\AlokNath\\Desktop\\Demisto_Project\\demisto-py-master\\demisto\\SimpleConnect.py");
}
}
The SampleConnect.py file that I'm trying to run:
import sys
sys.path.append("C:\Users\AlokNath\Desktop\Demisto_Project\demisto-py-
master\demisto")
import demisto
While Running the java file, I'm getting this error:
File "C:\Users\AlokNath\Desktop\Demisto_Project\demisto-py-master\demisto\SimpleConnect.py", line 3, in <module>
import demisto
ImportError: No module named demisto
Although I've defined the "demisto" module in the system path and checked that the system path in python contains the appropriate path to Jython 2.7.lb2 Library. I'm not sure where am I going wrong. Any help is appreciated.
Regards,
Alok
I found a solution to the import error problem. We need to copy the missing module to the “site-packages” folder under "modeler-installation/lib/jython/Lib". This will resolve the dependency problem.

RJB Hello World Example

I am trying to call a function from a java class in my Ruby on Rails project using RJB (Ruby Java Bridge).
The Java class is
public class HelloWorld {
int fifty(){
return 50 ;
}
public static void main(String[] args) {
// Prints "Hello, World" in the terminal window.
System.out.println("Hello, World");
}
}
and in the controller I have
require "rjb"
def home
myclass = Rjb::load(classpath ='\\home\\mennatallah\\TopicalClusteringofTweets\\lib\\java_libs\\helloworld.class', jvmargs=[])
myclass_instance = myclass.new
#output = myclass_instance.fifty
end
It gives " undefined method `new' for nil:NilClass "
How can I do this ?
you can try the following. it might help:
Rjb::add_jar( Dir.glob("#{Rails.root}/lib/java_libs/*.jar").join(':'))
Rjb::load(Dir.glob("#{Rails.root}/lib/java_libs/*.jar").join(':'))
test = Rjb.import('HelloWorld')
instance_class = test.new

groovy win cmd line class and script

I'm trying to run a groovy(2.4.3) script on windows that calls a goovy class xxxxx.groovy. I've tried a number of variations using classpath and various scripts, some examples below, always getting MultipleCompliationErrorsException.... unable to resolve class
classfile is firstclass.groovy
import org.apache.commons.io.FilenameUtils
class firstclassstart {
def wluid, wlpwd, wlserver, port
private wlconnection, connectString, jmxConnector, Filpath, Filpass, Filname, OSRPDpath, Passphrase
// object constructor
firstclassstart(wluid, wlpwd, wlserver, port) {
this.wluid = wluid
this.wlpwd = wlpwd
this.wlserver = wlserver
this.port = port
}
def isFile(Filpath) {
// Create a File object representing the folder 'A/B'
def folder = new File(Filpath)
if (!org.apache.commons.io.FilenameUtils.isExtension(Filpath, "txt")) {
println "bad extension"
return false
} else if (!folder.exists()) {
// Create all folders up-to and including B
println " path is wrong"
return false
} else
println "file found"
return true
}
}
cmd line script test.groovy
import firstclass
def sample = new firstclass.firstclassstart("weblogic", "Admin123", "x.com", "7002")
//def sample = new firstclassstart("weblogic", "Admin123", "x.com", "7002")
sample.isFile("./firstclass.groovy")
..\groovy -cp "firstclass.groovy;commons-io-1.3.2.jar" testfc.groovy
script test.groovy
GroovyShell shell = new GroovyShell()
def script = shell.parse(new File('mylib/firstclass.groovy'))
firstclass sample = new script.firstclass("uid", "pwd", "url", "port")
sample.getstatus()
c:>groovy test.groovy
script test.groovy v2 put firstclass.groovy in directory test below script
import test.firstclass
firstclass sample = new script.firstclass("uid", "pwd", "url", "port")
sample.getstatus()
c:>groovy test.groovy
just looking for a bullet proof, portable way to oranize my java classes, .groovy classess, etc. and scripts.
Thanks
I think that you can do using for example your first approach:
groovy -cp mylib/firstclass.groovy mylib/test.groovy
However I see some problems in your code which are probably causing MultipleCompliationErrorsException.
Since you're including firstclass.groovy in your classpath, you've to add the import firstclass in the test.groovy.
Why are you using script.firstclass in test.groovy? you're class is called simply firstclass.
In your firstclass.groovy you're using import org.apache.commons.io.FilenameUtils and probably other, however you're not including it in the classpath.
So finally I think that, you've to change your test.groovy for something like:
import firstclass
firstclass sample = new firstclass("uid", "pwd", "url", "port")
sample.getstatus()
And in your command add the remaining includes for apache Commons IO to the classpath.
groovy -cp "mylib/firstclass.groovy;commons-io-2.4.jar;" mylib/testexe.groovy
Hope this helps,
UPDATE BASED ON OP CHANGES:
After the changes you've some things wrong, I try to enumerate it:
If your file is called firstclass.groovy your class must be class firstclass not class firstclassstart.
In your test.groovy use new firstclass not new firstclass.firstclassstart.
So the thing is, your code must be:
class file firstclass.groovy:
import org.apache.commons.io.FilenameUtils
class firstclass {
def wluid, wlpwd, wlserver, port
private wlconnection, connectString, jmxConnector, Filpath, Filpass, Filname, OSRPDpath, Passphrase
// object constructor
firstclass(wluid, wlpwd, wlserver, port) {
this.wluid = wluid
this.wlpwd = wlpwd
this.wlserver = wlserver
this.port = port
}
def isFile(Filpath) {
// Create a File object representing the folder 'A/B'
def folder = new File(Filpath)
if (!org.apache.commons.io.FilenameUtils.isExtension(Filpath, "txt")) {
println "bad extension"
return false
} else if (!folder.exists()) {
// Create all folders up-to and including B
println " path is wrong"
return false
} else
println "file found"
return true
}
}
script test.groovy:
import firstclass
def sample = new firstclass("weblogic", "Admin123", "x.com", "7002")
sample.isFile("./firstclass.groovy")
Finally the command to execute it:
groovy -cp "firstclass.groovy;commons-io-1.3.2.jar" test.groovy
With this changes your code must works, I try it and works as expected.

Groovy sandbox and Java: execute Groovy script

Task: execute groovy script with Groovy sandbox:
http://groovy.codehaus.org/api/overview-summary.html
http://groovy-sandbox.kohsuke.org/
Groovy Script to execute:
query.reverse(); // QUERY is a some string that should be reversed
File "GroovyScriptSandbox.groovy" should get two parameters(script and values for this script):
package test.my.groovy.sandbox
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.ImportCustomizer
import org.codehaus.groovy.control.customizers.SecureASTCustomizer
import org.springframework.stereotype.Component
#Component
class GroovyScriptSandbox {
def config
def shell
public String runScript(final String script, final String query) {
final ImportCustomizer imports = new ImportCustomizer()
.addStarImports('groovyx.net.http')
.addStaticStars('groovyx.net.http.ContentType', 'groovyx.net.http.Method')
config = new CompilerConfiguration()
config.addCompilationCustomizers(imports)
def newScript = "{ query -> " + script + "}"
shell = new GroovyShell(config)
def clos = shell.evaluate(newScript)
return clos.call(query)
}
}
Java method that executes "GroovyScriptSandbox.groovy":
#Resource
private GroovyScriptSandbox groovyScriptSandbox;
#RequestMapping(value = "/run", method = RequestMethod.POST)
#ResponseBody
public String runScript(#RequestParam("script") final String script,
#RequestParam("query") final String query) {
return groovyScriptSandbox.runScript(script, query);
}
In that case all works fine:
Java controller getting script parameter equal "query.reverse()" and query parameter equals "0123"
Groovy file executes script "query.reverse()" in sandbox where query equals "0123"
Result equals "3210"
Question:
I'm trying to replace "GroovyScriptSandbox.groovy" file with "GroovyScriptSandbox.java" and I don't know how to write the same groovy code in Java.
Finally found solution:
public String scriptRunner(final String script, final String query) {
final ImportCustomizer imports = new ImportCustomizer();
imports.addStaticStars("java.lang.Math");
imports.addStarImports("groovyx.net.http");
imports.addStaticStars("groovyx.net.http.ContentType", "groovyx.net.http.Method");
final SecureASTCustomizer secure = new SecureASTCustomizer();
secure.setClosuresAllowed(true);
final CompilerConfiguration config = new CompilerConfiguration();
config.addCompilationCustomizers(imports, secure);
final Binding intBinding = new Binding(); // alow parameters in the script
intBinding.setVariable("query", query);
final GroovyShell shell = new GroovyShell(intBinding, config); // create shall
// code execution
final Object clos = shell.evaluate(script);
if (clos == null) {
return "No result avalible!";
}
return clos.toString();
}

Categories

Resources