13

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?

2
  • If your input is complex enough, I recommend creating POJOs that represent your input data and using Jackson YAML factory to deserialize your input as a JSON or YAML file (YAML will also parse JSON). Then use Args4J and accept the JSON as a File Option as well as have an option for input like -i that tells you to read the input from stdin so that the JSON can be piped in from another program. This lets them have a template that they can do simple token replacement with then pipe to your program. Or you can do the same thing from node for that matter. Commented Apr 20, 2017 at 21:22
  • On further thought, it looks like sending your data to the java program via stdout/stdin would make the most sense. Having a temp file you create then load from the java program just isn't necessary and introduces an IO bottleneck Commented Apr 20, 2017 at 21:28

5 Answers 5

6
+25

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

3 Comments

Can I pass parameters that are not Strings (like an Array)?
I've just tried that. I passed ` ['asd', 'qwe', 'zxc'] ` and received it as comma separated string "asd,qwe,zxc" which easily can be split by comma and converted to array
Yeah, but some of the elements could have commas in them too.
0

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.

Comments

0

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})

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.