From 82b4d735ca55891976270c8538f70cc7fa45f62f Mon Sep 17 00:00:00 2001 From: xuxueli <931591021@qq.com> Date: Thu, 12 Dec 2019 17:41:15 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4commons-exec=EF=BC=8C?= =?UTF-8?q?=E9=87=87=E7=94=A8=E5=8E=9F=E7=94=9F=E6=96=B9=E5=BC=8F=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/XXL-JOB官方文档.md | 4 +- pom.xml | 2 - xxl-job-core/pom.xml | 7 - .../com/xxl/job/core/util/ScriptUtil.java | 153 ++++++++++++++++-- 4 files changed, 144 insertions(+), 22 deletions(-) diff --git a/doc/XXL-JOB官方文档.md b/doc/XXL-JOB官方文档.md index 3d80541b..1680b2e3 100644 --- a/doc/XXL-JOB官方文档.md +++ b/doc/XXL-JOB官方文档.md @@ -1672,9 +1672,9 @@ public ReturnT execute(String param) { return ReturnT.SUCCESS; } ``` -- 2、调度中心dispatcher servlet加载顺序优化; +- 2、移除commons-exec,采用原生方式实现; - 3、执行器回调乱码问题修复; -- 4、[迭代中]移除commons-exec,采用原生方式实现; +- 4、调度中心dispatcher servlet加载顺序优化; - 5、[迭代中]任务操作API服务调整为restful方式,降低接入成本; diff --git a/pom.xml b/pom.xml index d67b4a81..7a6023ac 100644 --- a/pom.xml +++ b/pom.xml @@ -34,8 +34,6 @@ 1.7.28 4.12 - 1.3 - 2.5.8 3.1.0 diff --git a/xxl-job-core/pom.xml b/xxl-job-core/pom.xml index 489b34ce..1dec2aa5 100644 --- a/xxl-job-core/pom.xml +++ b/xxl-job-core/pom.xml @@ -29,13 +29,6 @@ ${groovy.version} - - - org.apache.commons - commons-exec - ${commons-exec.version} - - org.springframework diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/util/ScriptUtil.java b/xxl-job-core/src/main/java/com/xxl/job/core/util/ScriptUtil.java index 72f61bb7..83bc86e7 100644 --- a/xxl-job-core/src/main/java/com/xxl/job/core/util/ScriptUtil.java +++ b/xxl-job-core/src/main/java/com/xxl/job/core/util/ScriptUtil.java @@ -1,12 +1,13 @@ package com.xxl.job.core.util; import com.xxl.job.core.log.XxlJobLogger; -import org.apache.commons.exec.CommandLine; -import org.apache.commons.exec.DefaultExecutor; -import org.apache.commons.exec.PumpStreamHandler; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; /** * 1、内嵌编译器如"PythonInterpreter"无法引用扩展包,因此推荐使用java调用控制台进程方式"Runtime.getRuntime().exec()"来运行脚本(shell或python); @@ -42,12 +43,7 @@ public class ScriptUtil { } /** - * 日志文件输出方式 - * - * 优点:支持将目标数据实时输出到指定日志文件中去 - * 缺点: - * 标准输出和错误输出优先级固定,可能和脚本中顺序不一致 - * Java无法实时获取 + * 脚本执行,日志文件实时输出 * * @param command * @param scriptFile @@ -56,7 +52,142 @@ public class ScriptUtil { * @return * @throws IOException */ - public static int execToFile(String command, String scriptFile, String logFile, String... params) throws IOException { + public static int execToFileB(String command, String scriptFile, String logFile, String... params) throws IOException { + + FileOutputStream fileOutputStream = null; + Thread inputThread = null; + Thread errThread = null; + try { + // file + fileOutputStream = new FileOutputStream(logFile, true); + + // command + List cmdarray = new ArrayList<>(); + cmdarray.add(command); + cmdarray.add(scriptFile); + if (params!=null && params.length>0) { + for (String param:params) { + cmdarray.add(param); + } + } + String[] cmdarrayFinal = cmdarray.toArray(new String[cmdarray.size()]); + + // process-exec + final Process process = Runtime.getRuntime().exec(cmdarrayFinal); + + // log-thread + final FileOutputStream finalFileOutputStream = fileOutputStream; + inputThread = new Thread(new Runnable() { + @Override + public void run() { + try { + copy(process.getInputStream(), finalFileOutputStream, new byte[1024]); + } catch (IOException e) { + XxlJobLogger.log(e); + } + } + }); + errThread = new Thread(new Runnable() { + @Override + public void run() { + try { + copy(process.getErrorStream(), finalFileOutputStream, new byte[1024]); + } catch (IOException e) { + XxlJobLogger.log(e); + } + } + }); + inputThread.start(); + errThread.start(); + + // process-wait + int exitValue = process.waitFor(); // exit code: 0=success, 1=error + + // log-thread join + inputThread.join(); + errThread.join(); + + return exitValue; + } catch (Exception e) { + XxlJobLogger.log(e); + return -1; + } finally { + if (fileOutputStream != null) { + try { + fileOutputStream.close(); + } catch (IOException e) { + XxlJobLogger.log(e); + } + + } + if (inputThread != null && inputThread.isAlive()) { + inputThread.interrupt(); + } + if (errThread != null && errThread.isAlive()) { + errThread.interrupt(); + } + } + } + + /** + * 数据流Copy(Input自动关闭,Output不处理) + * + * @param inputStream + * @param outputStream + * @param buffer + * @return + * @throws IOException + */ + private static long copy(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws IOException { + try { + long total = 0; + for (;;) { + int res = inputStream.read(buffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (outputStream != null) { + outputStream.write(buffer, 0, res); + } + } + } + outputStream.flush(); + //out = null; + inputStream.close(); + inputStream = null; + return total; + } finally { + if (inputStream != null) { + inputStream.close(); + } + } + } + + /** + * 脚本执行,日志文件实时输出 + * + * 优点:支持将目标数据实时输出到指定日志文件中去 + * 缺点: + * 标准输出和错误输出优先级固定,可能和脚本中顺序不一致 + * Java无法实时获取 + * + * + * + * org.apache.commons + * commons-exec + * ${commons-exec.version} + * + * + * @param command + * @param scriptFile + * @param logFile + * @param params + * @return + * @throws IOException + */ + /*public static int execToFile(String command, String scriptFile, String logFile, String... params) throws IOException { // 标准输出:print (null if watchdog timeout) // 错误输出:logging + 异常 (still exists if watchdog timeout) // 标准输入 @@ -92,6 +223,6 @@ public class ScriptUtil { } } - } + }*/ }