中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java?Runtime的使用方法是什么

發布時間:2021-12-15 17:05:26 來源:億速云 閱讀:134 作者:柒染 欄目:開發技術

這篇文章將為大家詳細講解有關Java Runtime的使用方法是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

    前言

    最近做項目框架,需要在框架結束的時候,關閉服務器連接,清除部分框架運行lock文件,這里就想到了shutdownhook,順便學了學Runtime的使用

    1. shutdownhook

    demo示例,證明在程序正常結束的時候會調用,如果kill -9 那肯定就不會調用了

    public class ShutdownHookTest { 
        public static void main(String[] args) {
            System.out.println("==============application start================");
     
            Runtime.getRuntime().addShutdownHook(new Thread(()->{
                System.out.println("--------------hook 1----------------");
            }));
            Runtime.getRuntime().addShutdownHook(new Thread(()->{
                System.out.println("--------------hook 2----------------");
            }));
     
            System.out.println("==============application end================");
        }
    }

    正常運行結束,結果如下

    ==============application start================
    ==============application end================
    --------------hook 1----------------
    --------------hook 2----------------

    Process finished with exit code 0

    如果暫停,點擊下圖左下角的正方形紅圖標,停止正在運行的應用

    Java?Runtime的使用方法是什么

    結果如下,shutdownhook已執行。

    Java?Runtime的使用方法是什么

    shutdownhook可以處理程序正常結束的時候,刪除文件,關閉連接等

    2. exec執行

    2.1 常規命令執行

    demo示例如下,比如ls

    public class ShutdownHookTest { 
        public static void main(String[] args) throws InterruptedException, IOException {
            Process process = Runtime.getRuntime().exec("ls"); 
            try (InputStream fis = process.getInputStream();
                 InputStreamReader isr = new InputStreamReader(fis);
                 BufferedReader br = new BufferedReader(isr)) {
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            }
        }
    }

    結果如下

    Java?Runtime的使用方法是什么

    而正常執行結果

    Java?Runtime的使用方法是什么

    但是這個方法有遠程執行風險,即在瀏覽器端通過這個方法執行特定指令,比如執行rm -rf *,結果就很……

    2.2 管道符

    但是遇見管道符之后就會失效,什么辦法解決,sh -c,但是不能直接用,否則獲取到的是TTY窗口信息

    public static void main(String[] args) throws IOException {
            Process process = Runtime.getRuntime().exec("sh -c ps aux|grep java"); 
            try (InputStream fis = process.getInputStream();
                 InputStreamReader isr = new InputStreamReader(fis);
                 BufferedReader br = new BufferedReader(isr)) {
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            }
        }

    結果????

    Java?Runtime的使用方法是什么

    sh -c的參數要分離,不然runtime會認為是一個參數

    Java?Runtime的使用方法是什么

    2.3源碼分析

    跟蹤代碼,使用ProcessImpl來執行指令

    public Process exec(String[] cmdarray, String[] envp, File dir)
            throws IOException {
            return new ProcessBuilder(cmdarray)
                .environment(envp)
                .directory(dir)
                .start();
        }

    ProcessBuilder

    // Only for use by ProcessBuilder.start()
        static Process start(String[] cmdarray,
                             java.util.Map<String,String> environment,
                             String dir,
                             ProcessBuilder.Redirect[] redirects,
                             boolean redirectErrorStream)
            throws IOException
        {
            assert cmdarray != null && cmdarray.length > 0;
     
            // Convert arguments to a contiguous block; it's easier to do
            // memory management in Java than in C.
            byte[][] args = new byte[cmdarray.length-1][];
            int size = args.length; // For added NUL bytes
            for (int i = 0; i < args.length; i++) {
                args[i] = cmdarray[i+1].getBytes();
                size += args[i].length;
            }
            byte[] argBlock = new byte[size];
            int i = 0;
            for (byte[] arg : args) {
                System.arraycopy(arg, 0, argBlock, i, arg.length);
                i += arg.length + 1;
                // No need to write NUL bytes explicitly
            }
     
            int[] envc = new int[1];
            byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc); 
            int[] std_fds; 
            FileInputStream  f0 = null;
            FileOutputStream f1 = null;
            FileOutputStream f2 = null;
     
            try {
                if (redirects == null) {
                    std_fds = new int[] { -1, -1, -1 };
                } else {
                    std_fds = new int[3];
     
                    if (redirects[0] == Redirect.PIPE)
                        std_fds[0] = -1;
                    else if (redirects[0] == Redirect.INHERIT)
                        std_fds[0] = 0;
                    else {
                        f0 = new FileInputStream(redirects[0].file());
                        std_fds[0] = fdAccess.get(f0.getFD());
                    }
     
                    if (redirects[1] == Redirect.PIPE)
                        std_fds[1] = -1;
                    else if (redirects[1] == Redirect.INHERIT)
                        std_fds[1] = 1;
                    else {
                        f1 = new FileOutputStream(redirects[1].file(),
                                                  redirects[1].append());
                        std_fds[1] = fdAccess.get(f1.getFD());
                    }
     
                    if (redirects[2] == Redirect.PIPE)
                        std_fds[2] = -1;
                    else if (redirects[2] == Redirect.INHERIT)
                        std_fds[2] = 2;
                    else {
                        f2 = new FileOutputStream(redirects[2].file(),
                                                  redirects[2].append());
                        std_fds[2] = fdAccess.get(f2.getFD());
                    }
                }
     
            return new UNIXProcess
                (toCString(cmdarray[0]),
                 argBlock, args.length,
                 envBlock, envc[0],
                 toCString(dir),
                     std_fds,
                 redirectErrorStream);
            } finally {
                // In theory, close() can throw IOException
                // (although it is rather unlikely to happen here)
                try { if (f0 != null) f0.close(); }
                finally {
                    try { if (f1 != null) f1.close(); }
                    finally { if (f2 != null) f2.close(); }
                }
            }
        }

    new UNIXProcess 環境

     /**
     * java.lang.Process subclass in the UNIX environment.
     *
     * @author Mario Wolczko and Ross Knippel.
     * @author Konstantin Kladko (ported to Linux and Bsd)
     * @author Martin Buchholz
     * @author Volker Simonis (ported to AIX)
     */
    final class UNIXProcess extends Process {

    3. 總結

    Runtime用處非常多,偏底層

    比如gc調用

    Java?Runtime的使用方法是什么

    加載jar文件

    Java?Runtime的使用方法是什么

    Runtime功能強大,但需要合理利用,很多攻擊是通過Runtime執行的漏洞

    但是使用shutdownhook還是很方便的,用來做停止任務的后續處理。

    關于Java Runtime的使用方法是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    罗源县| 临汾市| 井研县| 墨江| 肃北| 巧家县| 浦北县| 贺州市| 内乡县| 南投县| 长沙县| 尖扎县| 闽侯县| 汶川县| 凌海市| 台前县| 怀化市| 奈曼旗| 嘉鱼县| 安泽县| 凤山市| 临城县| 昌黎县| 安徽省| 鄯善县| 揭东县| 潼关县| 绥阳县| 吴旗县| 清远市| 海林市| 淮北市| 东光县| 鄂州市| 温宿县| 望江县| 木里| 随州市| 嘉鱼县| 吴江市| 温宿县|