We are able to call java in C# code and able to pass Strings and integers as method parameters. Able to access Strings are integers directly by using java java.lang.String and java.lang.Integer with out issues.
But when we pass C# custom object as method parameter we could not find a way to access it.
Eg: Employee.cs is the C# class with parameter name.
Used proxygen to create EmployeeLibraray.dll, EmployeeLibraray.j4n.dll and EmployeeLibraray.j4n.
C# code where we are trying to pass C# object
var bs = new BridgeSetup();
bs.AddAllJarsClassPath("./");
Bridge.CreateJVM(bs);
Bridge.RegisterAssembly(typeof(JavaTest).Assembly);
JavaTest obj = new JavaTest(); ================================> JavaTest
is the class generated using proxygen where it is called in C#
EmployeeLibraray.Employee e = new EmployeeLibraray.Employee();
===========> Custom C# object to be passed to Java
e.LoginName = "test";
obj.execute( e);
Code in java
public void execute(system.Object inputObj) throws Exception {
}
Question
How should we cast the inputObj as Employee so that can access directly e.getName().
Related
I have a class in java:
public class MyClass{
public String a=null;
public String b=null;
public String c=null;
public String d=null;
public static String testMyClass() {
//my method instruction using the attributes a,b,c and d
}
The trouble is that MyClass attributes must be received from python to be able to use the method testMyClass. So is it possible to instantiate a java class from python and after send it back to java using py4j?
Anyone can show how to make it if it is possible? Or have another alternative?
I don't think that is possible unless someone knows of a "bridge" utility between Java and Python.
However, you may do this:
Create a JSON in the Python script in a structure that matches that of MyClass
Receive it in your Java method and deserialize the JSON into an instance of MyClass using Jackson or some JSON tool.
Your next problem will be the communication between you Java process and Python process. For that, see if this StackOverflow question helps: Passing data from Java process to a python script
I am trying some things out with JNI and by that I found the following problem:
If I want to use a native function in Java I load the needed lib, in which the needed function is stored, via
static{
System.loadLibrary("lib");
}
and use
native private static int calculate(byte[] numberArray);
to declare the native method in the java file. During the program itself I can use this function to calculate something with:
int result = calculate(array);
This works only if I compiled the shared object with the header-file created by javah so that each function is named on c side as:
static void Java_com_packagename_File_calculate(const void* array, void* result){
code[...]
}
If I delete the reference in the java code ("native [...] calculate[...]")to this c function; is there any possibility to access / execute the still existing c-code via java (of course without editing the exisiting file ;-)) for example via reflections or inheritance? Or is there something possible like:
public class NewClass{
public int nativeCheater(){
System.loadLibrary("lib");
native private static int Java_com_packagename_File_calculate;
}
}
It is important that I want to use a whole new class without any relations to the prior used package com.packagename.(File).
Thanks in advance :-)
No, but you can create a new class with same package and class name and access the same native method. The new class can declare this method public.
An alternative is to use dynamic binding via Jni_OnLoad() and RegisterNatives(). This way, your native implementations may bind to any Java class, or even more than one.
But if you have access neither to the Java class nor to the native source, you can always create your own native method, in your own class, and inside your C explicitly call the original:
static void Java_com_mypackagename_File_calculate(const void* array, void* result) {
Java_com_packagename_File_calculate(array, result);
}
I have been trying to develop an application. A bean script will be written as per requirement which in turn will call methods (defined in the application) in various order as per requirement. The application code (apart for bean script) would not be changed.
Also, the application uses external jars which provide large number of methods - of which some are implemented in the application. However, I would like to have the possibility to use the other methods (ones that are not yet implemented) without making changes to application should the requirement arise. For this, I would like to use the Java reflection API. The user should be able to call any method present in the external jars by passing the method name and corresponding parameters (using the the external jar documentation).
I'm a java newbie so I have some code that tries to achieve it (may not be syntactically correct):
public void callExternalJarMethod(String methodName, Class[] methodParameterTypes, Object[] methodParameters)
throws NoSuchMethodException {
String className = "SampleClassName";
Class classObject = Class.forName(className);
Method methodObject;
if (methodParameterTypes.length == 0) {
methodObject = classObject.getMethod(methodName, null);
} else {
methodObject = classObject.getMethod(methodName, methodParameterTypes);
}
// Not handling calling of static methods in which case "null" would be passed instead of methodObject to the invoke method
Object returnValue = methodObject.invoke(methodObject, methodParameters);
}
I'm trying to find a way I can get the Class[] methodParameterTypes, and Object[] methodParameters populated with the relevant values. I would have the parameter types and parameter values as string. Also, any pointers towards useful utils would be appreciated.
Thanks in advance.
You are not passing an instance of SampleClassName to the Method.invoke() call here...
Object returnValue = methodObject.invoke(methodObject, methodParameters);
If the method you are going to invoke is static, you can do this...
Object returnValue = methodObject.invoke(null, methodParameters);
Otherwise (non-static), you need to create an instance of SampleClassName to execute the method on.
If the class does not need any constructor arguments, you could use...
Object returnValue = methodObject.invoke(classObject.newInstance(), methodParameters);
(Obviously there will be a load of Exceptions that you need to handle by doing "newInstance" and "invoke"...)
I'm aware that it is possible to use Java defined static methods in Lua, due to the section "Libraries of Java Functions" on http://luaj.org/luaj/README.html.
However I am struggling to find out how I can use the same for instance methods, I have a shortened example here:
private static class CallbackStore {
public void test(final String test) {
}
}
(I am aware that I can use a static method here as well, but it is not possible with the real life scenario)
I am using the following Lua code:
-- Always name this function "initCallbacks"
function initCallbacks(callbackStore)
callbackStore.test("test")
end
Which does not work as it is expecting userdata back, but I give it a string.
And I call the Lua code like this:
globals.load(new StringReader(codeTextArea.getText()), "interopTest").call();
CallbackStore callbackStore = new CallbackStore();
LuaValue initCallbacks = globals.get("initCallbacks");
initCallbacks.invoke(CoerceJavaToLua.coerce(callbackStore));
where the Lua code is returned by codeTextArea.getText()
Bottom line of my question is, how do I make my code running with test as an instance method?
When accessing member functions (in Lua objects in general, not just luaj) you have to provide the this argument manually as the first argument like so:
callbackStore.test(callbackStore,"test")
Or, you can use the shorthand notation for the same thing:
callbackStore:test("test")
I'm pretty new to Java, so I'm hoping one of you guys knows how to do this. I'm having the user specify both the type and value of arguments, in any XML-like way, to be passed to methods that are external to my application.
Example: javac myAppsName externalJavaClass methodofExternalClass [parameters]
Of course, to find the proper method, we have to have the proper parameter types as the method may be overloaded and that's the only way to tell the difference between the different versions. Parameters are currently formatted in this manner:
(type)value(/type), e.g. (int)71(/int) (string)This is my string that I'm passing as a parameter!(/string)
I parse them, getting the constructor for whatever type is indicated, then execute that constructor by running its method, newInstance(<String value>), loading the new instance into an Object. This works fine and dandy, but as we all know, some methods take arrays, or even multi-dimensional arrays.
I could handle the argument formatting like so: (array)(array)(int)0(/int)(int)1(/int)(/array)(array)(int)2(/int)(int)3(/int)(/array)(/array)... or perhaps even better... {{(int)0(/int)(int)1(/int)}{(int)2(/int)(int)3(/int)}}.
The question is, how can this be implemented? Do I have to start wrapping everything in an Object[] array so I can handle primitives, etc. as argObj[0], but load an array as I normally would? (Unfortunately, I would have to make it an Object[][] array if I wanted to support two-dimensional arrays. This implementation wouldn't be very pretty.)
What you're really looking for is JSON, and one of the Java kits for handling it.
Yes there is, and it's called java.lang.Object. You can even assign arrays like int[][] to an variable declared as java.lang.Object.
But I fear that's not what you wanted. It seems that you are writing a client-service framework -- the client (your user) pass some data to the service (your app). There're existing libraries that can do the same thing, e.g., Thrift, Protobuf. If you are looking for XML-based solution, there is SOAP.
I think what you are looking for here is a way to dynamically call Java methods based on attributes described inside an XML file.
If that's the case, you can explore the Java Reflection API.
Example class:
package foo;
public class Bar {
public void doSomething(String x) {
System.out.println("This is a method doSomething that takes in a String parameter");
}
public void doSomething(String [] arr, String str) {
System.out.println("This is a method doSomething that takes in a String arr parameter and a String parameter");
}
}
To dynamically use the methods in this class, do the following:
Class c = Class.forName("foo.Bar");
Object newInstance = c.newInstance();
Method method = c.getMethod("doSomething", String.class);
// This will locate the first method
method.invoke(newInstance, "Hello World");
Method method = c.getMethod("doSomething", String[].class, String.class);
// This will locate the second method
String [] arr = {"Hello", "World"};
method.invoke(newInstance, arr, "Hello World");
So you can specify in your XML file as follows:
<method>
<name>doSomething</name>
<params>
<param>java.lang.String</param>
</params>
</method>
<method>
<name>doSomething</name>
<params>
<param>java.lang.String[]</param> // or any other annotation to indicate that its an arr
<param>java.lang.String</param>
</params>
</method>
Then, read the XML file and use it to find the Java methods dynamically.
To dynamically create an array:
Class c = Class.forName("java.lang.String");
int length = 5;
Object o = Array.newInstance(c, length); // o is a String arr of length 5
String [] arr = (String []) o;