I know it's possible to load a DLL (Windows library) in java.
And I know that a compiled java program runs anywhere..
Can a java program that loads a DLL run in a Unix environment ? (if the DLL file is present there)
No. A DLL runs native Windows instructions that are not compatible with a UNIX operating system. However shared libraries (.so) can be accessed using JNI.
To ensure a portable "Write once run anywhere" model, calls to native libraries should be avoided in favor of a pure Java implementation.
I would be very surprised. The DLL (provided it's native) will be built with OS and platform-specifics.
No. You can't take a Windows PE/COFF DLL and stick it in a Unix environment, it just won't work. (Unless you're talking about Cygwin/MSYS)
You will have to compile the library for the target system and use that.
It is possible to load the DLL in unix indeed. However many dlls use the windows API which is not available on UNIX. You must also check for copyright issues that you may encounter doing that. Native library access is possible using JNI. But this (loading DLL in unix) is not a supported and reliable configuration.
To give you a brief answer and a short advice: the answer is no and the advice is to not waste your time doing this.
Related
I have some Java-app and a customer with some UWP-app implemented in C#, distributed through the Windows Store etc., who wants to use some pieces of my app. Those pieces are pretty OS-independent, only parsing of some special binary file formats, applying some business logic configured using YAML files and stuff. No network, GUI, only some accesses to files etc.
We currently use IKVM to make the code of interest available to C# but ran into different problems already. Some were supporting .NET Core, some had to do with the native toolchain in Release etc. While right now things seem to work after applying some workarounds, I'm looking for alternatives to IKVM already a bit.
The only thing I currently use of IKVM is simply creating a DLL of my code using ikvmc, which can then be referenced in the UWP-project. The compiler is summarized like the following:
The ikvmc tool converts Java bytecode to .NET dll's and exe's.
That's where the support to create native Windows images of GraalVM came into my mind. Others seem to already build native binaries for Windows and according to the docs, GraalVM is able to create shared libs using "--shared". From my understanding, IKVM implements a JVM in .NET and maps things as needed and possible. That sounds pretty much like what "Substrate VM" does in case of a native image, doesn't it?
This executable includes the application, the libraries, the JDK and
does not run on the Java VM, but includes necessary components like
memory management and thread scheduling from a different virtual
machine, called “Substrate VM”. Substrate VM is the name for the
runtime components (like the deoptimizer, garbage collector, thread
scheduling etc.).
https://www.graalvm.org/docs/reference-manual/native-image/
So, is there any chance that a native image in form of a DLL can replace the DLL created by ikvmc currently? Did anyone try that already and has any experiences? Did anyone try already to create a native DLL and consume that in some other native Windows app? From my understanding UWP "only" applies additional restrictions which one might be able to work around again. Or is this approach totally impossible for some reasons?
Thanks all for your input!
I'm not very familiar with the IKVM project, so this answer is mostly about the generic question:
Can you create a native DLL/shared library and consume that in some other native Windows app?
It should be possible. You can compile Java code into a shared library. The entry points are marked with the #CEntrypoint annotation.
You can then use the generated shared library and the header files to consume your library from a native application.
This way for example GraalVM distributions use the GraalVM JIT compiler by default:
The GraalVM JIT is written in Java
Compiled as a shared library with the native-image
Used in Hotspot.
Here's a page describing how to consume those from Java through the JNI: https://www.graalvm.org/reference-manual/native-image/ImplementingNativeMethodsInJavaWithSVM/
which could be very similar to how would you use a shared library from a C# application.
GraalVM native images are not very flexible, unlike IKVM.NET images. Unless you like writing wrappers and playing with P/Invoke, you should stick to IKVM.NET.
NOTE: I am behind an IKVM.NET fork
http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u3-download-1501626.html
We know that java is a Platform Independent Language then why does this site provide JDKs for all OSes like Linux, Windows, Solaris?
Then why do we tell java is Platform Independent?
it is like this:
your application
---------------------
JAVA on OS1
---------------------
OS1
---------------------
hardware
---------------------
if you write your application on top of Java, then you can just move your java
application, as is, without changing it, or even compile it, to new OS, because
your program is written on one platform, which is Java, not the native OS.
So, you need to download specific Java for your OS. But from application point of view, it is the same API. Java makes your application platform independent since it hides the OS from your application. But Java itself, it has to be compiled and build for each specific OS. But the application do not care about that. The application sees the same API. That is the whole point.
Because there you download the Installer for the Java Virtual Machine. This is the environment where your Java Application is running in.
The reason why Java is OS independent, is because its running in this JVM.
The JVM's job is to hide the differences between platforms and to provide the same execution environment to application code regardless of platform.
The JVM is written in C++, and is compiled to a native binary, just like any other C++ application. (You wouldn't expect a .exe file to run on Linux, after all).
So the JVM is platform-specific, but the environment it provides is not.
To explain you in simple terms, you no need to compile your java source code when you move your code from one OS to another, but to run your compiled java code you need to have OS specific Java run time machine. Thats why you have different JDK for different OS.
To add to others answers, Java is qualified Platform independent because the code you write is supposed to works on every platform. That's not totally true in fact. The Java code is always compiled in bytecode in the same way, but the JVM interprets this common bytecode in different way in function of the OS, there is one JVM per OS. OS that don't have a JVM implementation to use bytecode can't support Java.
On a recent question, I got comments asking whether I was using "native code" in my application. Now, I know that there is some way to call code in traditional binary libraries (DLLs, SOs) from inside a Java application using a thing called "JNI". I have read that Wikipedia entry but I never used this.
I am using a number of libraries, some of which may or may not use native code. How do I find out if they do? I did not have to install any SOs (running on Linux), but I guess that doesn't mean the libraries are not using any? Do I have to browse through all the documentation (which varies greatly in quality between libraries) or can I do some analysis on the JARs?
Usually using libraries that require JNI requires some additional setup (like putting .dll or .so files in the right places or setting the java.library.path System property).
If you did nothing of that, then chances are that you're not using JNI anywhere. This is also somewhat likely, as only quite specialized libraries require JNI.
However there's also JNA, which is a wrapper around JNI which simplifies its usage and which sometimes makes it unnecessary to do any explicit setup. If that's used by one of your libraries, then it's harder to detect.
If you get a crash dump, then checking that for any non-standard libraries can give a hint if a user-loaded native library is to blame.
To nitpick, every single Java application uses JNI indirectly at least. For example, System class contains several native methods, which map to the native JRE (as can be seen from its source code).
Whether your program/libraries use (directly or indirectly) some other native functions than those contained in the standard JRE, is indeed hard to detect. The .dlls / .sos may be packed into the .jar, to be extracted only when needed, so not having to install native libraries doesn't guarantee that it doesn't use any. It should usually be stated in the library documentation, though, because the vendor probably won't provide binaries for every imaginable system that Java runs on. But to be sure, I think the only way is to scan through the source code for native methods.
If a java library (jar) uses a native library (dll on Windows or so on Linux) the chances are that it is a system wide and well known library (such as glibc on Linux) or a custom one. In the last case it is common to pack it within the jar, so you can just open it up with a ZIP decompressor (i.e. 7zip on Windows will do fine) and browse the files. You should see dll files if it is targeted to Windows, so files if targeted to a Unix platform, or even both. The native library files usually are left at the root level of the jar.
If the jar uses custom libraries but it is packed along with an application it is common to leave the native libraries in an external folder with other application files (in this case there is no consensus). In this case you should look for the application launcher (a bat / sh file) or the configuration file if the lanucher is binary (an ini / conf file) and find out the JVM configuration (where java.library.path points to).
Probably the easiest way of doing this is using jmap or pmap to show which .so (shared object) files are mapped into your Java process. If there's anything other than stuff that's in /lib, /usr/lib or the Java lib directory it's a JNI suspect. You can also look at the /proc entry for the Java process under /proc/<pid>/maps. See the following manpages:
http://linux.die.net/man/1/jmap-java-1.6.0-openjdk
http://linux.die.net/man/1/pmap
http://linux.die.net/man/5/proc
I have several scripts written in perl, python, and java (wrapped under java GUI with system calls to perl & python). And I have many not-tech-savy users that need to use this in their windows machines (xp & 7).
To avoid users from installing perl,python,and java and to avoid potential incompatibility between various versions of these interpreters, I'd like to make a local copy of these interpreters in a folder and then calling them. I'd zip the whole folder (which would also contain my code) and send it away.
I'd have to worry about environment variables and make calls to the correct interpreter (especially when other versions of python,java,perl may exists in their current system), but not sure what other problems I may face. Any better ideas?
I never used jython and do not know the overhead of moving to it. I also suspect a complex python system, with many files and 3rd party modules will have problems. Same with perl scripts and I don't know a robust perl interpreter callable from java.
Thank you, in advance.
Try Portable Python and Portable Perl. You can unzip them into your application tree and they should work.
Why don't you try migrating your perl/python code into java and then packagin everything into a nice webstart application? What do perl/python offer that java doesn't support?
For perl you can use something like perl2exe and for python py2exe so you can have 2 exes (which would include all the necessary interpreter bits) and invoke them as resources from within java? Or unzip them inside user's home directory and call them again as normal external programs (ProcessBuilder ?) ?
Could anyone tell me the difference between library and native library in terms of java? I found the word "native library" in the following line:
Type 1 - drivers that implement the
JDBC API as a mapping to another data
access API, such as ODBC. Drivers of
this type are generally dependent on a
native library, which limits their
portability. The JDBC-ODBC Bridge
driver is an example of a Type 1
driver.
which you can found here
"Native Library" generally means a non-Java library that's used by the system (so C/C++, etc). Think normal DLLs or libs.
Java can load these native libraries through JNI.
In the context of Java, a library is one written in Java and available in the form of Java bytecode *.class files, typically compressed into a JAR archive. By contrast, a native library is one that has been compiled to machine code and is typically written in C or C++. Native libraries are *.so, *.dylib, *.dll, *.a, or *.lib files (depending on your platform) that link against the Java Native Interface (JNI) library and expose the functionality from C or C++ to Java through the Java Native Interace mechanism.
A native library is a library that contains "native" code. That is, code that has been compiled for a specific hardware architecture or operating system such as x86 or windows.
Including such native library in your project may break the platform-independence of you application.
In this context, "library" is assumed to refer to a library written in Java (and probably distributed as a jar) whereas "native library" refers to a library written in something like C or OpenForth and compiled down to machine code.