I'm trying to extend the example from this tutorial by sending Python objects to Java. While the example code which exchanges String objects between Python and Java works fine, when I try to replace it with my own Python object (Event), an error regarding object_id is displayed.
Python Code:
class Event(object):
#some content here
stack = gateway.entry_point.getStack()
event = Event()
stack.push(event)
Error:
Traceback (most recent call last):
File "/home/******/src/py4jSample.py", line 19, in <module>
stack.push(event)
File "/usr/local/lib/python2.7/dist-packages/py4j-0.7-py2.7.egg/py4j/java_gateway.py", line 423, in __call__
[get_command_part(arg, self.pool) for arg in new_args])
File "/usr/local/lib/python2.7/dist-packages/py4j-0.7-py2.7.egg/py4j/protocol.py", line 241, in get_command_part
command_part = REFERENCE_TYPE + parameter._get_object_id()
AttributeError: 'Event' object has no attribute '_get_object_id'
Any idea how this can be solved?
the problem is that you cannot send pure Python objects to the Java side (in this case, calling push actually calls the Java method "Stack.push"). You can only send (1) objects that can be automatically converted to Java objects (primitives such as int, byte array, strings), (2) objects received from Java such as "stack", or (3) Python objects implementing a Java interface:
class Event(object):
def myMethod(param1, param2):
return "foo"
class Java:
implements = ['yourpackage.IEvent']
If you want to send Python objects implementing a Java interface, you need to accept incoming connections from the Python interpreter (the JVM will call back the Python interpreter if a Python method is called):
gateway = JavaGateway(start_callback_server=True)
stack = gateway.entry_point.getStack()
event = Event()
stack.push(event)
Related
I need to write an application for a client that calls a method from a ".dll" file. The ".dll" file was previously executed manually from an ".exe" GUI but now they want to automate the process.
I never worked with .dll files so everything that I found until now is the result of a complete day of research, I also received a small documentation with this tool:
The interface is an ActiveX DLL which provides two functions (GetUnitInfo and SaveResult).
In the moment I just want to run the "GetUnitInfo" method from the Winwdows command line using RUNDLL32.exe.
This is the documentation for the "GetUnitInfo" method:
The interface for GetUnitInfo is as follows:
Public Function GetUnitInfo( _
ByVal strRequest As String, _
ByRef strUnitInfo As String,
Optional ByVal strStationName As String = "") As Long
Sample calling code can be:
Dim lRet As Long
Dim strXML as String
lRet = GetUnitInfo( _“<?xml version=""1.0"" ?><GetUnitInfo
xmlns=""urn:GetUnitInfo-schema"" SerialNumber=""BD3ZZTC8MA"" />", strXML)
So I tried to run this method with some dummy parameters because the method returns an error if the parameters are not OK. The command:
RUNDLL32.EXE FFTester.dll, GetUnitInfo test1, test2
But I receive this error:
I used "Dependency Walker" to list the functions from the dll file:
But this are all the functions, normally I would expected that also "GetUnitInfo" is listed.
Can somebody help? It is not mandatory to use RUNDLL32.
Later edit:
I want to call this DLL from a tool that is written in JAVA, I tried to use JNA but I failed so I was thinking to call the dll functions from the command line because if this works I can use a process builder to execute the command.
I fixed my problem and I will provide a solution, maybe it will help someone else.
I used com4j library to generate the interfaces for my dll. After this you need to register your DLL otherwise most problely your code will throw an "ComException", you can read more in my second question.
To register a DLL:
C:\Windows\SysWOW64>regsvr32.exe "path to your DLL" for 32 bit DLL
Or
C:\Windows\System32>regsvr32.exe "path to your DLL" for 64 bit DLL
Also depending on your DLL type, 32 or 64 bit, you need to use proper Eclipse/JDK.
I have a java class I am using in my jruby project and in ruby I can set a value to an object via the send method. I am doing the same in jruby but using the java_send method instead. However, when I try using this I get the following error TypeError: can't convert Java::JavaIo::File into Array from org/jruby/java/proxies/JavaProxy.java:321:in 'java_send'
I have a java instance and I need to call the object via a symbol. Below is what I am doing in the code:
OUTPUT_FILES = [:make, :model]
javaArgs = javaArgs.new
OUTPUT_FILES.each do |filename|
file = java.io.File.new(path, "#{filename.to_s.underscore}.csv")
file.createNewFile
javaArgs.java_send(filename, file)
end
and just to make sure when I do javaArgs.make = file it works without any problems.
java_send expects its arguments passed as an array: javaArgs.java_send filename, [ file ]
I embed jruby script engine into my java program by using javax.script.ScriptEngineManager
I made some jruby code that end with do ~ end block,
after running all code, NullPointerException occured.
but code ends with any other statement, no exception occurs.
version : 1.7.19
Caused by: java.lang.NullPointerException
at org.jruby.embed.variable.Argv.updateARGV(Argv.java:169)
at org.jruby.embed.variable.Argv.retrieve(Argv.java:158)
at org.jruby.embed.variable.VariableInterceptor.retrieve(VariableInterceptor.java:154)
at org.jruby.embed.internal.BiVariableMap.retrieve(BiVariableMap.java:378)
at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:124)
in ARGV.java updateARGV
if (vars.containsKey((Object)name)) {
var = vars.getVariable((RubyObject)receiver.getRuntime().getTopSelf(), name);
var.setRubyObject(argv);
vars.getVariable returned null because of isReceiverIdentical return false
in BiVariableMap.java
if (var.isReceiverIdentical(receiver)) {
return var;
}
In isReceiverIdentical, this method just compare receiver with BiVariable's receiver usgin '=='.
Is this jruby bug? Or do I have to do something for this?
If you need more information about this problem, plz comment it!
I got ScriptEngine(engine) from ScriptEngineManager and set some java instance and method like this
engine.put("this", console);
engine.eval("$command = $this.java_method :command, [java.lang.String]");
here is my test ruby code. result and tab is java object
that has some method return String and list.
result = $command.call "something to pass"
puts result.getMessage
tabular = result.getData
tabular.each do |tab|
rows = tab.getRows
rows.each do |row|
puts row
end
puts tab.getColumnNames
end
I had created ruby type object in my java code by creating new Ruby object...
This causes checking fail in updateARGV because a receiver that register variable in BiVariableMap and another receiver that update variable are different.
So, I got a Ruby object from new ScriptingContainer(from it we can always get a same Ruby object if local context is singleton) and used it to create new ruby type object in my java code.
Reference: https://github.com/jruby/jruby/wiki/RedBridge#Singleton
I have a simple python script in my local machine, which returns a string. I want to run this script from java application and get the return value. I'm trying to do this using Pyrolite. I downloaded the jar files and added them to my java class path. But I'm not able to run the script.
I got the below sample code from readme.txt
NameServerProxy ns = NameServerProxy.locateNS(null);
PyroProxy remoteobject = new PyroProxy(ns.lookup("Your.Pyro.Object"));
Object result = remoteobject.call("pythonmethod", 42, "hello", new int[]{1,2,3});
String message = (String)result; // cast to the type that 'pythonmethod' returns
System.out.println("result message="+message);
remoteobject.close();
ns.close();
But this is not working for me. My system configuration is
OS: Windows 8
JDK: jdk1.7.0_51
Python: 2.6
Please help me with this.
This is how I have edited the code:
NameServerProxy ns = NameServerProxy.locateNS(null);
PyroProxy remoteobject = new PyroProxy();
Object result = remoteobject.call("C:\\trail1.py", null);
String message = (String)result; // cast to the type that 'pythonmethod' returns
System.out.println("result message="+message);
remoteobject.close();
ns.close();
I'm not positive that I understand what you're trying to do.
If you carefully read the tutorial, you'll see that you can't use Pyrolite the way you are. It specifies that you must have a python script running as a server, WITH a name server, where you must define some classes (for example Your.Pyro.Object).
Then you'll be able to call those objects you defined in that python script, but not the script itself.
To do what you want to do you'll need to call a function like C's fork(). Then you're able to call an executable, and you don't need Pyrolite.
Please forgive me, as I am a Java man dabbling in Javascript business :)
I wanted to be able to define a set of integration test cases to be easy to script against a Java application. I thought Javascript would be a perfect language to script against. To that end, I am using the Rhino engine that comes with JDK 7, via Java's Scripting API. The scripts would have access to Java classes already defined in the application, and could be reused to define use case scenarios for integration testing.
In the Java application, I have binded the javascript engine itself to the script as jsengine, so that I can load javascript files (Including a JavaScript file during Rhino eval).
I have two Javascript files, as defined below:
Function.js:
function send(msg) {
send.sendMessage(msg);
}
TestCase.js
jsengine.eval(new java.io.FileReader("Function.js");
sendMsg("Test Message");
I also have the following object defined and binded to the script as "javaobj":
public class TestConnection {
...
public void send(String message) {
// Code to send the string message via JMS
}
}
However, the Rhino engine complains with the following Exception. It seems to not like calling the javaobj's send method, for some reason.
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot find function send in object
function sendMsg(msg) {...}. (TestCase.js#3) in TestCase.js at line number 3
at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:224)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:212)
at com.foo.test.scenario.JavaScriptEngine.execute(JavaScriptEngine.java:56)
at com.foo.test.TestSuite.start(TestSuite.java:88)
at com.foo.test.TestSuite.main(TestSuite.java:41)
Caused by: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot find function send in object
function sendMsg(msg) {...}. (TestCase.js#3) in TestCase.js at line number 3
at sun.org.mozilla.javascript.internal.ScriptRuntime.constructError(ScriptRuntime.java:3773)
at sun.org.mozilla.javascript.internal.ScriptRuntime.constructError(ScriptRuntime.java:3751)
at sun.org.mozilla.javascript.internal.ScriptRuntime.typeError(ScriptRuntime.java:3779)
at sun.org.mozilla.javascript.internal.ScriptRuntime.typeError2(ScriptRuntime.java:3798)
at sun.org.mozilla.javascript.internal.ScriptRuntime.notFunctionError(ScriptRuntime.java:3869)
at sun.org.mozilla.javascript.internal.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2345)
at sun.org.mozilla.javascript.internal.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2312)
at sun.org.mozilla.javascript.internal.Interpreter.interpretLoop(Interpreter.java:1524)
at sun.org.mozilla.javascript.internal.Interpreter.interpret(Interpreter.java:854)
at sun.org.mozilla.javascript.internal.InterpretedFunction.call(InterpretedFunction.java:164)
at sun.org.mozilla.javascript.internal.ContextFactory.doTopCall(ContextFactory.java:429)
at com.sun.script.javascript.RhinoScriptEngine$1.superDoTopCall(RhinoScriptEngine.java:116)
at com.sun.script.javascript.RhinoScriptEngine$1.doTopCall(RhinoScriptEngine.java:109)
at sun.org.mozilla.javascript.internal.ScriptRuntime.doTopCall(ScriptRuntime.java:3163)
at sun.org.mozilla.javascript.internal.InterpretedFunction.exec(InterpretedFunction.java:175)
at sun.org.mozilla.javascript.internal.Context.evaluateReader(Context.java:1159)
at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:214)
... 4 more
Has anyone ever encountered this type of issue with Rhino?
P.S. This question seems related, but no answer given as well (TypeError in Rhino: migration from Java 6 to Java 7)
Looks like I found my own answer. There was a name conflict between the Javascript function and the name of the binded Java object. Both having the same name, the engine tries to call a non-existent method on a Function object!
Silly me... :P