I have a Java program that is mostly GUI and it shows data that is written to an xml file from a c++ command line tool. Now I want to add a button to the java program to refresh the data. This means that my program has to call the c++ functionality.
Is the best way to just call the program from java through a system call?
The c++ program will be compiled for mac os and windows and should always be in the same directory as the java program.
I would like to generate an executable can the c program be stored inside the jar and called from my program?
If you have access to the code and want an 'interactive' experience with the external program (e.g., make call, get results, make additional calls), investigate JNI, which allows you to call C or C++ code from a Java application by including & linking JNI juice to your C or C++ app with .
See:
http://en.wikipedia.org/wiki/Java_Native_Interface
http://www.acm.org/crossroads/xrds4-2/jni.html
If you really just need a "launch app and get results" sort of solution, check out Runtime.exec(), which lets you launch an external program & capture its output.
See:
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1
http://www.rgagnon.com/javadetails/java-0014.html
Assuming no better communication method is available (SOAP, ICE, Sockets, etc), I'd call the executable using Runtime.exec(). JNI can be used to interface directly, but I wouldn't recommended it. No you can't put an executable in the jar. Well you can, but you can't run it, since the shell doesn't know how to run it.
You may also want to look at the Java Native Access API (JNA).
To answer your final question, you can't run an executable from within your jar.
However, you can store it within your jar and extract it to a temporary directory/file prior to running it (check for its presence the first time and extract if necessary). This will simplify your distribution somewhat, in that you only have the jar to distribute, and ensures that you're running an executable that matches your jarred Java code.
Related
I am trying to implement something like virtual machine in Java. Yes, it NEEDS
to be made in java, since it wraps some already-coded java library and implements
it's abstractions. But on the problem...
The actual problem is that it is intended to run java programs written to be run
on UNIX platforms (e.g. They need to log to /var/log). I can load the jar, and launch it by invoking main method... But the real problem lies that whenever the file tries to access the filesystem, it crashes because the filesystem is not in proper format (e.g. It is missing /var/volatile as it is used commonly on embedded systems but rarely on full desktops). I am looking for a solution to translate default Java java.nio.File abstract pathnames to some other locations, or to make virtual FS in a file (like loop device), or anything similar, that would work like chroot for the program. I couldn't find a single soultion to this problem around the web. The real reason behind that is to allow users of any platform to run the VM without modifing the source code of the program being run in the VM.
Many Thanks.
From what I read, there are a couple of ways to run java files in a node.js application. One way is to spawn a child process: (the java code is packaged with dependencies in an executable jar.)
var exec = require('child_process').exec, child;
child = exec('java -jar file.jar arg1 arg2',
function (error, stdout, stderr){
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if(error !== null){
console.log('exec error: ' + error);
}
});
The other way is to use the java - npm module (link), a wrapper over JNI (this will let me create objects, set and get attributes, run methods).
In a production environment, when I want my node.js (Express) server to call a java program (it just saves an image to the local directory), please advise me on which would be the better way to accomplish this (in terms of best practices). Also, there is a long list of arguments that I need to pass to the main class and doing that on the command line is a bit of a struggle. Should I make the java program read from an input file instead?
1) If you use exec, you will run an entire program, whereas if you use a JNI interface, you'll be able to directly interact with the libraries and classes in the jar and do things like call a single function or create an instance of a class. However, if you don't need anything like that, I think using exec is far simpler and will also run faster. Sounds like you just want to run the Java application as a standalone process, and just log whether the application finished successfully or with errors. I'd say it's probably better to just use exec for that. Executing a child process this way is also far better for debugging, debugging JNI errors can be very difficult sometimes.
2) As for whether or not to read arguments from a file, yes, it's usually better to read from some sort of file as opposed to passing in arguments directly. It's less prone to human error (ie. typing in arguments every time), and far more configurable. If someone like a QA engineer only needs to edit a config file to swap out options, they don't need to understand your entire codebase to test it. Personally I use config files for every Java program I write.
You can use deployment toolkit and run the jar through jnlp. https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_toolkit.html
Advantage of running jars through jnlp is the ability to pass parameters from javascript to your jar. In this way you can dynamically customize your java program.
For this kind of problem you'd want to approach it in the following way:
Is there a decent way to run processes with arguments in my language/framework
Is there a decent way to deal with the programs output?
From experience, a decent way to deal with arguments in a process is to pass them as an (string) array. This is advantageous in that you do not have to resort to unnecessary string interpolation and manipulation. It is also more readable too which is a plus in this problem setting.
A decent way to deal with output is to use a listener/event based model. This way, you respond appropriately to the events instead of having if blocks for stderr and stdout. Again, this makes things readable and let's you handle output in a more maintainable manner.
If you go a bit further into this, you will also have to solve a problem of how to inject environment variables into your target program. As an example, you might want to run the java with a debugger or with less memory in the future, so your solution would also need to cater for this.
This is just one way of solving this kind of problem. If node is your platform, then have a look at Child Process which supports all of these techniques.
We can run the whole java project by making .jar file of it and run it using the command in the shell and run that shell file. In order to run java code from nodejs project as we know project could be a mix of java, js modules.
Call exec() function in node to create a child process to execute the shell file having a command to run .sh file and can also pass some argument in it from use.eg;
let fileName = 'someFile.txt';
let userName = 'Charlie Angle';
exec(`sh run.sh --context_param
paramFilePath="./storage/${fileName}" --context_param userName="${userName}"`, (error, stdout, stderr) => {// Some code based on execution of above command})
You can simply call a java command , with classpath & arguments, using module node-java-caller, it embeds the call to spawn and will also automatically install java if not present on the system
https://github.com/nvuillam/node-java-caller
I have created a C++ dll for a java application. I have the dll working within the application if I launch it separately, which includes a very lengthy batch file to get all of the correct arguments. I would like to try an debug the dll that I created in Visual Studio 2010. I have tried putting the command line and arguments into the debugging property page in visual studio. Although I am not able to get the application to launch correctly.
The command line to launch the application looks like this assuming the application is ApplicationName...
start "ApplicationName" "C:\AppDirectory\jre\bin\javaw" -D sun.java2d.nodraw=true -Xms24m -Xmx128m -classpath "C:\AppDirectory\classes\;C:\AppDirectory\classes\iText.jar" ApplicationName
Any ideas on how to property setup the debug settings for this?
Any ideas on where I could find some documentation on this?
I would strongly consider the following:
If possible, structure the JNI such that the code which does the work knows nothing about JNI. Have it receive only native C++ stuff as arguments and return native C++ stuff as return values, and not call any JNIEnv functions.
Have a shim layer that has the actual implementations of the native methods in your Java classes. The shim layer will know how to call JNIEnv functions to extract the parameters, turn them into native C++ objects and pass them to the working code. Likewise, this layer will know how to turn the C++ objects back into Java objects. For example, if a worker function returns a std::string, the shim layer will know how to call JNIEnv functions to have the native method return a Java String back to the JVM.
I understand that things can't always be structured this way, but there are some nice advantages to it:
It will allow you to write a C++ program to drive the worker code directly. This can make it much faster and easier to test your code rather than having to manipulate your Java app into a state where it is using your code how you want to test.
You will be able to run just your code under a debugger, valgrind, memory profilers, etc. without having to run the whole JVM under the tool. This makes it much easier to pin down what memory may be being leaked, buffers overrun, etc. without being swamped in "noise" caused by JVM internal operations.
It is true that this approach means the shim layer isn't being tested. But since the shim layer is only translating objects between the Java world and the C++ world it is hopefully pretty simple and thus amenable to being testing in the context of the full Java app.
In my application I added logic that checks a command line option at startup and calls DebugBreak if the command line option was passed to it.
I did this because my application is often called in quite complex scripts and it was sometimes very hard or even impossible to launch the application from the debugger with the correct environment (path, environment variables, temporary files, ...) set by the script.
So, simply call DebugBreak (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms679297%28v=vs.85%29.aspx) if a specific command line option is passed to your DLL.
When the breakpoint goes off, the JIT debugger will show a popup in which you can start or attach your debugger.
I have an strange issue.. I have source code of JAGS software which I can compile in solaris i86 and it generates an executable file.. and it was working fine... now issue is
I want to call this executable file from JAVA and wish I was able to do that..
Now I want to use the same source code without executable file and want to create an shared object which can be triggered from java usin JNI.
Is it possible to modify the make file and generate a shared object instead of an executable file?
You can call an executable from java. Just a matter of:
String[] cmd = { "/path/to/program", "arg1", "arg2" };
Process proc = Runtime.getRuntime().exec( cmd );
You can then use proc to communicate with the command via standard I/O streams, and to wait for it to finish.
Now if you wanted to go down the JNI path you will need to write some additional code to act as the JNI layer between the java and C. This layer is responsible for keeping track of the allocated C memory and converting between C data types and Java datatypes. This layer would then be able to call functions in your other source code (but probably not the main function). Then you need to modify/create a makefile which links your new JNI layer source code with the source code you already have into a .dll/.so. You then need to write the java class(es) that sit atop your JNI layer.
Which approach you choose really depends on what you want the native code to do, and how much interaction you need with it.
I need to be able to change the working directory in MATLAB without interacting with the command window. I'm launching MATLAB from a Java application. Right now the only solution I've come up with is closing MATLAB, changing directory from JAVA and relaunching. Is there some streamlined way to send MATLAB the 'cd' command from JAVA? Doing so from the command-line would also work, since I could use getRuntime().exec(command)
Thanks!
You can do this using JMI if you're using the same JVM as Matlab (if not then I have no idea). There is not much online info about this (it's WAY undocumented/unsupported). Google it or read this: http://www.cs.virginia.edu/~whitehouse/matlab/JavaMatlab.html. In short, you need to include Matlab's relevant JAR file and then use com.mathworks.jmi.Matlab's functionality. For example:
Matlab.evalConsoleOutput("cd('C:\Program Files\')");
Yair Altman
http://UndocumentedMatlab.com
I am working with Stephen Poletto who posted the original question. There wasn't any existing solution that met our needs so we wrote our own solution based off of Kamin Whitehouse's work mentioned by Yair. It is available for all to use at matlabcontrol.googlecode.com
It allows for controlling MATLAB from a Java program launched outside of MATLAB.