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.
Related
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 would like to know how to call and execute a matlab function with parameters using java and capture the output in java.
I see different options.
Create a JAR from your code, using the Builder JA.
Use matlabcontrol, which is a 3rd party automation server:
Use the MatlabControl.java, which allows to run matlab code from java running within the matlab JRE. enter link description here
While the Builder JA is expensive and the options 2 and 3 might get you in truble with future matlab versions, using the matlab CLI is another possibility which probably does not cause any maintenance. For parameters and return, I would use a file. The main disadvantage is a new matlab session starting for each call, which needs some time.
I have a Java application that is designed to run on removable drives. I would like to add a button to allow the user to safely remove the drive the program runs on as USB Disk Ejector allows. However, I'm not sure how to achieve this (code wise) as the drive cannot be ejected if the program is running from it. I know that this program is open source, but I don't know where to find the code I am looking for and it isn't written in a language I have learnt.
I would therefore very much appreciate it if somebody could help me work out how to achieve this functionality in my Java application. Obviously I don't want to just copy, but the only thing I know at the minute is I have to pass control over to some sort of temporary script that is not on the drive I wish to eject.
Thanks in advance
As far as I know, it is not possible to implement this in pure Java as operations such as ejecting/unmounting drives are operating system-specific and not included in the default Java library which usually only supports the lowest common denominator. You need to execute some platform-specific code either by executing a script/batch file or by running native code written e.g. in C using Java's JNI mechanism.
You're right that you will need to run the application from another drive. I would follow the Java Web Start CD Install guide, which should work just as well for a USB drive or any other media as it does for CDs.
You would need to make your application a Java Web Start application. It's actually much easier than it sounds; your .jar does not need to change, you just create a small XML file with a .jnlp extension and place it next to the .jar file. Information on Java Web Start and JNLP files can be found in the tutorial and in the links at the bottom of that page.
Your external executable which performs the safe removal can be included in your application .jar file. You can copy it from your .jar to a temporary file in order to run it:
Path safeRemovalProgram = Files.createTempFile(null, ".exe");
try (InputStream stream =
MyApp.class.getResourceAsStream("saferemoval.exe")) {
Files.copy(stream, safeRemovalProgram,
StandardCopyOption.REPLACE_EXISTING);
}
safeRemovalProgram.toFile().setExecutable(true);
ProcessBuilder builder =
new ProcessBuilder(safeRemovalProgram.toString());
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
Process safeRemovalProcess = builder.start();
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 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.