I'm attempting to use the CreateObject function within ColdFusion to access functionality within a DLL through JNI. I've managed to get ColdFusion to load the DLL OK using the java.lang.System.load function, but am not sure how to then access the functions contained within this method.
My current code:
<cfset CreateObject("java","java.lang.System").load("C://Path//To//JniDll.dll")>
<cfset JniObject = CreateObject("java","Organisation.product.package")>
Which fails on line 2 with the error
Object Instantiation Exception.
Class not found Organisation.product.package
It's possible I'm accessing these methods incorrectly, but haven't been able to find any information about using JNI in ColdFusion on the web.
Thanks for your help,
Tom
You won't get access to the methods in that DLL just by registering it AFAIK. Either you get supplied a Java wrapper (probably as a JAR) which will then use the DLL, or you have to see what COM interfaces the DLL exposes and call them via createobject(type="COM"), as others have suggested.
From the looks of your code and error, you're expecting a Java class Organisation.product.package to be present and CF can't see it, so I'd take a look in the CF administrator and see which paths are in your classpath. Drop the JAR I assume you have into CF's lib folder and restart CF and see if that makes a difference.
I would suggest you make it work in java first. After that you place the generated jar file in the correct coldfusion lib directory and load (the java class) using CreateObject. The java class should be responsible for the dll binding.
Related
I have an .so file that I successfully integrated into android studio and I can load the file by calling System.loadLibrary.
Is there a way I can see what methods and classes I can use now with this library loaded?
Depends on how the library maps Java methods to native function pointers: it can do one or both of the following:
Dynamic symbols that start with Java_ are mangled names for the class and method name.
If the code uses RegisterNatives system call you will have to put a breakpoint on env->RegisterNatives and look at the surrounding code/arguments.
I wonder how java.* libraries implement the java native interface?
To be more specific I am investigating the java.awt.Robot and come across native method calls. As I am in windows - does that mean there is a .cpp file laying around somewhere (inside the java.awt.* package?) - that the java.awt.Robot uses?
Whenever you call native code, you have to go via JNI. Typically, you need to build shared library. Calling schema follows (note that you don't call C file - it's just visualization of which method will be called):
So, in a sense, there is a file that contains source code of the library that you call.
In case of Windows, shared libraries are DLL files in case of Linux they are typically so files and in macOS dylib. If you want to make them "visible" to your Java code, you have few options here. You can put location (directory where library is) in:
PATH (windows)
LD_LIBRARY_PATH (macOS/Linux)
-Djava.library.path - work for all systems, it's just a jvm's argument.
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.
I have an applet which contains some images, regular java classes and class, which uses C code via JNI. All this is included in jar file, and the appropriate dll is located somewhere on a harddrive. In C code I have to read a bitmap from the applet(jar). I know that it is simple to access this file from java via getResourceAsStream() method, but can I do it from native code?
I understand that I can pass the bytes of the bitmap to native code as a workaround, but it requires some rewriting, so I would like to avoid this.
So, is there any way to access files from within jar via native code, executed by class belonging to this jar?
Just call the appropriate Java methods.
I am trying to create executable under windows platform for Java program using JNI ,C/C++ and invocation API, I have already created jar file for my program which includes all dependencies. I want to embed it in exe file, I was successful in running simple main class(present in file system) using JNI invocation API, I am planning to add jar file as resource in C/C++ program. But I don't know how do I run that jar file , One option is create temporary jar file on file system and run it using java, But I do not want to expose my jar file to everyone for security reasons, How can I run jar file on the fly using JNI ?
Compiling Java to an executable with GCJ does not work all the time, there are limitations as far as using reflection and other items such as UI classes, Look at this page.
If you convert you Java Code to a library or simply another module then you could link to it and simply run it without the need for a JVM.
My initial reaction was that I would be shocked if you could get this to work and have it be performant. But then I started thinking about it, and maybe you could pull this off using a custom class loader. If you embed the jar in the exe as a resource, it would be exactly the same as having the jar bytes be present at a particular offset in any file (whether an exe or not).
So, here's a potential strategy: implement a custom class loader that accepts the exe path and offset of the jar resource in that file. This would use a custom version of ZipFile that uses a fixed index offset for it's reads (unfortunately, it isn't going to be possible to use ZipFile itself - but if you grab the source of ZipFile it should be pretty obvious where you'll need to add the offset).
There is a bootstrapping issue here (how do you load the custom class loader?) - but I think it might be possible to do that from the JNI side. Basically you'd store the .class file for the loader as a separate resource in the exe, load it fully into memory then construct it using JNI calls. That will be a hassle, but it's just for one class, and then you can let the Java runtime take over the rest.
Sounds like an interesting project (Although, as others are pointing out, there isn't much security in what you are doing... I suppose that you could encrypt the embedded jar and add decryption code to the classloader, but you've kinda got to decide how far you want to take this thing).