Call VB.Net dll with classes and subfunctions, from Java with JNA - java

I have a third-party VB.Net dll that I want to call from Java.
The VB.Net dll has the following signature (pseudo code, but feels like Java...):
class MyClass1 {
public Object method1(StringRef arg1, StringRef arg2) {
// do something here...
return someResult;
}
}
class MyClass2 {
public Object method2(StringRef arg1, StringRef arg2) {
// do something here...
return someOtherResult;
}
}
Note: StringRef is my way of saying the method expects me to pass in strings by reference.
I am trying to call this dll object from within Java. Using JNA, I have the following:
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface DllName extends Library {
DllName INSTANCE = (DllName)Native.loadLibrary("DllName", DllName.class);
public static interface MyClass1 {
public Object method1(String arg1, String arg2);
}
public static interface MyClass2 {
public Object method2(String arg1, String arg2);
}
}
The INSTANCE object here loads just fine. However, I cannot figure out what structure the body of DllName should take to map to the dll's class, method signature. Also, I have not seen how I might call Native in a way that would load the object directly. For example, if I do:
DllName INSTANCE = (DllName)Native.loadLibrary("DllName.MyClass1", DllName.class);
This results in an UnsatisfiedLinkError since the dll is named DllName. Making this call requires a different interface than shown above.
Questions:
Is this even possible? E.g. Can I call a VB.Net dll from Java using JNA given the structure above.
What structure does DllName need to have to properly map to the class MyClass1 and MyClass2? This is my core question here.
In the DllName.MyClass1 call above, is there some alternative way?
Did I miss anything with any of the alternative items mentioned below? Perhaps some other solution I missed?
I have explored the following alternatives:
Reviewed this article, but did not see an example that matches my structure. I also looked at the unit tests referenced on the bottom.
Creating a C++ wrapper, as suggested here /questions/1556421/use-jni-instead-of-jna-to-call-native-code (I'd post as a link, but not enough reputation with SO...). I haven't actually tried this, as I am not familiar with C++. I would expect too-much head-banging, when I think some change to my Java code would suffice.
JNI: This seems like it is only for C/C++ type dlls.
javOnet: Almost works, but the VB.Net methods expect strings by reference, which is not currently supported by javOnet. I reported the issue to them, and I expect a fix. Even if it did work, it seems like a JNA solution should work. There is also a cost issue with that solution.
jni4net: This does not work for me since this is a third-party dll. jni4net expects some hook on the .Net side.
Please let me know if you would like me to add any additional color here.

javOnet already provides support for arguments passed by ref or out since version 1.2. You can read more at:
http://www.javonet.com/quick-start-guide/#Passing_arguments_by_reference_with_ref_and_out_keywrods
You must wrap you JAVA type in "AtomicReference" so it can be updated within the method call and your JAVA variable let's say integer will be automatically modified on .NET side. You can see the usage sample below:
NObject refEx = Javonet.New("RefExample");
//Wrap Java integer in AtomicReference to allow passing by reference
AtomicReference<Integer> myInt = new AtomicReference<Integer>(10);
refEx.invoke("Method",new NRef(myInt));
System.out.println(myInt.get());
//Output will display number "55" because int passed by reference has been modified within the method body.

Related

Java JNI moving around java functions and their C implementations

I'd like to start by saying please don't ask me to use the javah tool, I've had more luck writing the few jni function prototypes than getting that tool to work properly.
I know that I am loading my jni libraries properly because they work when I leave the class structure the same.
I have some package name:
package com.bb.me;
public class test {
test2 iTest = null;
public parent test()
{
iTest = new test();
return iTest;
}
//putting my native methods here work just fine
//public native void init();
//etc
}
The c jni function prototype for that above function looks like this:
JNIEXPORT void JNICALL Java_com_bb_me_test_init(JNIEnv* e, jobject i) {}
if I break that above function signature by renaming it inita and call the function I get an error like this:
No implementation found for native Lcom/bb/me/test;.init:()V
if on the other hand I move the native function to the inner class like this:
class test2 extends parent {
//public native void init();
}
and then try to call the same function, jni will complain at me a different way about unimplemented function but this time it looks like this:
No implementation found for native Lcom/bb/me/test$test2;.init:()V
I originally thought if I edited the jni function signature to something like this:
JNIEXPORT void JNICALL Java_com_bb_me_test_test2_init(JNIEnv* e, jobject i) {}
that the function would work but it doesn't seem like that's the case.
What does the "$" dollar sign mean in this jni function signature?
No implementation found for native Lcom/bb/me/test$test2;.init:()V
How can I move the location of this native function and update the jni function signatures without using the javah tool?
I'd like to start by saying please don't ask me to use the javah tool, I've had more luck writing the few jni function prototypes than getting that tool to work properly.
I won't ask you to use javah -- though it's hard not to do -- but I have to at least say that I find that remark surprising. I have found javah very easy to use indeed. If it's not working "properly" for you then I'm inclined to suspect that you have the wrong expectations.
What does the "$" dollar sign mean in this jni function signature?
The $ delimits the simple name of a nested class from the name of the class in which it is nested. This is an aspect of the JVM's internal representation of names, which is what JNI works with.
How can I move the location of this native function and update the jni function signatures without using the javah tool?
You could refer to Oracle's documentation for mapping Java native method names to C function names. The expected native function name is based on the fully-qualified JVM name of the native method's class, on the native method's unqualified name, and, if it's overloaded, on its signature. If you move a native method to a different class then you need to alter the function name to reflect the new location, and it is possible that you will also need to encode the function signature into the name if that was not already done.
The JVM name of your inner class is com/bb/me/test$test2. Supposing that the method is not overloaded, the C function name corresponding to the native method residing in that class would therefore be Java_com_bb_me_test_00024test2_init(). The arguments are a different story -- they depend on the arguments to the Java-side method as well as on whether the native method is static. I do not address them here.

Java equivalent of Javascript prototype

In JavaScript, you can do this.
String.prototype.removeNumericalCharacters = function(){
...code...
}
or
Number.prototype.addTwo = function(){
...code...
}
var a = 5;
a.addTwo();
//a is now 7
Is there a way to do something similar in Java? (I don't mean the actual function, just using that as an example)
An example in Java would be
int a = 5;
a.addTwo();
//A is now 7
My question is how do I define the .addTwo() method.
It's Friday so lets answer this question. I'm not going to dive into much details (it's Friday!) but hopefully you'll find this useful (to some extend).
You certainly know that Java objects don't have prototypes. If you want to add a field or a method to a Java class you have two options. You either extend the existing class and add the method/ field to it like this:
public class A {
}
public class B extends A {
int addTwo () {...};
}
However that's not changing the parent class. Objects of class A in the example still have no method addTwo.
Second approach is to dynamically change the class (you could use things like javassist) and method/fields to it. It's all fine but to use these new methids/fields you'd have to use reflection. Java is strongly typed and needs to know about class's available methods and fields during the compile time.
Finally and that's when things get really rough - primitive types, in your instance int, are 'hardwired' into JVM and can't be changed. So your example
int a = 5;
a.addTwo();
is impossible in Java. You'd have more luck with dynamic languages on JVM (Groovy is one of them). They're usually support optional typing and allow dynamic method calls.
So enjoy Friday!

Java imitate first-class functions

In Java, is there a way to emulate the first-class functions in lua and python, such as here?
def foo():
print "foo called"
bar = foo
bar() #output from this line is "foo called"
Or is the only way to have a switch statement with the different methods at each case?
Edit: thank you for the clarification, what I mean to ask is is there a way to create a reference to a function, and call it as if it was the function.
Also, the goal is not to call a certain implementation of a function, it is choose which function to call, the choices of which can entirely different. The reason I want to do this is to have a more general class that does not have to be edited to add functionality. Kind of like putting functions into a collection or list.
Edit2: for anybody viewing this question for the purpose of finding an answer to it: This has to do with stacks and heaps. Java cannot do this because its methods are stored on the stack, which is much more rigid than the heap. Python, however, stores its functions on the heap, with a reference to them on the stack. Since functions are called through a reference in python, you can change the reference to them and use as desired.
The code in the question does not demonstrate pass-by-reference behavior. In fact, neither Java nor Python have pass-by-reference semantics, it's all pass-by-value.
What you're demonstrating is first-order functions: the ability to treat a function as any other value. In Java 7 and older this is not possible, although in Java 8 a new syntax for anonymous functions (called lambdas) was introduced. The lambda syntax can be used to imitate the behavior shown.
you can't simulate pass by reference for methods, for similar things use interfaces, but for objects you can simulate here
(As #Óscar López just posted as I was writing this) What you're doing is keeping a reference to a function and passing that around by value.
The "Java way" of doing this would be to use interfaces:
Interface:
public interface Printer {
public void doPrint();
}
Implementation:
public class FooPrinter implements Printer {
public void doPrint() { System.out.println("foo"); }
}
(Other implementations could be done - BarPrinter, BazPrinter, etc.)
Caller:
Printer p = new FooPrinter();
// presumably some other code here and
// probably p is passed to another function which accepts Printer (not FooPrinter)
p.doPrint(); // outputs "foo"

Equivalent of #define in Java?

I'm writing a library that needs to have some code if a particular library is included. Since this code is scattered all around the project, it would be nice if users didn't have to comment/uncomment everything themselves.
In C, this would be easy enough with a #define in a header, and then code blocks surrounded with #ifdefs. Of course, Java doesn't have the C preprocessor...
To clarify - several external libraries will be distributed with mine. I do not want to have to include them all to minimize my executable size. If a developer does include a library, I need to be able to use it, and if not, then it can just be ignored.
What is the best way to do this in Java?
There's no way to do what you want from within Java. You could preprocess the Java source files, but that's outside the scope of Java.
Can you not abstract the differences and then vary the implementation?
Based on your clarification, it sounds like you might be able to create a factory method that will return either an object from one of the external libraries or a "stub" class whose functions will do what you would have done in the "not-available" conditional code.
As other have said, there is no such thing as #define/#ifdef in Java. But regarding your problem of having optional external libraries, which you would use, if present, and not use if not, using proxy classes might be an option (if the library interfaces aren't too big).
I had to do this once for the Mac OS X specific extensions for AWT/Swing (found in com.apple.eawt.*). The classes are, of course, only on the class-path if the application is running on Mac OS. To be able to use them but still allow the same app to be used on other platforms, I wrote simple proxy classes, which just offered the same methods as the original EAWT classes. Internally, the proxies used some reflection to determine if the real classes were on the class-path and would pass through all method calls. By using the java.lang.reflect.Proxy class, you can even create and pass around objects of a type defined in the external library, without having it available at compile time.
For example, the proxy for com.apple.eawt.ApplicationListener looked like this:
public class ApplicationListener {
private static Class<?> nativeClass;
static Class<?> getNativeClass() {
try {
if (ApplicationListener.nativeClass == null) {
ApplicationListener.nativeClass = Class.forName("com.apple.eawt.ApplicationListener");
}
return ApplicationListener.nativeClass;
} catch (ClassNotFoundException ex) {
throw new RuntimeException("This system does not support the Apple EAWT!", ex);
}
}
private Object nativeObject;
public ApplicationListener() {
Class<?> nativeClass = ApplicationListener.getNativeClass();
this.nativeObject = Proxy.newProxyInstance(nativeClass.getClassLoader(), new Class<?>[] {
nativeClass
}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
ApplicationEvent event = new ApplicationEvent(args[0]);
if (methodName.equals("handleReOpenApplication")) {
ApplicationListener.this.handleReOpenApplication(event);
} else if (methodName.equals("handleQuit")) {
ApplicationListener.this.handleQuit(event);
} else if (methodName.equals("handlePrintFile")) {
ApplicationListener.this.handlePrintFile(event);
} else if (methodName.equals("handlePreferences")) {
ApplicationListener.this.handlePreferences(event);
} else if (methodName.equals("handleOpenFile")) {
ApplicationListener.this.handleOpenFile(event);
} else if (methodName.equals("handleOpenApplication")) {
ApplicationListener.this.handleOpenApplication(event);
} else if (methodName.equals("handleAbout")) {
ApplicationListener.this.handleAbout(event);
}
return null;
}
});
}
Object getNativeObject() {
return this.nativeObject;
}
// followed by abstract definitions of all handle...(ApplicationEvent) methods
}
All this only makes sense, if you need just a few classes from an external library, because you have to do everything via reflection at runtime. For larger libraries, you probably would need some way to automate the generation of the proxies. But then, if you really are that dependent on a large external library, you should just require it at compile time.
Comment by Peter Lawrey: (Sorry to edit, its very hard to put code into a comment)
The follow example is generic by method so you don't need to know all the methods involved. You can also make this generic by class so you only need one InvocationHandler class coded to cover all cases.
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
ApplicationEvent event = new ApplicationEvent(args[0]);
Method method = ApplicationListener.class.getMethod(methodName, ApplicationEvent.class);
return method.invoke(ApplicationListener.this, event);
}
In Java one could use a variety of approaches to achieve the same result:
Dependency Injection
Annotations
Reflection
The Java way is to put behaviour that varies into a set of separate classes abstracted through an interface, then plug the required class at run time. See also:
Factory pattern
Builder pattern
Strategy pattern
Well, Java syntax is close enough to C that you could simply use the C preprocessor, which is usually shipped as a separate executable.
But Java isn't really about doing things at compile time anyway. The way I've handled similar situations before is with reflection. In your case, since your calls to the possibly-non-present library are scattered throughout the code, I would make a wrapper class, replace all the calls to the library with calls to the wrapper class, and then use reflection inside the wrapper class to invoke on the library if it is present.
Use a constant:
This week we create some constants
that have all of the benefits of using
the C preprocessor's facilities to
define compile-time constants and
conditionally compiled code.
Java has gotten rid of the entire
notion of a textual preprocessor (if
you take Java as a "descendent" of
C/C++). We can, however, get the best
benefits of at least some of the C
preprocessor's features in Java:
constants and conditional compilation.
I don't believe that there really is such a thing. Most true Java users will tell you that this is a Good Thing, and that relying on conditional compilation should be avoided at almost all costs.
I'm don't really agree with them...
You CAN use constants that can be defined from the compile line, and that will have some of the effect, but not really all. (For example, you can't have things that don't compile, but you still want, inside #if 0... (and no, comments don't always solve that problem, because nesting comments can be tricky...)).
I think that most people will tell you to use some form of inheritance to do this, but that can be very ugly as well, with lots of repeated code...
That said, you CAN always just set up your IDE to throw your java through the pre-processor before sending it to javac...
"to minimize my executable size"
What do you mean by "executable size"?
If you mean the amount of code loaded at runtime, then you can conditionally load classes through the classloader. So you distribute your alternative code no matter what, but it's only actually loaded if the library that it stands in for is missing. You can use an Adapter (or similar) to encapsulate the API, to make sure that almost all of your code is exactly the same either way, and one of two wrapper classes is loaded according to your case. The Java security SPI might give you some ideas how this can be structured and implemented.
If you mean the size of your .jar file, then you can do the above, but tell your developers how to strip the unnecessary classes out of the jar, in the case where they know they aren't going to be needed.
I have one more best way to say.
What you need is a final variable.
public static final boolean LibraryIncluded= false; //or true - manually set this
Then inside the code say as
if(LibraryIncluded){
//do what you want to do if library is included
}
else
{
//do if you want anything to do if the library is not included
}
This will work as #ifdef. Any one of the blocks will be present in the executable code. Other will be eliminated in the compile time itself
Use properties to do this kind of thing.
Use things like Class.forName to identify the class.
Do not use if-statements when you can trivially translate a property directly to a class.
Depending on what you are doing (not quite enough information) you could do something like this:
interface Foo
{
void foo();
}
class FakeFoo
implements Foo
{
public void foo()
{
// do nothing
}
}
class RealFoo
{
public void foo()
{
// do something
}
}
and then provide a class to abstract the instantiation:
class FooFactory
{
public static Foo makeFoo()
{
final String name;
final FooClass fooClass;
final Foo foo;
name = System.getProperty("foo.class");
fooClass = Class.forName(name);
foo = (Foo)fooClass.newInstance();
return (foo);
}
}
Then run java with -Dfoo.name=RealFoo|FakeFoo
Ignored the exception handling in the makeFoo method and you can do it other ways... but the idea is the same.
That way you compile both versions of the Foo subclasses and let the developer choose at runtime which they wish to use.
I see you specifying two mutually exclusive problems here (or, more likely, you have chosen one and I'm just not understanding which choice you've made).
You have to make a choice: Are you shipping two versions of your source code (one if the library exists, and one if it does not), or are you shipping a single version and expecting it to work with the library if the library exists.
If you want a single version to detect the library's existence and use it if available, then you MUST have all the code to access it in your distributed code--you cannot trim it out. Since you are equating your problem with using a #define, I assumed this was not your goal--you want to ship 2 versions (The only way #define can work)
So, with 2 versions you can define a libraryInterface. This can either be an object that wraps your library and forwards all the calls to the library for you or an interface--in either case this object MUST exist at compile time for both modes.
public LibraryInterface getLibrary()
{
if(LIBRARY_EXISTS) // final boolean
{
// Instantiate your wrapper class or reflectively create an instance
return library;
}
return null;
}
Now, when you want to USE your library (cases where you would have had a #ifdef in C) you have this:
if(LIBRARY_EXISTS)
library.doFunc()
Library is an interface that exists in both cases. Since it's always protected by LIBRARY_EXISTS, it will compile out (should never even load into your class loader--but that's implementation dependent).
If your library is a pre-packaged library provided by a 3rd party, you may have to make Library a wrapper class that forwards it's calls to your library. Since your library wrapper is never instantiated if LIBRARY_EXISTS is false, it shouldn't even be loaded at runtime (Heck, it shouldn't even be compiled in if the JVM is smart enough since it's always protected by a final constant.) but remember that the wrapper MUST be available at compile time in both cases.
If it helps have a look at j2me polish or Using preprocessor directives in BlackBerry JDE plugin for eclipse?
this is for mobiles app but this can be reused no ?

Java static reflection on subclasses

I am implementing a sort of ORM in Java. I am trying to do a static find method that is only in the parent class. Let me get to the point:
public class DB {
public static Object find (int id) {
// i want to return anew instance of the calling subclass
}
}
public class Item extends DB {
// nothing here
}
public class Test {
public static void main () {
Item i = (Item) Item.find(2);
...
}
}
I don't know how to have the find method know which of its inherited class is calling it, so that i can return the right instance (and maybe call the right constructor, etc.) And the inherited class could be anything, no limit.
I've tried stacktrace, but it's only traced from Test to DB.
Any ideas?
Thank you everyone!
Static methods are not inherited, so you can't do this. A common approach to this problem (not including using one of tons of available ORM solutions) is to split your class hierarchy into two:
"Entity" (e.g. classes representing your actual data)
and "DAO" (Data Access Object) - classes that contain methods to manipulate data persistence.
A word to the wise: It's probably a bad idea to try and implement your own ORM. Projects like hibernate have covered this task in great detail, so if you roll your own you are likely to reinvent the wheel and possibly attempt to solve problems that have already been solved.
More on topic, ChssPly76 is correct in that you cannot accomplish this because of how static methods are handled in Java. When the VM loads the bytecode for the static method invocation, it will perform a lookup to find where the method actually is located. It won't find it on the Item class, so it will instead bind the call to DB.find.
However! It may be possible to achieve what you are trying to do with some bytecode wrangling. Viewing the bytecode (using javap -c) for the static method call in your example, we get the following:
invokestatic Method Item.find:(I)Ljava/lang/Object
Thus, once your call reaches DB.find, you could follow the stacktrace back to the callsite, and then inspect the bytecode at the callsite to retrive the actual target of the call. In theory, anyway, as I haven't seen this myself in practice. Also, beware of hacking bytecode like this, for here be dragons.
Kudos for identifying the active record pattern, and wanting to use it in Java. I do agree it's a design pattern that makes more sense than most DB access patterns found in Java, and it's one of the strengths of Ruby and PHP.
I think you may find the "Generic DAO" article at IBM developerworks useful.
Short: use Generics wisely.

Categories

Resources