Làm cách nào để khởi động lại ứng dụng Java?


94

Làm cách nào để khởi động lại ứng dụng Java AWT? Tôi có một nút mà tôi đã đính kèm một trình xử lý sự kiện. Tôi nên sử dụng mã nào để khởi động lại ứng dụng?

Tôi muốn làm điều tương tự Application.Restart()như trong ứng dụng C #.


2
Có lẽ tôi không hiểu câu hỏi của bạn. Bạn muốn ứng dụng của mình có nút khởi động lại ứng dụng? Vì vậy, sau khi ứng dụng không còn chạy nữa, nó có thể tự khởi động lại không? Điều đó nghe có vẻ không thể đối với tôi.
Jay

Tôi không hỏi rằng sau khi JVM dừng, tôi hỏi rằng làm thế nào tôi có thể hồi sinh khung java chính của mình?
Azfar Niaz

2
Không phải là không thể. Tôi thấy bàn làm việc nhật thực thường xuyên khởi động lại, ngay cả các cửa sổ cũng thực hiện thủ thuật này sau khi cập nhật. Giả định sai là ứng dụng là thứ duy nhất chạy mà không có gì bên dưới nó. Chúng tôi sẽ cần một trình khởi chạy có khả năng khởi động lại, tất cả đều bị lỗi.
whatnick

giống như trong ứng dụng C #, nơi bạn có thể viết System.restart () để làm như vậy?
Azfar Niaz

@aniaz thì bạn nên cập nhật câu hỏi để chỉ ra bạn muốn hiển thị / ẩn khung hình. Ứng dụng KHÔNG phải là Khung.
whatnick

Câu trả lời:


104

Tất nhiên, có thể khởi động lại một ứng dụng Java.

Phương pháp sau đây cho thấy một cách để khởi động lại một ứng dụng Java:

public void restartApplication()
{
  final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
  final File currentJar = new File(MyClassInTheJar.class.getProtectionDomain().getCodeSource().getLocation().toURI());

  /* is it a jar file? */
  if(!currentJar.getName().endsWith(".jar"))
    return;

  /* Build command: java -jar application.jar */
  final ArrayList<String> command = new ArrayList<String>();
  command.add(javaBin);
  command.add("-jar");
  command.add(currentJar.getPath());

  final ProcessBuilder builder = new ProcessBuilder(command);
  builder.start();
  System.exit(0);
}

Về cơ bản nó làm như sau:

  1. Tìm tệp thực thi java (Tôi đã sử dụng tệp nhị phân java ở đây, nhưng điều đó phụ thuộc vào yêu cầu của bạn)
  2. Tìm ứng dụng (trong trường hợp của tôi là một jar, sử dụng MyClassInTheJarlớp để tự tìm vị trí jar)
  3. Xây dựng lệnh để khởi động lại jar (sử dụng nhị phân java trong trường hợp này)
  4. Thực hiện nó! (và do đó chấm dứt ứng dụng hiện tại và khởi động lại)

5
Không có một khung thời gian nhỏ nào trong đó hai phiên bản của cùng một ứng dụng đang chạy cùng một lúc?
Monir

5
System.exit (0) sẽ không chấm dứt tiến trình con?
Horcrux7

16
@Veger Câu hỏi có System.exit(0)chấm dứt tiến trình con có câu trả lời giống như câu trả lời này có thực sự hoạt động hay không và tại sao. Nếu bạn không thể đưa ra lời giải thích hợp lý cùng với câu trả lời của mình, bạn đã làm một công việc không tốt. Câu trả lời cung cấp nhiều câu hỏi hơn câu trả lời không phải là một ví dụ về câu trả lời thấu đáo. Câu trả lời tốt không chỉ hiển thị mã mà còn giải thích cách thức và lý do tại sao chúng hoạt động, nhược điểm là gì và đâu là lựa chọn thay thế. Bạn thậm chí đã không cố gắng che những thứ này.
Tomáš Zato - Phục hồi Monica

8
Rất nhiều bình luận tranh luận về việc có nên trả lời câu hỏi của @ Horcrux7 hay không. Các bạn có thể đã nói với anh ấy câu trả lời ngay từ đầu lol. Vâng, tôi sẽ tiếp tục và làm điều đó (hơi muộn tôi biết): không nó không. Đây.
Voldemort,

10
Để tự trả lời câu hỏi của tôi. Mẫu không hoạt động !!! System.exit (0) chấm dứt quy trình máy khách ngay lập tức.
Horcrux7

35
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;

public class Main {
    public static void main(String[] args) throws IOException, InterruptedException {
        StringBuilder cmd = new StringBuilder();
        cmd.append(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java ");
        for (String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
            cmd.append(jvmArg + " ");
        }
        cmd.append("-cp ").append(ManagementFactory.getRuntimeMXBean().getClassPath()).append(" ");
        cmd.append(Main.class.getName()).append(" ");
        for (String arg : args) {
            cmd.append(arg).append(" ");
        }
        Runtime.getRuntime().exec(cmd.toString());
        System.exit(0);
    }
}

Dành riêng cho tất cả những ai nói rằng điều đó là không thể.

Chương trình này thu thập tất cả thông tin có sẵn để xây dựng lại dòng lệnh ban đầu. Sau đó, nó khởi chạy nó và vì nó là lệnh giống nhau nên ứng dụng của bạn sẽ khởi động lần thứ hai. Sau đó, chúng tôi thoát khỏi chương trình gốc, chương trình con vẫn chạy (ngay cả trong Linux) và thực hiện điều tương tự.

CẢNH BÁO : Nếu bạn chạy điều này, hãy lưu ý rằng nó không bao giờ kết thúc việc tạo các quy trình mới, tương tự như một quả bom ngã ba .


Cải tiến có thể ManagementFactory.getRuntimeMXBean().getInputArguments() sẽ chỉ cung cấp cho bạn các đối số đầu vào được chuyển đến JVM. Nó bỏ lỡ các thông số được chuyển đến ứng dụng của bạn. vd java -jar start.jar -MISSED_PARAM=true. Trên một jvm oracle, bạn có thể lấy các tham số đó bằng cách sử dụng System.getProperty("sun.java.command").
Chris2M

1
Máy ảo mẹ có thể kết thúc nếu máy ảo con và máy ảo mẹ không được kết nối với nhau bằng các đường ống, đó là điều xảy ra theo cách máy ảo con được khởi động. Bằng cách sử dụng ProcessBuilderinheritIO(), máy ảo con có thể được khởi động theo cách mà máy ảo mẹ sẽ kết thúc.
Christian Hujer

1
Tôi đã có một phiên bản của điều này. Nhận xét này là để cho bạn biết cách ngăn chặn nó: đổi tên một cái gì đó trong đường dẫn chứa java.exe.
Dale

Nói chính xác thì đây không phải là khởi động lại mà là khởi chạy một JVM mới với các đối số tương tự như cái này.
Thorbjørn Ravn Andersen

4
Có gì khác biệt? Có sự khác biệt giữa khởi động lại PC và tắt hệ điều hành + khởi động lại máy tính không?
Meinersbur

27

Về cơ bản, bạn không thể. Ít nhất là không theo một cách đáng tin cậy. Tuy nhiên, bạn không cần phải làm vậy.

Các không thể là một phần

Để khởi động lại chương trình Java, bạn cần khởi động lại JVM. Để khởi động lại JVM, bạn cần

  1. Định vị javatrình khởi chạy đã được sử dụng. Bạn có thể thử với System.getProperty("java.home")nhưng không có gì đảm bảo rằng điều này sẽ thực sự trỏ đến trình khởi chạy được sử dụng để khởi chạy ứng dụng của bạn. (Giá trị trả về có thể không trỏ đến JRE được sử dụng để khởi chạy ứng dụng hoặc nó có thể đã bị ghi đè -Djava.home.)

  2. Bạn có lẽ sẽ muốn tôn vinh những bộ nhớ ban đầu cài đặt vv ( -Xmx, -Xms, ...), do đó bạn cần phải tìm ra những nơi sử dụng để khởi động JVM đầu tiên. Bạn có thể thử sử dụng ManagementFactory.getRuntimeMXBean().getInputArguments()nhưng không có gì đảm bảo rằng điều này sẽ phản ánh các cài đặt được sử dụng. Điều này thậm chí còn được viết trong tài liệu của phương pháp đó:

    Thông thường, không phải tất cả các tùy chọn dòng lệnh cho lệnh 'java' đều được chuyển đến máy ảo Java. Do đó, các đối số đầu vào được trả về có thể không bao gồm tất cả các tùy chọn dòng lệnh.

  3. Nếu chương trình của bạn đọc đầu vào từ Standard.instdin ban đầu sẽ bị mất khi khởi động lại.

  4. Rất nhiều thủ thuật và hack này sẽ thất bại khi có a SecurityManager.

Các không cần phần

Tôi khuyên bạn nên thiết kế ứng dụng của mình sao cho dễ dàng dọn dẹp mọi thứ và sau đó tạo một phiên bản mới của lớp "chính" của bạn.

Nhiều ứng dụng được thiết kế để không làm gì khác ngoài việc tạo một thể hiện trong phương thức main:

public class MainClass {
    ...
    public static void main(String[] args) {
        new MainClass().launch();
    }
    ...
}

Bằng cách sử dụng mẫu này, nó sẽ đủ dễ dàng để thực hiện một số việc như:

public class MainClass {
    ...
    public static void main(String[] args) {
        boolean restart;
        do {
            restart = new MainClass().launch();
        } while (restart);
    }
    ...
}

launch()trả về true nếu và chỉ khi ứng dụng bị tắt theo cách cần khởi động lại.


3
+1 để được tư vấn thiết kế tốt hơn; mặc dù, đôi khi nó không thể thực hiện được, đặc biệt nếu sử dụng JNI chẳng hạn.
maerics

Vâng, một thư viện gốc có thể sửa đổi trạng thái chung không thể sửa đổi từ giao diện JNI, vì vậy sẽ không có cách nào để "khởi động lại" trạng thái của chương trình ngoài việc khởi động lại quá trình. Tất nhiên, thư viện gốc nên được thiết kế tốt hơn nhưng đôi khi bạn phụ thuộc vào những thứ bạn không thể kiểm soát.
maerics

Được, nhưng với lý do đó, bạn cũng có thể có một thư viện Java thuần túy sửa đổi một số biến tĩnh nội bộ. Tuy nhiên, đây sẽ là một lỗ hổng thiết kế và không nên xảy ra trong các thư viện được viết tốt.
aioobe

1
Câu trả lời của bạn là không chính xác, vì nó hoàn toàn có thể xảy ra ngay cả khi không có các ứng dụng / daemon bên ngoài như được hiển thị bởi Meinersbur và câu trả lời của riêng tôi. Và vì mục đích tự cập nhật, khởi động lại một ứng dụng là một giải pháp tốt, vì vậy thực tế cũng cần phải khởi động lại các ứng dụng.
Veger

1
Nhưng bạn làm sử dụng một ứng dụng bên ngoài: java! Bạn đang quên rằng Java là một đặc tả ngôn ngữ, không phải một chương trình. Điều gì sẽ xảy ra nếu tôi chạy chương trình của bạn bằng một số jvm khác, chẳng hạn như kaffe chẳng hạn? Vẫn cập nhật câu trả lời của tôi :-)
aioobe

9

Nói một cách chính xác, một chương trình Java không thể tự khởi động lại vì để làm như vậy, nó phải giết JVM mà nó đang chạy và sau đó khởi động lại, nhưng một khi JVM không còn chạy nữa (bị giết) thì không thể thực hiện hành động nào.

Bạn có thể thực hiện một số thủ thuật với trình tải lớp tùy chỉnh để tải, đóng gói và khởi động lại các thành phần AWT nhưng điều này có thể sẽ gây ra nhiều vấn đề đau đầu liên quan đến vòng lặp sự kiện GUI.

Tùy thuộc vào cách ứng dụng được khởi chạy, bạn có thể bắt đầu JVM trong một tập lệnh trình bao bọc có chứa vòng lặp do / while, vòng lặp này tiếp tục trong khi JVM thoát bằng một mã cụ thể, sau đó ứng dụng AWT sẽ phải gọi System.exit(RESTART_CODE). Ví dụ, trong mã giả tập lệnh:

DO
  # Launch the awt program
  EXIT_CODE = # Get the exit code of the last process
WHILE (EXIT_CODE == RESTART_CODE)

Ứng dụng AWT sẽ thoát khỏi JVM bằng thứ gì đó khác với RESTART_CODE khi kết thúc "bình thường" không yêu cầu khởi động lại.


giải pháp rất thú vị. Vấn đề trên OSX là, thông thường, các ứng dụng Java được chạy từ một trình biên dịch JavaApplicationStub... Không chắc liệu có một cách dễ dàng để giải quyết vấn đề đó hay không.
Dan Rosenstark

7

Eclipse thường khởi động lại sau khi cài đặt plugin. Họ thực hiện việc này bằng cách sử dụng trình bao bọc eclipse.exe (ứng dụng trình khởi chạy) cho các cửa sổ. Ứng dụng này thực thi jar người chạy nhật thực lõi và nếu ứng dụng java nhật thực kết thúc bằng mã khởi chạy lại, eclipse.exe khởi động lại bàn làm việc. Bạn có thể tạo một bit tương tự của mã gốc, tập lệnh shell hoặc một trình bao bọc mã java khác để khởi động lại.


5

các cửa sổ

public void restartApp(){

    // This launches a new instance of application dirctly, 
    // remember to add some sleep to the start of the cmd file to make sure current instance is
    // completely terminated, otherwise 2 instances of the application can overlap causing strange
    // things:)

    new ProcessBuilder("cmd","/c start /min c:/path/to/script/that/launches/my/application.cmd ^& exit").start();
    System.exit(0);
}

/ phút để bắt đầu tập lệnh trong cửa sổ thu nhỏ

^ & exit để đóng cửa sổ cmd sau khi kết thúc

một tập lệnh cmd mẫu có thể là

@echo off
rem add some sleep (e.g. 10 seconds) to allow the preceding application instance to release any open resources (like ports) and exit gracefully, otherwise the new instance could fail to start
sleep 10   
set path=C:\someFolder\application_lib\libs;%path%
java -jar application.jar

ngủ 10 giấc ngủ trong 10 giây



4

Mặc dù câu hỏi này đã cũ và đã được trả lời, nhưng tôi đã tình cờ gặp vấn đề với một số giải pháp và quyết định thêm đề xuất của mình vào hỗn hợp.

Vấn đề với một số giải pháp là chúng xây dựng một chuỗi lệnh duy nhất. Điều này tạo ra các vấn đề khi một số tham số chứa khoảng trắng, đặc biệt là java.home .

Ví dụ: trên windows, dòng

final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";

Có thể trả lại một cái gì đó như thế này:C:\Program Files\Java\jre7\bin\java

Chuỗi này phải được đặt trong dấu ngoặc kép hoặc thoát do khoảng trống trong Program Files. Không phải là một vấn đề lớn, nhưng hơi khó chịu và dễ xảy ra lỗi, đặc biệt là trong các ứng dụng đa nền tảng.

Do đó, giải pháp của tôi xây dựng lệnh dưới dạng một mảng lệnh:

public static void restart(String[] args) {

        ArrayList<String> commands = new ArrayList<String>(4 + jvmArgs.size() + args.length);
        List<String> jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments();

        // Java
        commands.add(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");

        // Jvm arguments
        for (String jvmArg : jvmArgs) {
            commands.add(jvmArg);
        }

        // Classpath
        commands.add("-cp");
        commands.add(ManagementFactory.getRuntimeMXBean().getClassPath());

        // Class to be executed
        commands.add(BGAgent.class.getName());

        // Command line arguments
        for (String arg : args) {
            commands.add(arg);
        }

        File workingDir = null; // Null working dir means that the child uses the same working directory

        String[] env = null; // Null env means that the child uses the same environment

        String[] commandArray = new String[commands.size()];
        commandArray = commands.toArray(commandArray);

        try {
            Runtime.getRuntime().exec(commandArray, env, workingDir);
            System.exit(0);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3

Tôi đang tự nghiên cứu chủ đề này khi bắt gặp câu hỏi này.

Bất kể thực tế là câu trả lời đã được chấp nhận, tôi vẫn muốn đưa ra một cách tiếp cận thay thế để hoàn thiện. Cụ thể, Apache Ant là một giải pháp rất linh hoạt.

Về cơ bản, mọi thứ tổng hợp thành một tệp kịch bản Ant với một tác vụ thực thi Java duy nhất (tham khảo tại đâytại đây ) được gọi từ mã Java (xem tại đây ). Mã Java này, có thể là một phương thức khởi chạy , có thể là một phần của ứng dụng cần được khởi động lại. Ứng dụng cần có sự phụ thuộc vào thư viện Apache Ant (jar).

Bất cứ khi nào ứng dụng cần được khởi động lại, nó sẽ gọi phương thức khởi chạy và thoát khỏi máy ảo. Nhiệm vụ Ant java nên có các tùy chọn forkspawn được đặt thành true.

Đây là một ví dụ về tập lệnh Ant:

<project name="applaucher" default="launch" basedir=".">
<target name="launch">
    <java classname="package.MasinClass" fork="true" spawn="true">
        <jvmarg value="-splash:splash.jpg"/>
        <jvmarg value="-D other VM params"/>
        <classpath>
            <pathelement location="lib-1.jar" />
            ...
            <pathelement location="lib-n.jar" />
        </classpath>
    </java>
</target>
</project>

Mã cho phương thức khởi chạy có thể trông giống như sau:

public final void launch(final String antScriptFile) {
 /* configure Ant and execute the task */
   final File buildFile = new File(antScriptFile);
   final Project p = new Project();
   p.setUserProperty("ant.file", buildFile.getAbsolutePath());

   final DefaultLogger consoleLogger = new DefaultLogger();
   consoleLogger.setErrorPrintStream(System.err);
   consoleLogger.setOutputPrintStream(System.out);
   consoleLogger.setMessageOutputLevel(Project.MSG_INFO);
   p.addBuildListener(consoleLogger);

   try {
       p.fireBuildStarted();
       p.init();
       final ProjectHelper helper = ProjectHelper.getProjectHelper();
       p.addReference("ant.projectHelper", helper);
       helper.parse(p, buildFile);
       p.executeTarget(p.getDefaultTarget());
       p.fireBuildFinished(null);
   } catch (final BuildException e) {
       p.fireBuildFinished(e);
   }

   /* exit the current VM */
   System.exit(0);

}

Một điều rất tiện lợi ở đây là cùng một tập lệnh được sử dụng để khởi động ứng dụng ban đầu cũng như khởi động lại.


3

Chỉ thêm thông tin không có trong các câu trả lời khác.

Nếu có sẵn procfs /proc/self/cmdline

Nếu bạn đang chạy trong môi trường cung cấp procfs và do đó có /procsẵn hệ thống tệp (có nghĩa là đây không phải là giải pháp di động), bạn có thể đọc Java /proc/self/cmdlineđể tự khởi động lại, như sau:

public static void restart() throws IOException {
    new ProcessBuilder(getMyOwnCmdLine()).inheritIO().start();
}
public static String[] getMyOwnCmdLine() throws IOException {
    return readFirstLine("/proc/self/cmdline").split("\u0000");
}
public static String readFirstLine(final String filename) throws IOException {
    try (final BufferedReader in = new BufferedReader(new FileReader(filename))) {
        return in.readLine();
    }
}

Trên các hệ thống có /proc/self/cmdlinesẵn, đây có lẽ là cách thanh lịch nhất để "khởi động lại" tiến trình Java hiện tại từ Java. Không có JNI tham gia và không cần đoán đường dẫn và nội dung. Điều này cũng sẽ xử lý tất cả các tùy chọn JVM được chuyển đến javanhị phân. Dòng lệnh sẽ hoàn toàn giống với dòng lệnh của quy trình JVM hiện tại.

Nhiều hệ thống UNIX bao gồm GNU / Linux (bao gồm cả Android) ngày nay có procfs Tuy nhiên, trên một số hệ thống như FreeBSD, nó không được dùng nữa và bị loại bỏ dần. Mac OS X là một ngoại lệ vì nó không có procfs . Windows cũng không có procfs . Cygwin có procfs nhưng nó vô hình với Java vì nó chỉ hiển thị với các ứng dụng sử dụng Cygwin DLL thay vì lệnh gọi hệ thống Windows và Java không biết về Cygwin.

Đừng quên sử dụng ProcessBuilder.inheritIO()

Mặc định là stdin/ stdout/ stderr(trong Java được gọi là System.in/ System.out/ System.err) của Quy trình đã bắt đầu được đặt thành các đường ống cho phép quy trình hiện đang chạy giao tiếp với quy trình mới bắt đầu. Nếu bạn muốn khởi động lại quy trình hiện tại, rất có thể đây không phải là điều bạn muốn . Thay vào đó, bạn muốn rằng stdin/ stdout/ stderrgiống với / của VM hiện tại. Điều này được gọi là kế thừa . Bạn có thể làm như vậy bằng cách gọi phiên bản inheritIO()của bạn ProcessBuilder.

Cạm bẫy trên Windows

Trường hợp sử dụng thường xuyên của một restart()chức năng là khởi động lại ứng dụng sau khi cập nhật. Lần cuối cùng tôi thử điều này trên Windows, điều này có vấn đề. Khi ghi đè .jartệp của ứng dụng bằng phiên bản mới, ứng dụng bắt đầu hoạt động sai và đưa ra các ngoại lệ về .jartệp. Tôi chỉ nói, trong trường hợp đây là trường hợp sử dụng của bạn. Trước đó, tôi đã giải quyết vấn đề bằng cách gói ứng dụng trong một tệp lô và sử dụng giá trị trả về kỳ diệu System.exit()mà từ đó tôi đã truy vấn trong tệp lô và thay vào đó, tệp lô sẽ khởi động lại ứng dụng.


2

Câu hỏi cũ và tất cả những điều đó. Nhưng đây là một cách khác mang lại một số lợi thế.

Trên Windows, bạn có thể yêu cầu bộ lập lịch tác vụ khởi động lại ứng dụng cho bạn. Điều này có lợi thế là đợi một khoảng thời gian cụ thể trước khi ứng dụng được khởi động lại. Bạn có thể đi tới trình quản lý tác vụ và xóa tác vụ và nó sẽ ngừng lặp lại.

SimpleDateFormat hhmm = new SimpleDateFormat("kk:mm");    
Calendar aCal = Calendar.getInstance(); 
aCal.add(Calendar.SECOND, 65);
String nextMinute = hhmm.format(aCal.getTime()); //Task Scheduler Doesn't accept seconds and won't do current minute.
String[] create = {"c:\\windows\\system32\\schtasks.exe", "/CREATE", "/F", "/TN", "RestartMyProg", "/SC", "ONCE", "/ST", nextMinute, "/TR", "java -jar c:\\my\\dev\\RestartTest.jar"};  
Process proc = Runtime.getRuntime().exec(create, null, null);
System.out.println("Exit Now");
try {Thread.sleep(1000);} catch (Exception e){} // just so you can see it better
System.exit(0);

2

Tương tự như câu trả lời ' cải tiến ' của Yoda , nhưng với những cải tiến hơn nữa (cả chức năng, khả năng đọc và khả năng kiểm tra). Bây giờ nó an toàn để chạy và khởi động lại nhiều lần với số lượng đối số chương trình đã cho.

  • Không tích lũy các JAVA_TOOL_OPTIONStùy chọn.
  • Tự động tìm lớp chính.
  • Kế thừa stdout / stderr hiện tại.

public static void main(String[] args) throws Exception {
    if (args.length == 0)
        return;
    else
        args = Arrays.copyOf(args, args.length - 1);

    List<String> command = new ArrayList<>(32);
    appendJavaExecutable(command);
    appendVMArgs(command);
    appendClassPath(command);
    appendEntryPoint(command);
    appendArgs(command, args);

    System.out.println(command);
    try {
        new ProcessBuilder(command).inheritIO().start();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

private static void appendJavaExecutable(List<String> cmd) {
    cmd.add(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
}

private static void appendVMArgs(Collection<String> cmd) {
    Collection<String> vmArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();

    String javaToolOptions = System.getenv("JAVA_TOOL_OPTIONS");
    if (javaToolOptions != null) {
        Collection<String> javaToolOptionsList = Arrays.asList(javaToolOptions.split(" "));
        vmArguments = new ArrayList<>(vmArguments);
        vmArguments.removeAll(javaToolOptionsList);
    }

    cmd.addAll(vmArguments);
}

private static void appendClassPath(List<String> cmd) {
    cmd.add("-cp");
    cmd.add(ManagementFactory.getRuntimeMXBean().getClassPath());
}

    private static void appendEntryPoint(List<String> cmd) {
    StackTraceElement[] stackTrace          = new Throwable().getStackTrace();
    StackTraceElement   stackTraceElement   = stackTrace[stackTrace.length - 1];
    String              fullyQualifiedClass = stackTraceElement.getClassName();
    String              entryMethod         = stackTraceElement.getMethodName();
    if (!entryMethod.equals("main"))
        throw new AssertionError("Entry point is not a 'main()': " + fullyQualifiedClass + '.' + entryMethod);

    cmd.add(fullyQualifiedClass);
}

private static void appendArgs(List<String> cmd, String[] args) {
    cmd.addAll(Arrays.asList(args));
}

V1.1 Sửa lỗi: con trỏ null nếu JAVA_TOOL_OPTIONS không được đặt


Thí dụ:

$ java -cp Temp.jar Temp a b c d e
[/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp, a, b, c, d]
[/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp, a, b, c]
[/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp, a, b]
[/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp, a]
[/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java, -cp, Temp.jar, Temp]
$

-13
System.err.println("Someone is Restarting me...");
setVisible(false);
try {
    Thread.sleep(600);
} catch (InterruptedException e1) {
    e1.printStackTrace();
}
setVisible(true);

Tôi đoán bạn không thực sự muốn dừng ứng dụng, nhưng để "Khởi động lại" nó. Đối với điều đó, bạn có thể sử dụng điều này và thêm "Đặt lại" của mình trước khi ngủ và sau cửa sổ ẩn.


4
Người dùng yêu cầu khởi động lại ứng dụng chứ không chỉ ẩn và hiện một cửa sổ.
Amr Lotfy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.