I have a jni dll that has functions being called from java. The problem is that this dll has all the java classes in the default package (in the dll "Java_classname_methodname"). It is impossible to get the source of this dll and it would take EXTREMELY long to rewrite. So I basically need to call the functions in this dll from java in a different package than default. I've tried for hours on end to rename the functions in the dll with a hex editor and several tools to modify the checksum and addresses in the dll but it's just too much for me because I have almost no experience with this. I would very much prefer this route, but I just don't have the proper tools or the know-how. So what I'm left with is trying to hardcode the package name in java. I tried using jna as described in this stack overflow post to do something like this:
Map options = new HashMap();
options.
put(
Library.OPTION_FUNCTION_MAPPER,
new StdCallFunctionMapper() {
public String getFunctionName(NativeLibrary library, Method method) {
method.setName(method.getName().replace("com.test.", "");
return super.getFunctionName(library, method);
}
}
);
Native.loadLibrary(..., ..., options);
But there is no setName in Method. Ideally I'd like to get this done without any extra libraries but I'm obviously not opposed to using something like jna. And before anyone asks, yes this is permitted by the library's usage license. Please don't tell me it's not possible because know that it's possible, just difficult. Whichever way it must be done I am willing to put in the work (either modifying dll or using java code with some external library). And by the way, I also need this done on .so and .dylib files eventually (not as important as dll). Thank you for your time.
I have a JNI dll that has functions being called from java. The problem is that this DLL has all the java classes in the default package (in the dll "Java_classname_methodname").
So the corresponding Java class with the native methods wasn't in a package either.
It is impossible to get the source of this dll and it would take EXTREMELY long to rewrite. So I basically need to call the functions in this dll from java in a different package than default.
Correct.
I've tried for hours on end to rename the functions in the dll with a hex editor and several tools to modify the checksum and addresses in the dll but it's just too much for me because I have almost no experience with this.
You may be able to alias the function names somehow, but it's been about 20 years since I practiced in this area.
I would very much prefer this route, but I just don't have the proper tools or the know-how. So what I'm left with is trying to hardcode the package name in java.
No. There is no package name to hard-code. What you're left with is trying to call native methods in a class without a package from a class in a package, which since 1.4 is not possible.
What you need to to do is either:
It is possible to call the package-less Java native methods via reflection. So, you can write a wrapper class that does that, which lives in the package of your choice, and the rest of your code can call the wrapper.
Or
As follows:
Write another Java class in the package of your choice with the appropriate native methods.
Create an import library from the existing DLL.
Write another DLL and link it with this import library.
Load this new DLL from your Java code.
Have this DLL use the RegisterNatives method on initialization, to register the existing JNI entry points in the old DLL under the new native method names & signatures.
Use javah to get the required native method names and javap to get the required Java signatures. Don't try to guess them by hand.
Don't ask me how this maps to .so files.
Related
I've been trying to find an answer to this for some time, but I think part of my problem is that I don't really know how to phrase my question. I understand the that JVM ultimately preforms all the system calls at run-time that the Java program needs to make, my confusion is about the underlying way that Java classes tell the JVM to do this.
Take for example, the File class in the standard Java library. As far as I know, this is considered the most fundamental API for opening/creating files in Java. But, File is just another class right? So in theory I should be able to write my own File class from scratch which doesn't utilize the pre-exisitng one, right? How would I do that? What is happening inside the File class that tells the VM to actually create the file? I looked at the source code for the File class, and it looks like it calls another class called VMFile, but I could find no explanation of what VMFile is. When I looked at the VMFile source code, it just had function declarations with no definitions.
Thank you for your help.
The Java Native Interface (JNI) is the glue between Java classes and the OS. Native methods have a 'native' attribute (look it up in the JLS).
From what I understood dll are not standardized. thus one cannot just call something in a dll.
However I found this :http://johannburkard.de/software/nativecall/
This library allow you to call any method from a dll in java, so it seems that you can call any method in a dll.
but it was done for 32 bit system, thus I cannot use it.
I have this dll, autohotkey.dll, I know there is the method "ahkExec" inside which take a String as parameter.
Is this really not possible to run it from java without using some kind of c++ magic?
Thanks.
ps : here is how it is done with nativeCall : https://gist.github.com/brigand/1526712
You've been able to call DLLs in Java since version 1.0 using Java Native Interface (JNI).
There is no magic in invoking external methods but you have to follow some rules based on what JNI provides .
If you need to use one function from library you could write a specific Wrapper-class like in this tutorial
For more tricky things better to work with SWIG
I have an existing .c and .h file from a library. I would like to be able to call the functions contained within the c files from Java. I understand that this requires the JNI, and I have a pretty good understanding of how I will need to modify the .c and .h files in order to make them work with the JNI. What I don't fully understand how to do, or if it's even the purpose of the JNI, is to make a simple JNI library that I can then wrap into another java application. I want to create the interface; extend the C API into Java so I can use it there. The final result would be something like: someCmethodInSomeJNILibrary() located in some jnilib sort of file.
Thanks in advance
First, you may wish to consider using JNA. JNA would allow you to interact without writing additional native code. This is particularly convenient if you already have a library and don't want to build another.
With JNI, the steps required include:
Design a Java API of native methods for interacting with the C code.
Use javah to generate C stubs for the Java native methods.
Glue the C stubs to your C code.
Generate a dynamic/shared library containing the native method functions and your original C code.
Load that shared library in Java.
More detail can be found in "Compiling, Loading, and Linking Native Methods" in the JNI documentation.
I'm writing a C++ dll (file extension in Visual Studio is .cpp but the code is C) which uses JNI for loading and calling instance methods of some Java classes. As a result my project is made up by C++ source and header files plus some Java class files (the class files for the Java objects used through JNI). I would like to create a single dll library including also the Java class files "in a single bundle". Is it possible to put both the C and Java files into the dll?
This is perfectly possible, though not necessarily intuitive. I haven't tested this but I would imagine it would work easily if you knew what you were doing.
First off, you're going to need a way to package the class file's binary into the native binary you own, and then of course be able to seamlessly read that chunk at any point in time. How you achieve this is up to you, there is no real 'right way' to do it.
That being said, if you can get a handle to the memory where the .class file's data resides (after loading the DLL) and pass it to Java as a byte[] or ByteBuffer, you'd then want to use any one of ClassLoader's defineClass overloads along with a call to findLoadedClass and then finally loadClass.
This would allow you to load in a class from virtually any data source. As I mentioned before, how you store/retrieve the native data for the class is up to you.
In PHP, we have:
<?php include 'external_file.php'; ?>
Whereas in Java, you have imports:
import javax.servlet.http.HttpServlet;
It is to my understanding that PHP includes simply dump the contents of the external file into the file that contains the include statement.
My gut feeling is that Java handles these includes/imports differently than PHP. What are the key differences?
PHP's include is pretty much the exact same thing as having literally cut/pasted the raw contents of the included file at the point where the include() directive is.
Java's compiled, so there's no source code to "include" - the JVM is simply loading object/class definitions and making them available for use. It's much like the #include directives in C. you're not loading literal source code, just function definitions/prototypes/fingerprints for later use.
In php it simply dumps the contents of the file in the current file.
In Java, an imported class is used:
For compiling the source to byte code using the imported classes.
At runtime when the JVM sees that your program references the imported class, it loads it and uses it(for method invocations and member accesses if it is the case)
PHP simply just includes whatever is in that file. It's simply merging the two files together.
Java's import function gives you access to the methods specified in that import. Basically, PHP is just a rudimentary combining of the two files while Java gives you access to that file's methods and interface.
You have <jsp:include> in Java similar to PHP include.
Java import is similar to PHP load module.
The closest to a php include in Java is a static import. I.e. something like: import static javax.servlet.http.HttpServlet. This allows you to reference methods in the same class file as if they were declared locally (this only applies for static members of the imported class. However, this is very seldom used. It's a tighter form of coupling and should be avoided in most cases. The only time I find it helpful is for Junit test cases. Doing a static import of org.junit.Assert allows you to use the shorter form assertEquals(...) instead of Assert.assertEquals(...). Check out Oracle's documentation on static imports here.
The main difference from my experience is that PHP allows you do do anything. You can treat PHP includes the same way as Java uses its imports. A PHP file can be all function, or it can simply execute from start to finish.
So your php file could be
<?php
echo(1 + 4)
?>
or it could include function which you call later on
<?php
function addTwoNumbers()
{
return 1 + 4;
}
?>
If you inccluded the second php file you could call the addTwoNumbers function below your include statement. I like to practice specifying individual functions rather than create many PHP files.
They are very different. Php just include the source code from the included file.
Java is using the ClassLoader to load the compiled class located somewhere in the CLASSPATH. The import just tells the compiler that you want to reference those classes in the current namespace. The import does not load anything by itself, only when you use new, the JVM will load the class.