摘要:在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的命令终端执行相应的命令并将执行结果返回。
若项目部署的服务器是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("
");
}
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;
}
}
博客记录着学习的脚步,分享着最新的技术,非常感谢您的阅读,本博客将不断进行更新,希望能够给您在技术上带来帮助。