Best way to distribute an application that uses JNI - c++

I am currently working on a Windows desktop application that uses JNI to call methods located inside a jar file.
I need to know the best way to package my application so that it can link to jvm.dll. I am not sure if I should package all the binaries found inside the JDK's bin directory into my setup file (not sure if I am allowed to do so)?
The problem is all examples found online links directly the jvm.dll found in the JDK installation path. And since my application is a commercial one, I cannot rely or ask that every user should install the JDK along side my app because that would be ridiculous.
Please can someone clarify the best method to package such application?
Regards

jvm.dll is also installed with the normal java runtime (bin/client subdirectory). By checking some registry values, you can find the path to it, load it from there and check whether the correct version is installed. If you have already linked jvm.lib, you'll then need to add jvm.dll to the list of delay loaded dlls, so you can load it at runtime.
See my recent answer to another question for details:
https://stackoverflow.com/a/14434203/93652

Related

How to embed python into C++ aplication and then deploy/release?

I am currently working on a C++ gui application. The application uses the Python/C API to call some python scripts. The scripts are located in the solution directory, and I call them by simply providing the path. This is currently working fine while debugging the application or even running the generated .exe file, but I am wondering how this could work if I want to release and distribute the application onto a different computer for someone to use. How can these scripts be deployed with the application?
I also have a .ttf font file with the same situation. How can this resource file be deployed with the application?
In other words, I want to deploy/release a C++ application with the scripts and resource files.
FYI: the C++ application is a Visual Studio project.
Thanks for the help in advance, and let me know if any more information is needed!
Update:
I just wanted to clear up the way my project is working currently:
PyObject* pArgs = PyTuple_New(5); // I setup the arguments the python function needs
PyImport_ImportModule("requests"); // imports...
// make python call
PyObject* pResult = PyObject_CallObject(pFunc, pArgs);
So this is (for the most part) how I call the scripts with the C++ source code. The scripts are located in a folder that is located in the solution directory.
I hope this explains my problem a little better.
Update:
Just another little update... Using some answers to other similar questions got me to the following point:
I need to obtain a python library, compile and link it with my C++ application, and then bundle the dependencies with the application (How to distribute C++ application which calls Python?)
So I guess my question is now shifting to how I would be able to get this done. What are the specific steps to do this? I also got a link (https://docs.python.org/3.5/using/windows.html#embedded-distribution) to an embedded distribution of a python environment (maybe this should somehow be used?). Also, I am able to statically link python into the application. I just don't know how to bundle and deploy the scripts I created and use in the application.
PyImport_ImportModule("requests")
The parameter is "requests".
Put the py file aside exe file when distributing.
So, you need to make sure that the C++ application can still access the python libraries when its released and those libraries/dependencies arent necessarily available on other systems.
You'll need to, like another commenter suggested, use one of the importing modules utilities, like PyImport_ImportModule("library name").
You can see these utilities here: https://docs.python.org/3/c-api/import.html
You'll also need to either
Put the libraries that you want with the exe (in the same directory) or
put them in the system environment path ( which is probably less straightforward).
Hope that helps and that I understood you're question correctly.

Application deployment doesn't work after adding QSound

I have an application that I could deploy on other machines (Visual Studio). I added the module QtMultimedia to use the QSound class.
Wanting redeploy my app, the executable indicates me first that I need Qt5Multimedia.dll then Qt5Network.dll (which I have not added in my project).
Now my application doesn't launch, but no error message, I do not understand ...
I did not find much on the internet.
First of all - use dependency walker to list all the dependencies and make sure you have all the required dlls right besides the binary.
Next, make sure you've copied all the required plugins to the appropriate plugin folder besides the binary. In particulary take a look at plugins/audio/qtaudio_windows.dll, I think you might need to deploy it.
Also a good way to check what you app uses is to use process explorer on the machine you have no troubles on to check all the dlls it uses when the app is running.
I finally found !
First I need to go in the folder of my exe
Then use : "windeployqt.exe ." (whithout the quotes).
That add all I need to execute my exe. :)

Packaging a jre with my application

My application contains an c++ exe file which invokes a java program using JNI, thus requiring jvm.dll. However, I want my application to ship with its own embedded jre but after I copy the jre6 folder found in JAVA_HOME and added it to my installer, it fails to run the program(Error occurred during initialization of VM Unable to load native library: Can't find dependent libraries), when I use dependency walker on jvm.dll, it says that it can't find gpsvc.dll, IEShims.dll and sysntfy.dll. After I tried copying those dlls to the same folder as jvm.dll, dependency walker tells me that gpsvc.dll andsysntfy.dll is 64 bit where it should be x86. Problem is, those were the only dlls on my system, what should I do?
The Java virtual machine consists of much more than just jvm.dll. You'll need to redistribute the whole JVM package and install that on a user's machine instead of just adding jvm.dll to your own application.
It will probably be much easier to require your users to download and install the JVM themselves before installing your application. If you really want to redistribute the JVM with your application, you'll need to find documentation on Oracle's website on what the exact license for that is and on how to do it. Look at this paragraph of the JDK 6 readme, for example.
It's not as simple as copying jvm.dll and other libraries that it depends on.
You may download the required dll's from the appropriate sites, i.e. from this one.

Finding an installed application on Mac/Linux

If you have an application which relies on another app being installed, you ideally want your installer to find that dependency path automatically. On Windows you can use the registry but what about Mac/Linux? In this particular case it's a C++ application, if that makes a difference.
If you try to distribute your application through any of the common package managers on Linux (apt, yum) you can add the application as a dependency.
If you down the route of custom install scripts you need to resort to some kind of hackery. Either find out which package manager is in use on the system and try to query with it (which can fail, if the other application was installed without the package manager) or try something like which required_app.
Go for the first, if you want to do it right.
In Mac OS X, if you're looking for an application that's bundled in a typical .app bundle, you can use Spotlight to find it from its bundle ID using the command line utility mdfind(1). For example, to find out if Firefox is installed (and where), run this command:
mdfind 'kMDItemCFBundleIdentifier == org.mozilla.firefox'
Generally, on UNIX systems you can expect all programs to reside in $PATH instead of being distributed in a hodge-podge collection of stupidly named and partially localized directories. So, essentially you don't need to find any dependency path - you just call the other "app" (program) via execvp, and the libc takes care of walking through the entries of $PATH and finding the executable.
In the classic UNIX model, you don't check anything in an installer, but just check at runtime whether an executable is available (with which, for example) or not.
The equivalent of a Windows Installer is the Linux Package Manager. The Package Manager handles dependencies and installs it (if it is not already present on the system). The dependency information for an application is stored within the package file. Each distribution has its own Package Manager, though the concept is the same.
There are plenty of resources online for specifics about a Package Manager. However, if you would like to get an overview in comparison with a Windows Installer, check out application management in GNU/Linux for Windows users.

Where to install SDK DLLs on a system so that they can be found by apps that need them

I've got an SDK I'm working on and the previous developer just dropped the DLLs in System32 (Apparently a serious offense: see here)
So assuming I move them out into \Program Files\\SDK (or whatever), how do I make sure that all the apps that needs those DLLs can access them? And to clarify, all apps that access these are doing early (static) binding to the DLLs at compile time so I can't pass the full path to them or anything. They need to be able to find it just given the DLL filename only.
Along the same lines, what about including a particular version of MSVCR80.dll? They all depend on this but I need to make sure they get a specific version (the one I include).
Any ideas?
An SDK is by definition a development kit. It's not a deployment patch...
What this means is that the applications that depend on those assemblies should ship with them and install them into their local \program files.. directories.
The reason for this is let's say you decide to do a breaking change by eliminating an entry point for example. By installing your "SDK", it has the potential to stop older programs from functioning.
You could take a play from the Java handbook and update the PATH environment variable. Whenever a program makes a call to an external assembly it searches along that environment variable until it finds it.
Of course, this could still result in the problem showing up. So your best bet is to just install the SDK into Program Files and let the developers of the products that depend on your toolkit decide whether they want to update their versions or not.
UPDATE
As I'm thinking about this, one last possibility is to GAC your assemblies. In the event you do so, bear in mind that they should be strongly named and properly versioned so as not to step on each other. I don't recommend this route because it hides the actual locations of the assemblies and makes uninstalling a little more difficult then simply hitting delete on your directory.
I can't tell you about your own DLLs, but you should never redistribute Microsoft DLLs alone.
You always have to use Microsoft Redistributable Package.
For example, if your application depends on dll from Dev Studio 2005 SP1, you should redistribute your application with Microsoft Visual Studio 2005 SP1 redistributable. The same applies to 2008. MS provide MSI based installer and Merge Module to include in your own product installer.
You are asking about "DLL Hell", something I had thought every Windows developer was familiar with. The order of search for DLLs is:
the directory the exex that calls them was loaded from
the current directory
various Windows directories (as discussed in your previous question)
directories in the PATH variable
As the Windows directories should be ruled out, that leaves you with three options.
You can put your install path in the search path, which will allow the applications to find them.
Alternatively, you can deploy the DLL's into the same directory as the application that depends on them.
I believe the first is better from an SDK perspective - it'll make development easier. But I think the second is better for when the application gets deployed to end-users, unless you expect there may be many consumers on a single system so the disk and memory footprint of having copies of the DLL are prohibitive.
If you can't install the dlls into the same directory as the exe using them you could append your directory to the PATH environment variable.
You don't say which version of Windows you're using, as the details are slightly different from what I remember.
You could also put your version of MSVCR80.dll in the same folder. However, you'd have to ensure that your folder was before the system one on the path otherwise the linker would pick up the "standard" one first. However, if you adopted the "local" dlls approach then you wouldn't have this problem as Windows searches the local directory first and so will pick up your version of MSVCR80.dll.
Is your version the latest or a previous version? You might be better off getting your app to work with that version or later and then allow the users to update their machines as required. This also illustrates why you should never mess with the dlls in \Windows or \Windows\system32 as, as others have pointed out, you could break other applications by changing the version of this dll.