how to call Nodejs function from java - java

I want to call node js function from java:
here is my hello.js javascript code:
function myFun(param)
{
console.log("hello"+param);
}
here is my java code:
public static void main(String[] args) throws IOException {
Process process = new ProcessBuilder("C:\\Program Files\\nodejs\\node.exe","hello.js").start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
With this java code i am able to execute hello.js file but i want to call myFun function and set the parameters in this function from java code .. is it possible to do this.

You can use GraalVM to call node.js function from java.
GraalVM offers you a polyglot runtime and the distribution includes both a JDK and a node.
You can execute JavaScript from Java, embedding the JavaScript context in your Java program, like this:
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.proxy.*;
public class HelloPolyglot {
static String JS_CODE = "(function myFun(param){console.log('hello '+param);})";
public static void main(String[] args) {
System.out.println("Hello Java!");
try (Context context = Context.create()) {
Value value = context.eval("js", JS_CODE);
value.execute(args[0]);
}
}
}
Note the () wrapping the function definition, I just want it to return the function immediately there. You can use other ways too, not just code in String too, Files, modules, etc.
And run it with GraalVM on the PATH:
❯ javac HelloPolyglot.java
❯ java HelloPolyglot StackOverflow
Hello Java!
hello StackOverflow
While it's not strictly necessary for this question, here's the Javadoc for the Value class so you can use the polyglot values.
This way you can use JavaScript. It won't have the platform capabilities node.js offers like the node event loop, fs access, etc, node is a separate platform and it's tricky to embed that into a JVM process.
What you can do -- is start the node process, which will start the JVM.
Imagine you have an app like app.js
var HelloPolyglot = Java.type("HelloPolyglot");
HelloPolyglot.main(["from node.js"]);
console.log("done");
You can then run (with GraalVM node):
❯ node --jvm --vm.cp=. app.js
Hello Java!
hello from node.js
done
Note that we pass --jvm to start it with the JVM (otherwise there'll be no capabiltiy to do Java), and pass the classpath of the Java program to the node so it knows how to start the JVM properly.
Both node and JVM then run in the same process, and the interop works using the same Value classes as above.

It's not that easy. You have a few possible methods to do that:
Use JNI-Bindings to V8 (Node.js is just V8 with a big library and some glue).
Use ProcessBuilder and pass the arguments.
(It's not exactly what you asked for) Use a Javascript-Engine written in Java (GraalVM)
Pros/Cons
Has the advantage, that it may give you a lot of control (==>More flexible), but writing JNI is hard, error-prone and time-consuming.
is the most simple solution, but not that flexible.
is maybe another solution, that can be superior to 1. (No need to ship native libraries) and 2. (Very fragile, as you need a specific location for node.exe).

I would suggest looking into https://github.com/caoccao/Javet, it allows you to embed a node.js runtime into a java application.

Related

Fortify issue - Command Injection

I am trying to do hp fortify security scan for my java application. I have few issues and i have fixed it. But i am unable to find the fix for the below issue.
Command Injection
String hostname = execReadToString("hostname").split("\\.")[0];
public static String execReadToString(String execCommand) throws IOException {
try (Scanner s = new Scanner(Runtime.getRuntime().exec(execCommand).getInputStream()).useDelimiter("\\A")) {
return s.hasNext() ? s.next() : "";
}
The method execReadToString() calls exec() to execute a command. This call might allow an attacker to inject malicious commands.
So i have tried with process builder also.
private static void gethostname(String cmd1) throws IOException {
if(Pattern.matches("[A-Za-z]+", cmd1)) {
ProcessBuilder pb = new ProcessBuilder(cmd1);
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String readline;
while ((readline = reader.readLine()) != null) {
System.out.println(readline);
}
}
}
Even this is giving me an security issue This start() call might allow an attacker to inject malicious commands.
What will be the ideal fix for this issue?
Thanks in advance
Usually this is because you're using user input to frame the command string, wherein user can inject malicious code to manipulate what command is being run ultimately (even if you add validation there will be ways to circumvent that).
In your case you seem to be hardcoding the command so this shouldn't be a problem, however, see the OWASP page on hardcoded command invocation (emphasis mine):
Unlike the previous examples, the command in this example is
hardcoded, so an attacker cannot control the argument passed to
system(). However, since the program does not specify an absolute path
for make, and does not scrub any environment variables prior to
invoking the command, the attacker can modify their $PATH variable to
point to a malicious binary named make and execute the CGI script from
a shell prompt. And since the program has been installed setuid root,
the attacker's version of make now runs with root privileges.
The environment plays a powerful role in the execution of system
commands within programs. Functions like system() and exec() use the
environment of the program that calls them, and therefore attackers
have a potential opportunity to influence the behavior of these calls.
Resolution:
Use native Java APIs / libraries to achieve what you want, instead of running a command - this is probably the best option. Use commands only when unavoidable, eg: 3rd party tools which do not have a Java client library. This approach has the added advantage of being more portable and in most cases, more efficient too. This library might help your scenario.
If you have to run a command, ensure you do not use user-supplied or external data even indirectly to construct it.
Or if you're hardcoding the command to run from the code, use absolute path to the command and do not use environment variables as part of it. For hostname (assuming you use the built-in command) this is usually /usr/bin/hostname but you can find the command path for your environment using which hostname.

java.lang.UnsatisfiedLinkError when loading .dll

I am trying to use a public interface in a .dll file in JAVA. This is what a public interface in the .dll shows:
// Interface declaration.
public interface ISslTcpClient
{
string Encrypt(string requestContent);
string Decrypt(string requestContent);
};
Here is how I load my dll and use it in my Java application in eclipse:
public class NJInew {
static {
System.loadLibrary("ICVTnsClient");
}
native String Encrypt(String requestContent);
public static void main(String[] args) {
NJInew p= new NJInew ();
p.Encrypt("pejman");
}
}
However I get the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: NJInew.Encrypt(Ljava/lang/String;)Ljava/lang/String;
at NJInew.Encrypt(Native Method)
at NJInew.main(NJInew.java:13)
Please let me know how to fix this issue and I would greatly appreciate it.
I do not understand how the native DLL can possibly look like a Java interface. Are you sure it's a JNI DLL? You can't call any old DLL from Java. If it isn't a JNI DLL you'll either need to add the required JNI entry points to it, starting with the javah tool, or write a wrapper DLL that contains those and calls this one.
This interface looks definitely like written in .NET C#. Therefore you do not need to call native DLL but managed .NET DLL and that is completely different topic.
You can achieve it yourself by wrapping .NET DLL with native C++ code and calling it from JAVA but number of obstacles and challenges is huge... You need to take care of type conversion, memory management, threads, C++ runtime depndencies and more... so that approach is not recommended.
What you should look for is native bridge like Javonet which takes care of all those things for you and makes sure you can run your code on any machine.
Using your interface would like like this:
Javonet.addReference("ICVTnsClient.dll");
NObject client = Javonet.New("SslTcpClient");
//some concreto type which implements this interface
String encryptedStr = client.invoke("Encrypt", "some string");
You can get free license for academic and non-commercial usage or try the free trial: http://www.javonet.com

How to execute a python script from a Java program using jython? [duplicate]

What's the easiest way to execute a Python script from Java, and receive the output of that script? I've looked for different libraries like Jepp or Jython, but most appear out of date. Another problem with the libraries is that I need to be able to easily include a library with the source code (though I don't need to source for the library itself) if I use a library.
Because of this, would the easiest/most effective way be to simply do something like call the script with runtime.exec, and then somehow capture printed output? Or, even though it would be very painful for me, I could also just have the Python script output to a temporary text file, then read the file in Java.
Note: the actual communication between Java and Python is not a requirement of the problem I am trying to solve. This is, however, the only way I can think of to easily perform what needs to be done.
Not sure if I understand your question correctly, but provided that you can call the Python executable from the console and just want to capture its output in Java, you can use the exec() method in the Java Runtime class.
Process p = Runtime.getRuntime().exec("python yourapp.py");
You can read up on how to actually read the output from this resource:
http://www.devdaily.com/java/edu/pj/pj010016
import java.io.*;
public class JavaRunCommand {
public static void main(String args[]) {
String s = null;
try {
// run the Unix "ps -ef" command
// using the Runtime exec method:
Process p = Runtime.getRuntime().exec("ps -ef");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
}
There is also an Apache library (the Apache exec project) that can help you with this. You can read more about it here:
http://www.devdaily.com/java/java-exec-processbuilder-process-1
http://commons.apache.org/exec/
You can include the Jython library in your Java Project. You can download the source code from the Jython project itself.
Jython does offers support for JSR-223 which basically lets you run a Python script from Java.
You can use a ScriptContext to configure where you want to send your output of the execution.
For instance, let's suppose you have the following Python script in a file named numbers.py:
for i in range(1,10):
print(i)
So, you can run it from Java as follows:
public static void main(String[] args) throws ScriptException, IOException {
StringWriter writer = new StringWriter(); //ouput will be stored here
ScriptEngineManager manager = new ScriptEngineManager();
ScriptContext context = new SimpleScriptContext();
context.setWriter(writer); //configures output redirection
ScriptEngine engine = manager.getEngineByName("python");
engine.eval(new FileReader("numbers.py"), context);
System.out.println(writer.toString());
}
And the output will be:
1
2
3
4
5
6
7
8
9
As long as your Python script is compatible with Python 2.5 you will not have any problems running this with Jython.
I met the same problem before, also read the answers here, but doesn't found any satisfy solution can balance the compatibility, performance and well format output, the Jython can't work with extend C packages and slower than CPython. So finally I decided to invent the wheel myself, it took my 5 nights, I hope it can help you too: jpserve(https://github.com/johnhuang-cn/jpserve).
JPserve provides a simple way to call Python and exchange the result by well format JSON, few performance loss. The following is the sample code.
At first, start jpserve on Python side
>>> from jpserve.jpserve import JPServe
>>> serve = JPServe(("localhost", 8888))
>>> serve.start()
INFO:JPServe:JPServe starting...
INFO:JPServe:JPServe listening in localhost 8888
Then call Python from JAVA side:
PyServeContext.init("localhost", 8888);
PyExecutor executor = PyServeContext.getExecutor();
script = "a = 2\n"
+ "b = 3\n"
+ "_result_ = a * b";
PyResult rs = executor.exec(script);
System.out.println("Result: " + rs.getResult());
---
Result: 6
Jep is anther option. It embeds CPython in Java through JNI.
import jep.Jep;
//...
try(Jep jep = new Jep(false)) {
jep.eval("s = 'hello world'");
jep.eval("print(s)");
jep.eval("a = 1 + 2");
Long a = (Long) jep.getValue("a");
}
I've looked for different libraries like Jepp or Jython, but most seem to be very out of date.
Jython is not "a library"; it's an implementation of the Python language on top of the Java Virtual Machine. It is definitely not out of date; the most recent release was Feb. 24 of this year. It implements Python 2.5, which means you will be missing a couple of more recent features, but it is honestly not much different from 2.7.
Note: the actual communication between Java and Python is not a requirement of the aforementioned assignment, so this isn't doing my homework for me. This is, however, the only way I can think of to easily perform what needs to be done.
This seems extremely unlikely for a school assignment. Please tell us more about what you're really trying to do. Usually, school assignments specify exactly what languages you'll be using for what, and I've never heard of one that involved more than one language at all. If it did, they'd tell you if you needed to set up this kind of communication, and how they intended you to do it.
Jython approach
Java is supposed to be platform independent, and to call a native application (like python) isn't very platform independent.
There is a version of Python (Jython) which is written in Java, which allow us to embed Python in our Java programs. As usually, when you are going to use external libraries, one hurdle is to compile and to run it correctly, therefore we go through the process of building and running a simple Java program with Jython.
We start by getting hold of jython jar file:
https://www.jython.org/download.html
I copied jython-2.5.3.jar to the directory where my Java program was going to be. Then I typed in the following program, which do the same as the previous two; take two numbers, sends them to python, which adds them, then python returns it back to our Java program, where the number is outputted to the screen:
import org.python.util.PythonInterpreter;
import org.python.core.*;
class test3{
public static void main(String a[]){
PythonInterpreter python = new PythonInterpreter();
int number1 = 10;
int number2 = 32;
python.set("number1", new PyInteger(number1));
python.set("number2", new PyInteger(number2));
python.exec("number3 = number1+number2");
PyObject number3 = python.get("number3");
System.out.println("val : "+number3.toString());
}
}
I call this file "test3.java", save it, and do the following to compile it:
javac -classpath jython-2.5.3.jar test3.java
The next step is to try to run it, which I do the following way:
java -classpath jython-2.5.3.jar:. test3
Now, this allows us to use Python from Java, in a platform independent manner. It is kind of slow. Still, it's kind of cool, that it is a Python interpreter written in Java.
ProcessBuilder is very easy to use.
ProcessBuilder pb = new ProcessBuilder("python","Your python file",""+Command line arguments if any);
Process p = pb.start();
This should call python. Refer to the process approach here for full example!
https://bytes.com/topic/python/insights/949995-three-ways-run-python-programs-java
You can try using groovy. It runs on the JVM and it comes with great support for running external processes and extracting the output:
http://groovy.codehaus.org/Executing+External+Processes+From+Groovy
You can see in this code taken from the same link how groovy makes it easy to get the status of the process:
println "return code: ${ proc.exitValue()}"
println "stderr: ${proc.err.text}"
println "stdout: ${proc.in.text}" // *out* from the external program is *in* for groovy
First I would recommend to use ProcessBuilder ( since 1.5 )
Simple usage is described here
https://stackoverflow.com/a/14483787
For more complex example refer to
http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html
I've encountered problem when launching Python script from Java, script
was producing too much output to standard out and everything went bad.
The best way to achieve would be to use Apache Commons Exec as I use it for production without problems even for Java 8 environment because of the fact that it lets you execute any external process (including python, bash etc) in synchronous and asynchronous way by using watchdogs.
CommandLine cmdLine = new CommandLine("python");
cmdLine.addArgument("/my/python/script/script.py");
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);
Executor executor = new DefaultExecutor();
executor.setExitValue(1);
executor.setWatchdog(watchdog);
executor.execute(cmdLine, resultHandler);
// some time later the result handler callback was invoked so we
// can safely request the exit value
resultHandler.waitFor();
Complete source code for a small but complete POC is shared here that addresses another concern in this post;
https://github.com/raohammad/externalprocessfromjava.git

redirect System.out to page

I am running a Java application through my JSP page.
is it possible to redirect everything that the Java app prints into System.out into my page?
Edit:
I have a package pkg which contains a main function. this function has lots of System.out.println calls. e.g.
package pkg;
public class pkg {
public static void main(String[] args) {
System.out.println("Hello");
}
}
In my index.jsp I call:
<%
pkg.pkg.main(new String[] {});
%>
I need to see everything the pkg.pkg.main prints on the page. e.g.
Hello
A naive approach would be to call System.setOut() with a suitably wrapped response output stream. However, this would not work once multiple concurrent requests kick in, as there would be no differentiation between the outputs from the different threads.
You could create your own output stream subclass that delegates to another thread-local output stream which you set to your response's output stream before invoking your pkgmain() method on each request. If your pkgmain() spawns additional threads then this approach might not work (though you could try using InheritableThreadLocal in this case).
Refactor the code of the called class so that it takes a Writer as argument, and print to this Writer rather than System.out:
package pkg;
public class pkg {
public static void main(String[] args) {
main(new OutputStreamWriter(System.out), args);
}
public static void main(Writer writer, String[] args) {
PrintWriter out = new PrintWriter(writer);
out.println("Hello");
}
}
and call this second main method from your JSP (which should be a servlet):
<%
pkg.main(out, new String[] {});
%>
Another approach, if you can't edit the source code of the to be executed class, is to use Runtime#exec() to execute the class programmatically using the java command the usual way like as you would execute it in command prompt and then capture its stdout (and stderr!) by Process.
Process process = Runtime.getRuntime().exec("java -cp /path/to/your/pkg pkg.pkg");
InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();
// Read and write it to response.getOutputStream() the usual way.
If you have never really used Runtime#exec() before, I strongly recommend to read this well known JavaWorld article (all the 4 pages) to learn and understand its caveats.
Last but not least, keep in mind that Java/JSP code runs physically in the machine where the webserver runs (the server side), not where the webbrowser runs (the client side) and also that the webserver's Java run time security manager should allow executing Runtime#exec() from inside a webapp. If you intend to deploy this app to a 3rd party host on which you don't have control over the security manager, chances are big that Runtime#exec() call will be blocked and throw SecurityException.
Needless to say, this is all pretty smelly. If those classes concerns user-controlled code, you're putting possibly huge security exploit holes open.

how to use java to get a js file and execute it and then get the result

How can I use java to get a js file located on a web server, then execute the function in the js file and get the result and use the result in java.
Can you guys give me some code snippet? Great thanks.
You can use the scripting engine built into Java:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public static void main(String[] args) throws Exception {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
Object result = engine.eval("my-java-script-code")
System.out.println("Result returned by Javascript is: " + result);
}
Here is a more elaborate example.
There's three steps to this process:
Fetch the JS file from the server.
Execute some JS function from the file.
Extract the result.
The first step is fairly simple, there are lots of HTTP libraries in Java that will do this - you effectively want to emulate the simple functionality of something like wget or curl. The exact manner in which you do this will vary depending on what format you want the JS file in for the next step, but the process to get hold of the byte stream is straightforward.
The second step will require executing the JS in a Javascript engine. Java itself cannot interpret Javascript, so you'd need to obtain an engine to run it in - Rhino is a common choice for this. Since you'd need to run this outside of Java, you'll likely have to spawn a process for execution in Rhino using ProcessBuilder. Additionally, depending on the format of the Javascript you might need to create your own "wrapper" javascript that functions like a main class in Java and calls the method in question.
Finally you need to get the result out - obviously you don't have direct access to JavaScript objects from your Java program. The easiest way is going to be for the JS program to print the result to standard out (possibly serialising as something like JSON depending on the complexity of the object), which is being streamed directly to your Java app due to the way you launched the Rhino process. This could be another job for your JS wrapper script, if any. Otherwise, if the JS function has observable side effects (creates a file/modifies a database) then you'll be able to query those directly from Java.
Job done.
I hope you realise this question is far too vague to get full answers. Asking the public to design an entire system goes beyond the point where you'll get useful, actionable responses.
There are plenty of examples on the web of how to download a file from a URL.
Suns version of the JDK and JRE includes the Mozilla Rhino scripting engine.
Assuming you have stored the contents of the javascript file in a string called 'script', you can execute scripts as follows
String result = null;
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
try {
jsEngine.eval(script);
result = jsEngine.get("result")
} catch (ScriptException ex) {
ex.printStackTrace();
}
The result will be extracted from the engine and stored in the 'result' variable.
The is a tutorial on scripting in Java that might be useful.

Categories