Java calling an external process - exe - java

I am building a java application, which at some point utilizes an external exe. At this point, I'm trying to simply add this exe as some sort of library, which I can use in process call, so user wouldn't have to install it..
This exe file is an command line tool which produces some output, which is further processsed by the application.
So my question is, how does one include exe file within a java application, instead of calling it as a system process. Also acceptable would be, if this exe would be for example in the final lib folder, where java app would fetch it and execute it.
I hope it is clear and thanks for any help.

Java interacts with other (native) code in a couple of ways:
to specifically coded libraries through Java Native Interface (JNI)
to external tools by forking a child process using Runtime.getRuntime().exec(...)
through network communications
In the first case, it is useful to include your JNI library with you Java program. It's thinkable to include it as a class resource in your JAR file, but that would be against the ideas of JAR files (holding classes and resources). More likely you should bundle the library (for all target platforms) with some sort of installation package (e.g. InstallAnywhere or others)
In the second case it's not useful to include the binary into your Java program (i.e. in the JAR file). Rather it most likely has (should have) its own installation procedure and your Java code should use an appropriate commandline (PATH) to find the executable.
I think the third case is not relevant.

Related

Compile python files + all dependecies + intepreter into one java\.net (dll or exe) file?

I have a couple of python files with some dependencies on third-party libraries, like pyaudio. So is there a way to compile everything including python intepreter itself into one .jar\dll file to use them in java\android or xamarin\ .net core, without actual installing python + doing pip install every time?
Also as an option - compile into c\c++?
You can use PyInstaller to create an executable.
Use this command:
pyinstaller --onefile <your_script>.py
https://medium.com/dreamcatcher-its-blog/making-an-stand-alone-executable-from-a-python-script-using-pyinstaller-d1df9170e263
I do not know about compiling into C, but for compiling executables in general you can use pyinstaller, cx_freeze, or a few other less common modules to create an executable folder which contains all the .dll files to run the program. I only have experience with cx_freeze so I'll discuss that here. If your goal is to have the end-user have only 1 "file" show up when they download it you need to use an installer program. To semi-quote cx_freeze documentation at: https://cx-freeze.readthedocs.io/en/latest/faq.html
cx_Freeze does not support building a single file exe, where all of the libraries for your application are embedded in one executable file. [There are modules that do this, but it's my understanding they use "hacks" that can get them flagged by antivirus software.]
You can use IExpress to compress the build directory from cx_Freeze into a self-extracting archive: an exe which unpacks your application into a temporary directory and runs it. IExpress is a utility that’s included with Windows, intended for making installers, but it works equally well if you tell it to run the cx_Freeze-built exe after extraction.
Alternatively, you can create a self extracting archive using 7zip. This is a bit more complex than using IExpress, but might provide more flexibility, and allows you to build your application using only open source tools.
Alternatively you can compile with python setup.py bdist_msi to create a single .msi file which will let the user choose where they want to install the program. At the end of the day the user will still have a directory with all the .dll files and whatnot, but they get to choose where they tuck that stuff away on their hard drive! I think this is the method most applications I've installed use. This is assuming you develop on Windows as well, if not you should include your OS on your post.

JNI to call .NET dll

I am trying to create a Java Application that will call C# dll through an intermediate Visula C++ dll, its all well and good when I try to run the .class file from cmd prompt or Eclipse IDE but the problem is in order to do it I need to place the C# dll in the same directory as the Java.exe or else there occurs an exception the the native call, thus making to impossible to build the Java Project, any idea as to how this can be done
There are other ways, without COM. You might find one preferable or need one if you can't change the .NET component to support COM clients.
When a process that loads the CLR, the assembly search paths are determined by the location of the process's main Win32 module. Assembly search paths are different than Win32 DLL search paths. In this case, it starts with the location of java.exe. As a result, the search paths include the Global Assembly Cache (GAC), the folder of java.exe, and subfolders listed as assembly probing paths in java.exe.config (if it exists).
See How the Runtime Locates Assemblies.
This leads to a few options:
Install the assembly in the GAC. (On an end-user machines an installer should be used but on a developer machine, you can use gacutil.)
Put the assembly in the java.exe folder. Or, conversely, put a copy of Java in your application folder.
Create a subfolder with write permissions for the assembly. Create or update a java.exe.config and list the subfolder as a probing path.
Create your own java.exe in C or C++ using the Java Invocation API. It's documented alongside JNI. You can name it whatever you wish since, after all, it is your application. (This what many Java-based applications do, even if they don't use .NET. For example, eclipse and LibreOffice.) The documentation gives a complete example in C. For a typical MSVC build, jni.h needs to on the project's include path, jvm.lib needs to be on the project's library path, and jvm.dll needs to be in the Win32 DLL search path.
Other alternatives:
The VC DLL can load the assembly explicitly from a path before the assembly is needed. See Assembly::LoadFile.
Load the assembly on demand after it's not found by the standard search. See AppDomain::AssemblyResolve Event (but note it's description is wrong: failure has not occurred until and if your custom resolver(s) fails).
You can enable and register your managed (.NET) dll with COM Interop.
See this link: http://support.microsoft.com/kb/828736

What is the file type for the final java application?

I finished a small program. What is the standard file type for the final application written with Java, so it can be run on any computer, easily and without any computer knowledge?
I've been told it's JAR, but Eclipse for example is an .exe file.
What's the standard file type for big, normal applications in Java?
Are most applications distributed in JAR, or rather in .exe or something else?
Serious desktop applications are packaged with platform-specific launchers, which are not written in Java. The launcher must first find out how to run the JVM installed on the system, and then pass it either the path to the executable JAR to run, or the complete classpath along with the name of the main class.
In other words, "it's complicated".
Most desktop applications are distributed using .jar files. A .exe is windows-specific, and non-portable across different operating systems. It's easy to find installers (or "launchers") that will simplify the distribution of a Java program in other platforms, but anyway you'll find that .jar files are the usual packaging mechanism.
If you have a small, simple Java program the easiest approach to distribute it would be to pack it in a .jar, making sure to make it executable. And remember, the computer where your code is expected to run must have installed some version of Java, be it JRE or JDK.
Desktop java applications are usually distributed as jar files.
JRE can launch a runnable jar file using -jar param.
You have one of several options:
1 - Create an executable jar file. By providing information in a manifest within the jar file users can simply execute the jar file by however system-dependent means exist for their OS.
2 - Write a batch file or shell script to invoke the JRE against your jar file (and specify command line parameters for, eg: the main class, the classpath, JVM options, etc.)
3 - Use a tool like jexepack or jsmooth to wrap your Java code within a native executable. I've only ever used these to create Windows binaries - there may be other options for other platforms but shell scripts are typically easier to work with here.

Converting dll to jar

I'm trying to find a way to convert a dll to a jar file. I have a .net application that communicates with a java application. The core entities are .net objects which I have to duplicate manually in java.
I've read about IKVM but it seems that it converts only jars to dlls and not the other way around.
Edit: If there is a tool that creates java classes from a dll it is also fine.
Thanks in advance
There isn't such a tool.
A dll is a natively compiled library. That means its been compiled down to machine code. Probably compiled by a C/C++/C# compiler.
A jar file is a zip file that contains '.class' files, which are files compiled down to 'java virtual machine code'. Probably compiled by a java/clojure/scala compiler.
These are two very different incompatible things.
It's not impossible to create such a tool that would do this translation, but it would definitely be an extremely difficult task, as it would entail translating from one machine code, to another, and would need to manage multiple issues like dependency solving, different type structure etc.
HOWEVER, I'm imagining that you want to do this because you want to use a DLL within some java code. That is somewhat possible, but is actually quite complicated. You'll need to use the JNI.
Take a look at this question as it might help you achieve what you want to do:
Calling C++ dll from Java
This is actually an easy task to perform. Converting .dll to .jar is as simple as using com4j and a couple of commands on the command line.
Download com4j.
Open command line and navigate to com4j directory in above step.
Execute below command.
java -jar tlbimp.jar -o outputFolder -p nameOfPackage "pathToFile"
Then jar the results with the following:
jar cf desiredJarName.jar folderYouWantJard

JNI-wrapped library seeks out wrong working directory -- how to circumvent?

I am using JNI to wrap a few native functions in a closed-source PDF library. It has an dependent fonts directory which must be in a subfolder of the calling application's directory. In my experience, it is standard to seek based on the current working directory. Thus, the problem.
When loading the JNI code into a Java application, the current working directory is correct. However, the calling application's directory is java.exe's bin directory. I have verified that putting the dependent fonts folder in C:\Program Files (x86)\Java\jre6\bin folder works as expected.
The library seems to be using a C++ GetCommandLine() call, or something similar to determine where the fonts directory should be. Obviously, this is an unacceptable solution.
I'd like to avoid calling an external EXE. But the only workarounds that I've come up with are:
Compile an EXE, place in Java project directory, and use Java's Runtime.exec() to execute. (this does work)
Make JNI code launch a separate process which does the same as above (gains nothing but more complexity)
Any ideas on how I can circumvent this problem? When Java applications are compiled as a runnable JAR, is the resultant command line still the JRE's C:\Program Files\...java.exe?
A Java executable maker can create an executable *.exe from your Java application without any native coding or compiling. You can put that executable, the jar files, the fonts and other application dependencies into a single install directory.
Exe4j is one of the executable makers that will support this, for Windows. It does not require any assumptions about the current working directory. This is important in the frequent case where you have no control over what the working directory is when the application is launched.

Categories

Resources