I want to call java from python with Py4J library,
from py4j.java_gateway import JavaGateway
gateway = JavaGateway() # connect to the JVM
gateway.jvm.java.lang.System.out.println('Hello World!')
I've got the following error: "Py4JNetworkError: An error occurred while trying to connect to the Java server". It's seems that no JVM is running, how to fix that?
Minimal working example:
//AdditionApplication.java
import py4j.GatewayServer;
public class AdditionApplication {
public static void main(String[] args) {
AdditionApplication app = new AdditionApplication();
// app is now the gateway.entry_point
GatewayServer server = new GatewayServer(app);
server.start();
}
}
Compile (make sure that the -cp path to the py4j is valid, otherwise adjust it such that it points to the right place):
javac -cp /usr/local/share/py4j/py4j0.9.jar AdditionApplication.java
Run it:
java -cp .:/usr/local/share/py4j/py4j0.9.jar AdditionApplication
Now, if you run your python script, in the terminal where the java AdditionApplication is running you should see something like:
>>> Hello World!
package test.test;
import py4j.GatewayServer;
public class AdditionApplication {
public int addition(int first, int second) {
return first + second;
}
public static void main(String[] args) {
AdditionApplication app = new AdditionApplication();
// app is now the gateway.entry_point
GatewayServer server = new GatewayServer(app);
server.start();
}
}
create a new class and run it(import py4j0.8.jar at 'py4j-0.8\py4j-0.8\py4j-java' first),then run python program
You should first start the java program, and then invoke java method from python.
py4j doesn't start jvm, it just connects to the already started java process.
Related
I am using py4j for communication between python and java.I am able to call python method from java side. But from python I am not able to send any object or call java method. Here is the code i have tried.
My java code:
public interface IHello {
public String sayHello();
public String sayHello(int i, String s);
// public String frompython();
}
//ExampleClientApplication.java
package py4j.examples;
import py4j.GatewayServer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ExampleClientApplication extends Thread {
public void run(){
System.out.println("thread is running...");
}
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
GatewayServer.turnLoggingOff();
GatewayServer server = new GatewayServer();
server.start();
IHello hello = (IHello) server.getPythonServerEntryPoint(new Class[] { IHello.class });
try {
System.out.println("Please enter a string");
String str = br.readLine();
System.out.println(hello.sayHello(1, str));
} catch (Exception e) {
e.printStackTrace();
}
ExampleClientApplication t1 = new ExampleClientApplication();
t1.start();
//server.shutdown();
}
}
My python code :
class SimpleHello(object):
def sayHello(self, int_value=None, string_value=None):
print(int_value, string_value)
return "From python to {0}".format(string_value)
class Java:
implements = ["py4j.examples.IHello"]
# Make sure that the python code is started first.
# Then execute: java -cp py4j.jar
py4j.examples.SingleThreadClientApplication
from py4j.java_gateway import JavaGateway, CallbackServerParameters
simple_hello = SimpleHello()
gateway = JavaGateway(
callback_server_parameters=CallbackServerParameters(),
python_server_entry_point=simple_hello)
The send objects problem is easily solved by implementing a getter/eval method in the java interface that is implemented by python, which can then be called from java to get the variable that is requested. For an example have a look at the py4j implementation here: https://github.com/subes/invesdwin-context-python
Specifically see the get/eval method implementation here: https://github.com/subes/invesdwin-context-python/blob/master/invesdwin-context-python-parent/invesdwin-context-python-runtime-py4j/src/main/java/de/invesdwin/context/python/runtime/py4j/pool/internal/Py4jInterpreter.py
For the other way around, you would have to do same on the java gateway class and provide a get/eval method that can be called from python. The actual java code could be executed in a ScriptEngine for groovy and the result could be returned to python. (see http://docs.groovy-lang.org/1.8.9/html/groovy-jdk/javax/script/ScriptEngine.html)
Though it might be a better idea to decide about a master/slave role and only once input the parameters, then execute the code in python and retrieve the results once. Or the other way around if python should be leading. Thus you would reduce the communication overhead a lot. For a tighter integration without as much of a performance penalty as py4j incurs, you should have a look at https://github.com/mrj0/jep to directly load the python lib into the java process. Then each call is not as expensive anymore.
I am learning how to use ProcessBuilder, I created a package called socketspractice, inside I have 2 classes, I am trying to create a new process where 'Program.java' calls 'test1.java' so it prints 'test1'.
When I use command prompt: "java socketspractice.test1" 'test1' prints, but using Netbeans it doesn't.
The question is, how can I set the path so it works the same way or what else am I missing? I am using Netbeans for this.
Program.java
package socketspractice;
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder;
public class Program {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder builderExecute = new ProcessBuilder("java", "socketspractice.test1");
builderExecute.start();
}
}
AND
test1.java
package socketspractice;
public class test1 {
public static void main(String[] args) {
// TODO code application logic here
System.out.println("test1");
}
}
The main issue with ur approach is that when you are starting ProcessBuilder it doesnt know where ur project lies on your machine, because its running as a seperate JVM process.
So please create you project as a maven project and then try to put the compiled jar in classpath and then start the process builder.
ProcessBuilder pb = new ProcessBuilder("java","-classpath",
"<complete location of your jar containing test1>", "socketspractice.test1")
I am trying to run a java file from php through shell_exec . It works for simple jar files i.e. jar files with single class. Out of the below 2 commands the first one works fine. The second one consists of a package with two class , so to call particular class from it , I followed this calling procedure. Both the commands works fine in terminal. But the second command fails in shell_exec.
<?php
echo shell_exec("java -jar First.jar hi php");
echo shell_exec("java -cp samlePackage.jar:. samplePackage.Test");
?>
Here is First.class
class First
{
public static void main(String args[])
{
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println("hello");
}
}
And here are the samplePackage classes
package samplePackage;
public class Hello
{
public void sayHello()
{
System.out.println("Hello");
}
}
package samplePackage;
public class Test
{
public static void main(String args[])
{
Hello obj = new Hello();
obj.sayHello();
}
}
I am not able to figure out my mistake. Please help.
Thanks in advance.
This question already has answers here:
How to open the command prompt and insert commands using Java?
(9 answers)
Closed 9 years ago.
I have 2 classes one is a simple one
Sample.java
public class Sample {
public static void main(String args[]) {
System.out.println("Hello World!!!!!");
}
}
Other one is something like this
Main.java
public class Main
{
public static void main(String[] args) throws Exception
{
Runtime.getRuntime().exec("java Sample");
}
}
I am basically trying to run the Main.java program to call Sample.java in a new command prompt...that is a new cmd that should open and print the output of Sample.java...how should I do this...???
Compile the two together, and then from Sample,
Main.main(args);
will do the trick. You don't need to import since you're in the same package.
Note the linked tutorial.
http://docs.oracle.com/javase/tutorial/java/package/index.html
Runtime.getRuntime().exec("cmd /c start cmd.exe /K \"cd <where_the_Sample_is> && javac Sample.java && java Sample\"");
or if the class is already compiled:
Runtime.getRuntime().exec("cmd /c start cmd.exe /K \"cd <where_the_Sample_is> && java Sample\"");
I am using eclipse. The class files are placed in the bin directory located under the projects directory. The below code starts command prompt, changes directory to bin and issues java Sample command. You can edit it up to your requirement.
Runtime.getRuntime().exec("cmd.exe /c cd \"bin\" & start cmd.exe /k \"java Sample\"");
You can use this code:
public class Main {
public static void main(String[] args) throws Exception {
Class<Sample> clazz = Sample.class;
Method mainMethod = clazz.getMethod("main", String[].class);
String[] params = null;
mainMethod.invoke(null, (Object) params);
}
}
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");
}
}