Java實現多種語言編譯執行
Java實現多種語言編譯執行
摘要:在Java開發過程中,經常會遇到使用Java實現某一個功能比其他語言要複雜,因此通常將該功能使用其他程式語言來完成後,再通過Java呼叫編譯程式編譯執行該指令碼,並將結果以字串形式傳給Java變數。本文將簡要介紹如何利用Java實現多種語言編譯執行。
本人在Java和web開發過程中常用到其他語言,例如利用python實現爬取網頁並通過Java儲存資料庫,通過執行C++檔案實現評測等。
讀者可以進入本人自己寫的網站進行體驗:易教通應用中心·線上編譯
(如果顯示不安全,或者時鐘快了等SSL驗證問題,可以將您的PC時間調至2017.9.20-2018.9.20之間即可)
一、原理介紹
在實現Java編譯其他語言時,可能大多數人會想到編譯原理,不過在實現執行編譯和執行時,並不需要了解編譯底層原理,但需要了解語言是先經過編譯、再通過執行並返回執行結果的這一過程。
我們知道,在編譯和執行一個指令碼檔案,可以直接在作業系統的命令列進行執行,例如以常用的python、c、c++、php為例:
(1)命令列執行python(適用windows和linux):
$ python hello.py
(2)命令列編譯和執行c++或c:
windows作業系統:
$ cl hello.cpp
$ hello.exe
linux作業系統:
$ g++ hello.cpp $ hello.out
(3)命令列執行php(適用windows和linux):
$ hello.php
(4)當然,命令列執行Java也可以,但必須要先編譯為位元組碼檔案再執行位元組碼檔案(適用windows和linux):
$ javac hello.java
$ java hello
Ps:更多的指令碼語言可參考其編譯執行的規則。
而原理就是Java通過呼叫windows的cmd或者linux的命令終端執行相應的命令並將執行結果返回。
二、Java程式
若專案部署的伺服器是linux伺服器,則終端為linux的命令,需要涉及到遠端連線。Java源程式如下:
1、ExecuteLinuxCmd類,主要完成遠端訪問linux伺服器,並執行呼叫命令終端
引數說明:
String hostname:linux遠端伺服器的IP地址
String user_id:linux遠端伺服器的名稱(一般為root)
String user_pass:linux遠端伺服器的登入密碼
String order:要執行的終端命令,多條命令用分號隔開
package com.estudy.exec;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class ExecuteLinuxCmd {
public String stateCode = "";
public String getStateCode() {
return stateCode;
}
public String executeLinuxCmd(String cmd) {
System.out.println("got cmd job : " + cmd);
Runtime run = Runtime.getRuntime();
try {
Process process = run.exec(cmd);
InputStream in = process.getInputStream();
BufferedReader bs = new BufferedReader(new InputStreamReader(in));
String result = null;
while (in.read() != -1) {
result = bs.readLine();
System.out.println("job result [" + result + "]");
}
in.close();
process.destroy();
return result;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String Linux(String hostname,String user_id,String user_pass,String order){
String prompt = "";
try
{
Connection conn = new Connection(hostname);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(user_id, user_pass);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
Session sess = conn.openSession();
sess.execCommand(order);
System.out.println("Here is some information about the remote host:");
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout,"UTF-8"));
int num = 0;
while (true){
String string = br.readLine();
if ("null".equals(string)||string == null||"".equals(string))
break;
else {
if(num == 0){
prompt += string;
num = 1;
}else {
prompt += "\n" + string;
}
}
}
System.out.println("ExitCode: " + sess.getExitStatus());
stateCode = String.valueOf(sess.getExitStatus());
sess.close();
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
System.exit(2);
}
return prompt;
}
public String Compile(String hostname,String user_id,String user_pass,String order){
String prompt = "";
try{
Connection conn = new Connection(hostname);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(user_id, user_pass);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
Session sess = conn.openSession();
sess.execCommand(order);
System.out.println("Here is some information about the remote host:");
StringBuffer sb = new StringBuffer();
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout,"UTF-8"));
String line = "";
while ((line = br.readLine()) != null) {
System.out.println(line);
sb.append(line).append("<br>");
}
prompt = sb.toString();
System.out.println("ExitCode: " + sess.getExitStatus());
stateCode = String.valueOf(sess.getExitStatus());
sess.close();
conn.close();
}
catch (IOException e){
e.printStackTrace(System.err);
System.exit(2);
}
return prompt;
}
}
2、main函式(主要呼叫ExecuteLinuxCmd類,該部分可以在普通的Java類中,也可以在web控制層中使用)
//編譯執行
public static String[] CompileAndRun(String language,String file){
ExecuteLinuxCmd e = new ExecuteLinuxCmd();
String []result = new String[2];
switch (language) {
case cpp:
result[1] = e.Compile(hostname, username, password, "g++ hello.cpp;./hello.out");
result[0] = e.getStateCode();//獲取響應情況
break;
case java:
result[1] = e.Compile(hostname, username, password, "export PATH=/usr/java/jdk1.7.0_80/bin:$PATH;javac hello.java;java hello");
result[0] = e.getStateCode();//獲取響應情況
break;
case php:
result[1] = e.Compile(hostname, username, password, "export PATH=/usr/local/anaconda/ENTER/bin:$PATH;hello.php");
result[0] = e.getStateCode();//獲取響應情況
break;
case python3:
result[1] = e.Compile(hostname, username, password, "export PATH=/usr/local/anaconda/ENTER/bin:$PATH;python hello.py");
result[0] = e.getStateCode();//獲取響應情況
break;
default:
break;
}
return result;
}
若專案部署在windows伺服器上,Java源程式如下:
1、CompileRun 類:呼叫cmd並執行命令,輸入引數為要執行的命令,函式返回的即為終端輸出的結果。
package wjn.ITM.compileRun;
import java.io.IOException;
import java.io.InputStream;
public class CompileRun {//呼叫cmd命令執行編譯執行java檔案並將值反饋
Process process;
public String exec(String cmd) {
Runtime run = Runtime.getRuntime();
String str = "";
try {
process= run.exec(cmd);
InputStream in=process.getInputStream(); //獲取DOS下的輸出
int temp,i=0;
byte b[]=new byte[10240];
while((temp=in.read())!=-1){
b[i]=(byte)temp;
i++;
}
str = new String(b);
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
部落格記錄著學習的腳步,分享著最新的技術,非常感謝您的閱讀,本部落格將不斷進行更新,希望能夠給您在技術上帶來幫助。