1. 程式人生 > >Java實現多種語言編譯執行

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

部落格記錄著學習的腳步,分享著最新的技術,非常感謝您的閱讀,本部落格將不斷進行更新,希望能夠給您在技術上帶來幫助。