java使用java -jar在当前应用程序调度另一可执行程序

最近,在研究公司的调度平台,也就是在某一应用程序中调用另一个应该程序,从而完成相应的业务逻辑。这里,另一应用程序是以jar包的方式提供。
下面,笔者直接贴代码,相关的解释已于注释:

/** * Project Name:testJava * File Name:JarInvoke.java * Package Name:com.qiyongkang.javaJar * Date:2015年9月18日上午9:02:58 * Copyright (c) 2015, CANNIKIN(http://http://code.taobao.org/p/cannikin/src/) All Rights Reserved. * */

package com.qiyongkang.javaJar;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/** * ClassName:JarInvoke <br/> * Function: TODO ADD FUNCTION. <br/> * Reason: TODO ADD REASON. <br/> * Date: 2015年9月18日 上午9:02:58 <br/> * * @author qiyongkang * @version * @since JDK 1.6 * @see */
public class JarInvoke {

    /* * 本示例是使用的java -jar方式调度程序 * 触发调用一个应用程序,1:以jar的方式运行 2:通过当前线程的contextClassLoader来加载外部jar,然后通过反射调用main方法 * jar方式表示的进程级调用,另外一种方式表示内部加载类,以线程的方式去运行 * 调用运行jar的JVM参数,如果选择以线程的方式去运行,那么这个参数将不起作用 * * 2.类加载方式,然后通过反射 * 每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类 * 系统默认的contextClassLoader是systemClassLoader, * 所以一般而言java程序在执行时可以使用JVM自带的类、$JAVA_HOME/jre/lib/ext/中的类和$CLASSPATH/中的类, * 对于非默认的jar,一般只能手动在配置环境添加。 * 但事实上,我们可以通过Thread.currentThread().setContextClassLoader()更改当前线程的contextClassLoader行为, * 实现在程序内加载外部jar * ClassLoader的工作原理是: * 1) 线程需要用到某个类时,contextClassLoader将被请求来载入该类 * 2) contextClassLoader请求它的父ClassLoader来完成该载入请求 * 3) 如果父ClassLoader无法载入类,则contextClassLoader试图自己来载入 * 这种方式,在没有优化的前提下,这种直接加载外部包的速度在jvm会有很大损耗,所以并不适合直接运用在需要复杂运算的jar中类调用上 */
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("java ");
        // 添加JVM参数
        sb.append("-Xms128m -Xmx256m -Xss1m ");

        // 所执行的jar路径名
        sb.append("-jar ");
        sb.append("./ShutDown/com.qiyongkang.shutdown.ShutDown.1.0.0.jar ");

        // 添加应用程序运行时传递的参数
        sb.append("3600");

        String cmd = sb.toString();

        try {
            Process process = Runtime.getRuntime().exec(cmd);
            // 读取子进程中的输入流信息,必须读取流信息,否则进程运行一段时间后会被挂起而不运行!
            // 先读取错误流,在读取标准流
            JarInvoke jarInvoke = new JarInvoke();
            jarInvoke.new ProcessStreamHelper(process.getErrorStream(), ProcessStreamHelper.ERROR_STREAM).start();
            jarInvoke.new ProcessStreamHelper(process.getInputStream(), ProcessStreamHelper.NORMAL_STREAM).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** * ClassName: ProcessStreamHelper <br/> * 子进程流读取帮助类,用来读取进程中的流信息. * <p/> * * @author qiyongkang * @since JDK 1.6 */
    class ProcessStreamHelper extends Thread {

        final static int NORMAL_STREAM = 0;

        final static int ERROR_STREAM = 1;

        private InputStream is;

        private int streamType;

        ProcessStreamHelper(InputStream is, int streamType) {
            super();
            this.is = is;
            this.streamType = streamType;
        }

        @Override
        public void run() {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    line = new String(line.getBytes(), "UTF-8");
                    if (streamType == NORMAL_STREAM) {
                        // debugLog("Read Line: " + line);
                    } else if (streamType == ERROR_STREAM) {
                        errorLog("Read Error: " + line);
                    } else {
                        // debugLog("Unkown Input Stream Type[" + streamType +
                        // "]");
                    }
                }
            } catch (IOException e) {
                errorLog("IOE: " + e + "\t\tMessage: " + e.getMessage());
            }
        }

        void debugLog(String message) {
            System.out.println("[Invoker Debug] " + message);
        }

        void errorLog(String message) {
            System.err.println("[Invoker Error] " + message);
        }
    }
}

我的项目结构展示如下图:
java使用java -jar在当前应用程序调度另一可执行程序_第1张图片
这里我的jar包使用ant打的包,相关的Main-Class和ClassPath已在MANIFEST.MF中指定:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.4
Created-By: 1.7.0_79-b15 (Oracle Corporation)
Main-Class: com.qiyongkang.shutdown.ShutDown
Class-Path: lib/commons-logging-1.1.3.jar lib/druid-1.0.0.jar

就写到这里了,有点偷懒,但也说得很清楚,这种调度程序的场景在某些项目中会使用到,比如数据处理,需要定期执行,因此便可打成jar包,放在统一的调度平台来调度执行这些jar程序。

你可能感兴趣的:(java,调度应用程序,java--jar)