Invoke compilers of different languages from within sts/eclipse - java

I have a situation where the user posts a file to server and it needs to be compiled on the server side. The server should detect the language and invoke the corresponding compiler and send the results back to client. Right now we are supporting Java, Python and C. Is there a way I can compile a Java file which is not imported into eclipse from within eclipse? And also, is there a way I can invoke compilers for python and C (or any other language can be used) from within eclipse?

When you detect the language of the code this becomes pretty easy:
String compiler = "";
switch(compilerCode)
{
case JAVA:
compiler = "javac";
break;
case C:
compiler = "javac";
break;
...
}
Process p = Runtime.getRuntime().exec(compiler + " " + file);
p.waitFor();
file will be the name of the file you are trying to compile, and compilerCode will be a code that will tell you which compiler to use.
This goes without saying but you should have all of the compilers installed to compile all of the languages you intend on supporting.
Edit:
It is super easy to get error messages from a running process. All you need to do is:
InputStream in = p.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
...
String error = reader.readLine();
...
reader.close();

Related

Adding a compiler to run a java code and show the output

I am making an android app which can run c, c++ and java programs. The app stores the respective files in a folder and is made to execute with the following code. Whenever I click on compile button it shows an IO Exception saying "error=13 permission denied".
try {
p = Runtime.getRuntime().exec(path + "/PocketIDE/JavaPrograms/"+ filename);
BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output2.append(line).append("\n");
p.waitFor();
}
String response = output2.toString();
output.setText(response);
} catch (IOException | InterruptedException e) {
output.setText(e.toString());
e.printStackTrace();
}
Is the above method the correct way to execute the program? or do I need to change the code?
p = Runtime.getRuntime().exec(path + "/PocketIDE/JavaPrograms/"+ filename);
You shouldn't run arbitrary Java code with the runtime that controls the execution of your app. This opens a massive security flaw, so Android disallows it. Instead, you should find a way to execute the Java code in its own environment and runtime.
The statement in your code can be used to execute other programs, but it is not necessarily a good idea.
The exec method internally forks the application`s process and creates a new one, which immediately executes the system command you give it.
From the path in your code I assume that you try to execute a binary executable, which is not allowed anymore by Android since API level 28:
Untrusted apps that target Android 10 cannot invoke exec() on files within the app's home directory. This execution of files from the writable app home directory is a W^X violation. Apps should load only the binary code that's embedded within an app's APK file.
The only possible solution is to reduce the API level to 28 or include the binary in the APK file during packaging.

How to create a 2 way communication between Java and Python

I am pretty new to both Java and Python, although I have some experience in programming. For an assignement, I need to create a program which uses Java in some way. My project would use Java as an UX, and Python for signal processing and feature extraction, since it has some good tools for that.
However, my question is how to establish communication between both programse. Maybe this question has been asked before, but since I do not know the best terms, I could not find answers.
In my Java Program, I can get the file path to a .csv file, send it to Python, and Python returns the original signals and processed signals. For that, I wrote:
private static void sendPython(String path, JTextField console)
{
String pathPython = "C:\\Users\\gonca\\Desktop\\untitled0.py";
String [] cmd = new String[3];
cmd[0] = "python";
cmd[1] = pathPython;
cmd[2] = path;
Runtime r = Runtime.getRuntime();
try
{
Process p = r.exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s = "";
while((s = in.readLine()) != null)
{
console.setText(s);
}
}
catch (IOException e)
{
console.setText("Unable to run python script");
}
}
I was thinking of having the py script output the signals in separated lines, with values separated by "," or ";", and using the BufferedRead to read each line, separate the values and create a new ArrayList from the separated values.
However, before starting working harder to do that, I would like to know if that is the best way to proceed, or is there a more efficient way to do it.
There are more ways to do that:
Solution 1:
Use the python library from java with System.loadLibrary, and call the python method. (here is an example using C/C++: Calling a python method from C/C++, and extracting its return value)
Solution 2:
Launch python as another process, and use D-Bus (or something similar) to communicate with it.
Since you have not mentioned how robust your application is I can think of a solution which can be used if you are planning for a higher level architecture.
Create a python based web application (HTTP server) with all logic to process your files.
Create a java app which can communicate via HTTP python server to get the CSV processed information.
Try to avoid Runtime execution of commands with in your codes that faces user as if it not is properly managed there is always a chance for security breach

Compiling and communication with shell application in Android/Java

I have a command line application (also it's source code in C language). I want to use it in my first android application.
Here are my questions:
I have a compiled executable for mac. Should I recompile it for android? If yes, how?
Is it possible to have a two way communication with an executable in shell in Java/Android?
I'm looking for something like:
Runtime.getRuntime().exec(cmd);
After a lot of googling, that line of code was only thing that I found. But I don't want to close the executable after each call (it communicates with a server on the internet). Here is what I want to do:
1. Open shell executable
2. write AAA
3. read line
4. write BBB
5. read line
6. write CCC
...
98. write XYZ
99. read line
100. close executable
Note that there may be nothing to read, and it shouldn't wait for it.
Yes, you need recompile it with NDK. How: you can find more information on official Android site, where examples also present.
Yes its also possible to do that, and there are two ways exist:
a) JNI. You need to write a wrapper for for you function, and compile a shared library
b) You can compile executable file, run it and communicate via input/output stream. Something like:
try {
Process pb = Runtime.getRuntime().exec(cmd);
String line;
BufferedReader input = new BufferedReader(new InputStreamReader(pb.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println("Input from your C/C++ app: " + line);
}
input.close();
} catch (IOException e) {
e.printStackTrace();
}

Executing an expression in a txt file through Java

Hi was wondering if there was a way to execute a line of code from a text file through Java.
For example, let's say I have a text file, and inside that text file it contains an expression
int a = 1;
int b = 2;
int c;
c = a + b;
So in my main class, I have a file object and it does a try/catch
File file = new File("test.txt");
try {
//code here
}catch (FileNotFoundException e) {
System.err.format("File does not exist \n");
}
My goal is to run the code from the test.txt and output the answer. How should I approach this?
Firstly as from the #D.B. commentary:
You might try using the JavaCompiler tool, however, it requires the JDK so if you're turning it in for extra credit make sure your instructor will run it using the JDK not the JRE
It would be possible to compile the while while you run your program. It would be something like:
Read the file.
Compose a valid Java application.
Compile it.
And start it to run on a new thread.
Now, basically you cannot write Java Standard Edition expressions on a file and load the to execute on run time. It is because all java statements must to be parsed and translated to Java Bytecodes and it can only be done before the program to starts running. Except the case where you construct another Java application, compile it and put it to run as a new application invocation, done by you or some Java System Call.
The only thing the Java Virtual Machine can run are Java Bytecodes. So, your text file is not translated to it, then they cannot run. Although, this is not true to languages as Python and Javascript due they do not need to be translated into Machine Language as Bytecodes for the Java virtual Machine and assembly code for the x86 or x64 processor architectures as languages as C++.
You solution is use a interpreted language as Python and Javascript, instead of a compiled languages as Java or C++. As pointed by #that other guy there is the scripting language BeanShell which is a Java-like scripting language, if you are interested to learn it.
References:
https://en.wikipedia.org/wiki/Interpreted_language
https://en.wikipedia.org/wiki/Compiled_language
https://en.wikipedia.org/wiki/Scripting_language
My goal is to run the code from the test.txt and output the answer. How should I approach this?
Within Java, to achieve this goal you can parse the file using your own syntax rules. And as well stated by #Vince Emigh
You'd need some form of parsing and semantic analysis to do this. You are asking us how to write an interpreter, and seeing how you haven't even posted your attempt or specified a specific problem you are having when implementing this, this is faaar too broad
For your example, it would be like:
text.txt
1
2
+
Your Java Source Code file:
File file = new File("test.txt");
try
{
BufferedReader br = new BufferedReader( new FileReader( file ) )
int numbers[] = new int[10];
String line;
while( ( line = br.readLine() ) != null )
{
if( line.contains( "+" ) )
{
... do stuff
}
}
}
catch( FileNotFoundException e )
{
System.err.format("File does not exist \n");
}
finally
{
if( reader !=null )
{
reader.close();
}
}
References:
How to read a large text file line by line using Java?
https://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html
https://docs.oracle.com/javase/7/docs/api/java/io/File.html
Is there an eval() function in Java?

Communicating to a C++ program from java

I want to execute a external .exe program from within java. The .exe is a CLI application which takes input in runtime( scanf() ) and outputs depending on the input. I can call the program to execute from java using
Process p = Runtime.getRuntime().exec("cmd /c start a.exe");
instead of
Process p = Runtime.getRuntime().exec("cmd /c start a.exe");
But I think it is also possible to call a program from within java. I have my whole program written in C++ just need a GUI which is written in java. There are a few things to notice:=
1) The communication with the .exe should be runtime (not through main(args) )
2) The java program should take the outputs and store in some variable / panel to use for future
3) Program to be executed can differ ( for example user may select a .exe that doesnt take any input at all)
........So basically the java GUI will act as a RuntimeEnv
public void runEXE()
{
String s = null;
try {
Process p = Runtime.getRuntime().exec("cmd /c a.exe");
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
I know there are a lot of questions about this topic out there. But i cant find any of them much useful.
Rather ugly little function that I use. This takes in the command to be passed to Runtime.getRuntime().exec, then saves the results into a String, and returns the String at the end. You can pick whether you only want the last line (or all output) and whether you want to save the stdout or stderr string from the process.
private static String systemResult(String cmd, boolean append, boolean useErr)
{
String result = "";
try{
// spawn the external process
//printCmd(cmd);
Process proc = Runtime.getRuntime().exec(cmd);
LineNumberReader lnr1 = new LineNumberReader(new InputStreamReader(proc.getErrorStream()));
LineNumberReader lnr2 = new LineNumberReader(new InputStreamReader(proc.getInputStream()));
String line;
int done = 0;
while(lnr1 != null || lnr2 != null){
try{
if(lnr1.ready()){
if((line = lnr1.readLine()) != null){
//System.err.println("A:" +line);
if(useErr){
if(append) result = result + line + "\n";
else result = line;
}
}
}else if(done == 1){
done = 2;
}
}catch(Exception e1){
try{ lnr1.close(); }catch(Exception e2){}
lnr1 = null;
}
try{
if(lnr2.ready()){
if((line = lnr2.readLine()) != null){
//System.err.println("====>Result: " + line);
if(!useErr){
if(append) result = result + line + "\n";
else result = line;
}
}
}else if(done == 2){
break;
}
}catch(Exception e1){
try{ lnr2.close(); }catch(Exception e2){}
lnr2 = null;
}
try{
proc.exitValue();
done = 1;
}catch(IllegalThreadStateException itsa){}
}
if(lnr1 != null) lnr1.close();
if(lnr2 != null) lnr2.close();
try{
proc.waitFor();
}catch(Exception ioe){
}finally{
try{
proc.getErrorStream().close();
proc.getInputStream().close();
proc.getOutputStream().close();
}catch(Exception e){}
proc = null;
}
}catch(Exception ioe){
}
return result;
}
You could use JNI as #linuxuser27 suggests, or you could use SWIG which helps to make the process of communicating from Java --> C++ a little less painful.
Google Protocol Buffers would be a good option for Java/C++ interoperability.
Protocol buffers are Google's
language-neutral, platform-neutral,
extensible mechanism for serializing
structured data – think XML, but
smaller, faster, and simpler. You
define how you want your data to be
structured once, then you can use
special generated source code to
easily write and read your structured
data to and from a variety of data
streams and using a variety of
languages – Java, C++, or Python.
I would look at JNI and use some type of IPC to communicate with the C++ project.
Update:
JNI is a way for Java to interface with the underlying native environment the JRE is running on. This method would require you to create a DLL that is loaded into the JRE when your Java program starts. This JNI DLL would then contain a method which could be called from within your Java program that would pass data into the JNI DLL that could then communicate to the C++ project via a named pipe or shared memory.
The named piped would be create using the CreateNamedPipe Win32 API. Within the JNI DLL you would most likely create a server and in the C++ project you would create the client. Note that the server example is multi-threaded but can easily be converted to a single thread model for simplicity.
Note that this is not a simple task. The other answers offer some approaches that are easier, JNA and passing data to the C++ project via stdin.
A couple of things:
First and foremost, if you haven't done so, read this critically important article: When Runtime.exec won't
Next, there are several ways for Java to communicate to other applications, and probably the easiest is via standard input and output streams. Have you tried using these?
Next there's JNI and the easier JNA, but you stated that your C++ program is running via CLI which suggests to me that you have a .NET dll, not a true Windows dll. Is this so? If so, it would make communication between Java and C++ more difficult.
You can execute .exe programs directly. You just need to supply the full path. Relative path will also be ok.
You can use pipes to interface with an external process: Sending Input to a Command, Reading Output from a Command
The solution can be found here
Problem getting output and passing input to a executing process running under java

Categories

Resources