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.
Related
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 dll file which is controlling a device, I need a tool to generate java classes which take the dll file as an input and generate all the need JNI classes.
Note: I don't have the C,C++ code for that DLL.
I believe you are doing all this so that you can call C++ methods through Java.
Instead use JNA library. It does not require any explicit JNI classes to be built. You can directly call C++methods. Read more about it here
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.
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.
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).