ฉันจะรีสตาร์ทแอปพลิเคชัน Java AWT ได้อย่างไร ฉันมีปุ่มที่ฉันแนบตัวจัดการเหตุการณ์ ฉันควรใช้รหัสใดในการรีสตาร์ทแอปพลิเคชัน
ฉันต้องการทำสิ่งเดียวกับที่Application.Restart()
ทำในแอปพลิเคชัน C #
ฉันจะรีสตาร์ทแอปพลิเคชัน Java AWT ได้อย่างไร ฉันมีปุ่มที่ฉันแนบตัวจัดการเหตุการณ์ ฉันควรใช้รหัสใดในการรีสตาร์ทแอปพลิเคชัน
ฉันต้องการทำสิ่งเดียวกับที่Application.Restart()
ทำในแอปพลิเคชัน C #
คำตอบ:
แน่นอนว่าสามารถรีสตาร์ทแอปพลิเคชัน Java ได้
วิธีการต่อไปนี้แสดงวิธีการรีสตาร์ทแอ็พพลิเคชัน 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);
}
โดยทั่วไปจะทำสิ่งต่อไปนี้:
MyClassInTheJar
คลาสเพื่อค้นหาตำแหน่งโถเอง)System.exit(0)
ยุติกระบวนการย่อยมีคำตอบเดียวกันหรือไม่ว่าคำตอบนี้ได้ผลจริงหรือไม่และเพราะเหตุใด หากคุณไม่สามารถให้คำอธิบายที่สมเหตุสมผลพร้อมกับคำตอบของคุณได้แสดงว่าคุณทำได้ไม่ดี คำตอบที่ให้คำถามมากกว่าคำตอบไม่ใช่ตัวอย่างของคำตอบอย่างละเอียด คำตอบที่ดีไม่เพียง แต่แสดงรหัส แต่ยังอธิบายถึงวิธีการและเหตุผลที่ใช้งานได้ว่ามีข้อเสียอย่างไรและทางเลือกอื่นคืออะไร คุณไม่ได้พยายามปกปิดสิ่งเหล่านี้ด้วยซ้ำ
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);
}
}
อุทิศให้ทุกคนที่บอกว่าเป็นไปไม่ได้
โปรแกรมนี้รวบรวมข้อมูลทั้งหมดที่มีเพื่อสร้างบรรทัดคำสั่งเดิมขึ้นใหม่ จากนั้นจะเปิดใช้งานและเนื่องจากเป็นคำสั่งเดียวกันแอปพลิเคชันของคุณจะเริ่มทำงานเป็นครั้งที่สอง จากนั้นเราออกจากโปรแกรมดั้งเดิมโปรแกรมลูกยังคงทำงานอยู่ (แม้ใน Linux) และทำสิ่งเดียวกัน
คำเตือน : ถ้าคุณทำงานนี้จะทราบว่ามันไม่เคยสิ้นสุดการสร้างกระบวนการใหม่คล้ายกับระเบิดส้อม
ManagementFactory.getRuntimeMXBean().getInputArguments()
จะให้อาร์กิวเมนต์อินพุตที่ส่งผ่านไปยัง JVM เท่านั้น ไม่มีพารามิเตอร์ที่ส่งผ่านไปยังแอปพลิเคชันของคุณ เช่นjava -jar start.jar -MISSED_PARAM=true
. ใน oracle jvm คุณสามารถดึงพารามิเตอร์เหล่านั้นโดยใช้System.getProperty("sun.java.command")
.
ProcessBuilder
และinheritIO()
VM ลูกสามารถเริ่มต้นในลักษณะที่ VM แม่จะสิ้นสุด
โดยพื้นฐานแล้วคุณทำไม่ได้ อย่างน้อยก็ไม่ใช่วิธีที่เชื่อถือได้ อย่างไรก็ตามคุณไม่จำเป็นต้องทำ
ในการรีสตาร์ทโปรแกรม Java คุณต้องรีสตาร์ท JVM ในการรีสตาร์ท JVM คุณต้อง
ค้นหาjava
ตัวเรียกใช้งานที่ใช้ คุณอาจลองใช้System.getProperty("java.home")
แต่ไม่มีการรับประกันว่าสิ่งนี้จะชี้ไปที่ตัวเรียกใช้งานที่ใช้เปิดแอปพลิเคชันของคุณ (ค่าที่ส่งคืนอาจไม่ชี้ไปที่ JRE ที่ใช้เปิดแอปพลิเคชันหรืออาจถูกแทนที่ด้วย-Djava.home
)
คุณน่าจะต้องการใช้การตั้งค่าหน่วยความจำดั้งเดิมเป็นต้น ( -Xmx
, -Xms
... ) ดังนั้นคุณต้องพิจารณาว่าการตั้งค่าใดที่ใช้ในการเริ่ม JVM แรก คุณสามารถลองใช้ManagementFactory.getRuntimeMXBean().getInputArguments()
แต่ไม่มีการรับประกันว่าจะแสดงการตั้งค่าที่ใช้ สิ่งนี้สะกดแม้กระทั่งในเอกสารของวิธีการนั้น:
โดยทั่วไปแล้วตัวเลือกบรรทัดคำสั่งบางส่วนของคำสั่ง 'java' จะไม่ถูกส่งไปยังเครื่องเสมือน Java ดังนั้นอาร์กิวเมนต์อินพุตที่ส่งคืนอาจไม่มีตัวเลือกบรรทัดคำสั่งทั้งหมด
หากโปรแกรมของคุณอ่านอินพุตจากStandard.in
stdin ดั้งเดิมจะหายไปในการรีสตาร์ท
เคล็ดลับและแฮ็กเหล่านี้จำนวนมากจะล้มเหลวต่อหน้าไฟล์SecurityManager
.
ฉันขอแนะนำให้คุณออกแบบแอปพลิเคชันของคุณเพื่อให้ง่ายต่อการทำความสะอาดทุกสิ่งและหลังจากนั้นให้สร้างอินสแตนซ์ใหม่ของคลาส "หลัก" ของคุณ
แอปพลิเคชั่นจำนวนมากได้รับการออกแบบมาเพื่อทำอะไรเลยนอกจากสร้างอินสแตนซ์ในเมธอดหลัก:
public class MainClass {
...
public static void main(String[] args) {
new MainClass().launch();
}
...
}
ด้วยการใช้รูปแบบนี้มันควรจะง่ายพอที่จะทำสิ่งต่างๆเช่น:
public class MainClass {
...
public static void main(String[] args) {
boolean restart;
do {
restart = new MainClass().launch();
} while (restart);
}
...
}
และปล่อยให้launch()
คืนค่าเป็นจริงในกรณีที่แอปพลิเคชันถูกปิดในลักษณะที่ต้องเริ่มต้นใหม่เท่านั้น
พูดอย่างเคร่งครัดโปรแกรม Java ไม่สามารถรีสตาร์ทตัวเองได้เนื่องจากจะดำเนินการดังนั้นจึงต้องฆ่า JVM ที่กำลังทำงานอยู่จากนั้นเริ่มต้นใหม่อีกครั้ง แต่เมื่อ JVM ไม่ทำงานอีกต่อไป (ถูกฆ่า) แล้วจะไม่สามารถดำเนินการใด ๆ ได้
คุณสามารถใช้เทคนิคบางอย่างกับคลาสโหลดเดอร์ที่กำหนดเองเพื่อโหลดแพ็คและเริ่มส่วนประกอบ AWT อีกครั้ง แต่อาจทำให้ปวดหัวมากเกี่ยวกับลูปเหตุการณ์ GUI
ขึ้นอยู่กับวิธีการเปิดแอปพลิเคชันคุณสามารถเริ่ม JVM ในสคริปต์ wrapper ซึ่งมีลูป do / while ซึ่งจะดำเนินต่อไปในขณะที่ JVM ออกพร้อมกับรหัสเฉพาะจากนั้นแอป AWT จะต้องเรียกSystem.exit(RESTART_CODE)
ใช้ ตัวอย่างเช่นในการเขียนสคริปต์ pseudocode:
DO
# Launch the awt program
EXIT_CODE = # Get the exit code of the last process
WHILE (EXIT_CODE == RESTART_CODE)
แอป AWT ควรออกจาก JVM ด้วยสิ่งอื่นที่ไม่ใช่ RESTART_CODE เมื่อการยุติ "ปกติ" ซึ่งไม่ต้องรีสตาร์ท
JavaApplicationStub
... ไม่แน่ใจว่ามีวิธีง่ายๆหรือไม่
java my-program.java
และบรรทัดสุดท้ายของไฟล์แบตช์คือif "%ERRORLEVEL%" EQU "1" java my-program.java
ถ้าโปรแกรมของฉันออกพร้อมกับSystem.exit(1)
มันจะรีสตาร์ทมิฉะนั้นSystem.exit(0)
จะทำให้ปิด แม้ว่าฉันจะสามารถทำได้โดยใช้ java บริสุทธิ์มาก่อน (การเพิ่ม hook การปิดระบบ + โดยใช้ processbuilder.inheritIO () เพื่อ stdin / out จะถูกส่งผ่านไปยังกระบวนการใหม่) วิธีนี้ง่ายกว่ามาก
โดยทั่วไป Eclipse จะรีสตาร์ทหลังจากติดตั้งปลั๊กอินแล้ว โดยใช้ wrapper eclipse.exe (แอปตัวเรียกใช้งาน) สำหรับ windows แอ็พพลิเคชันนี้เรียกใช้งาน jar ของรันเนอร์ eclipse หลักและหากแอ็พพลิเคชัน eclipse java สิ้นสุดลงด้วยโค้ดเปิดใช้งานใหม่ eclipse.exe จะรีสตาร์ทเวิร์กเบนช์ คุณสามารถสร้างโค้ดเนทีฟบิตเชลล์สคริปต์หรือ wrapper รหัส java อื่นที่คล้ายกันเพื่อให้รีสตาร์ท
Windows
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);
}
/ นาทีเพื่อเริ่มสคริปต์ในหน้าต่างย่อเล็กสุด
^ &ออกเพื่อปิดหน้าต่าง cmd หลังจากเสร็จสิ้น
ตัวอย่างสคริปต์ cmd อาจเป็น
@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
นอน 10หลับ 10 วินาที
หากคุณต้องการรีสตาร์ทแอปจริงๆคุณสามารถเขียนแอปแยกต่างหากเพื่อเริ่มต้น ...
หน้านี้มีตัวอย่างต่างๆมากมายสำหรับสถานการณ์ต่างๆ:
แม้ว่าคำถามนี้จะเก่าและมีคำตอบ แต่ฉันพบปัญหาเกี่ยวกับวิธีแก้ปัญหาบางอย่างและตัดสินใจเพิ่มข้อเสนอแนะของฉันลงในส่วนผสม
ปัญหาของโซลูชันบางอย่างคือพวกเขาสร้างสตริงคำสั่งเดียว นี้จะสร้างปัญหาเมื่อพารามิเตอร์บางมีช่องว่างโดยเฉพาะอย่างยิ่งjava.home
ตัวอย่างเช่นบน windows บรรทัด
final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
อาจส่งคืนสิ่งนี้:C:\Program Files\Java\jre7\bin\java
Program Files
สายนี้จะต้องมีการห่อในเครื่องหมายคำพูดหรือหนีเนื่องจากพื้นที่ใน ไม่ใช่ปัญหาใหญ่ แต่ค่อนข้างน่ารำคาญและเกิดข้อผิดพลาดโดยเฉพาะในแอปพลิเคชันข้ามแพลตฟอร์ม
ดังนั้นโซลูชันของฉันจึงสร้างคำสั่งเป็นอาร์เรย์ของคำสั่ง:
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();
}
}
เพียงแค่เพิ่มข้อมูลที่ไม่มีอยู่ในคำตอบอื่น ๆ
/proc/self/cmdline
ใช้ได้หากคุณกำลังรันในสภาพแวดล้อมที่จัดเตรียมprocfsดังนั้นจึงมี/proc
ระบบไฟล์ที่พร้อมใช้งาน (ซึ่งหมายความว่านี่ไม่ใช่โซลูชันแบบพกพา) คุณสามารถให้ Java อ่าน/proc/self/cmdline
เพื่อรีสตาร์ทตัวเองได้ดังนี้:
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();
}
}
บนระบบที่พร้อม/proc/self/cmdline
ใช้งานนี่อาจเป็นวิธีที่ดีที่สุดในการ "รีสตาร์ท" กระบวนการ Java ปัจจุบันจาก Java ไม่มี JNI เกี่ยวข้องและไม่ต้องคาดเดาเส้นทางและสิ่งต่างๆ นอกจากนี้ยังดูแลตัวเลือก JVM ทั้งหมดที่ส่งไปยังjava
ไบนารี บรรทัดคำสั่งจะเหมือนกับกระบวนการ JVM ปัจจุบันทุกประการ
ระบบ UNIX จำนวนมากรวมถึง GNU / Linux (รวมถึง Android) ในปัจจุบันมีprocfsอย่างไรก็ตามในบางระบบเช่น FreeBSD จะเลิกใช้งานและกำลังจะยุติลง Mac OS Xเป็นข้อยกเว้นในแง่ที่ว่ามันไม่ได้มี procfs ของ Windowsยังไม่ได้มีprocfs Cygwin มีprocfsแต่ไม่สามารถมองเห็นได้ใน Java เนื่องจากสามารถมองเห็นได้เฉพาะแอปพลิเคชันที่ใช้ Cygwin DLL แทนการเรียกระบบ Windows และ Java ไม่รู้จัก Cygwin
ProcessBuilder.inheritIO()
ค่าดีฟอลต์คือstdin
/ stdout
/ stderr
(ใน Java เรียกว่าSystem.in
/ System.out
/ System.err
) ของกระบวนการเริ่มต้นถูกตั้งค่าเป็นไปป์ซึ่งอนุญาตให้กระบวนการที่กำลังทำงานอยู่ในปัจจุบันสื่อสารกับกระบวนการที่เพิ่งเริ่มต้นใหม่ หากคุณต้องการที่จะเริ่มต้นกระบวนการในปัจจุบันนี้เป็นส่วนใหญ่มีแนวโน้มไม่ได้สิ่งที่คุณต้องการ แต่คุณต้องการให้stdin
/ stdout
/ stderr
เหมือนกับ VM ปัจจุบัน นี้เรียกว่าได้รับมรดก คุณสามารถทำได้โดยเรียกอินสแตนซ์inheritIO()
ของคุณProcessBuilder
กรณีการใช้งานบ่อยครั้งของrestart()
ฟังก์ชันคือการรีสตาร์ทแอปพลิเคชันหลังจากการอัปเดต ครั้งสุดท้ายที่ฉันลองใช้ Windows สิ่งนี้มีปัญหา เมื่อเขียนทับ.jar
ไฟล์ของแอปพลิเคชันด้วยเวอร์ชันใหม่แอปพลิเคชันจะเริ่มทำงานผิดปกติและให้ข้อยกเว้นเกี่ยวกับ.jar
ไฟล์ ฉันแค่บอกในกรณีนี้เป็นกรณีการใช้งานของคุณ ย้อนกลับไปตอนนั้นฉันแก้ไขปัญหาโดยการตัดแอปพลิเคชันในไฟล์แบตช์และใช้ค่าส่งคืนวิเศษจากSystem.exit()
ที่ฉันสอบถามในไฟล์แบตช์และให้ไฟล์แบตช์รีสตาร์ทแอปพลิเคชันแทน
.jar
ไฟล์ที่สร้างขึ้นใหม่จากไดเร็กทอรี build build\libs\my.jar
ไปยังไดเร็กทอรีการทำงานปัจจุบันแล้วเรียกใช้สิ่งนั้นแทน สิ่งนี้หลีกเลี่ยงไม่ให้ฉันเขียนทับ jar ที่กำลังทำงานอยู่ (เนื่องจากฉันรวบรวม jar ของฉันใหม่โดยอัตโนมัติระหว่างการรีสตาร์ท) และวิธีนี้ยังช่วยให้มี jar ที่รันได้เสมอในกรณีที่การอัพเดต / คอมไพล์ล้มเหลว โดยที่การรีสตาร์ทจะเรียกใช้ jar ที่คอมไพล์ไว้ก่อนหน้านี้
ฉันกำลังค้นคว้าเรื่องนี้ด้วยตัวเองเมื่อเจอคำถามนี้
แม้ว่าคำตอบจะได้รับการยอมรับแล้วก็ตามฉันก็ยังคงต้องการเสนอแนวทางอื่นเพื่อความสมบูรณ์ โดยเฉพาะ Apache Ant เป็นโซลูชันที่ยืดหยุ่นมาก
โดยพื้นฐานแล้วทุกอย่างจะเข้าสู่ไฟล์ Ant script ด้วยภารกิจการเรียกใช้ Java เดียว (ดูที่นี่และที่นี่ ) เรียกใช้จากโค้ด Java (ดูที่นี่ ) รหัสนี้ Java ซึ่งอาจเป็นวิธีที่เปิดตัวอาจจะเป็นส่วนหนึ่งของโปรแกรมที่จะต้องมีการเริ่มต้นใหม่ แอปพลิเคชันจำเป็นต้องมีการพึ่งพาไลบรารี Apache Ant (jar)
เมื่อใดก็ตามที่แอพลิเคชันจะต้องมีการเริ่มต้นใหม่ก็ควรเรียกวิธีการเปิดตัวและออกจาก VM งาน Ant java ควรมีอ็อพชันforkและspawnตั้งค่าเป็น true
นี่คือตัวอย่างของ Ant script:
<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>
รหัสสำหรับวิธีการเปิดตัวอาจมีลักษณะดังนี้:
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);
}
สิ่งที่สะดวกมากที่นี่คือสคริปต์เดียวกันนี้ใช้สำหรับการเริ่มต้นแอปพลิเคชันครั้งแรกและการรีสตาร์ท
คำถามเก่าและทั้งหมดนั้น แต่นี่เป็นอีกวิธีหนึ่งที่มีข้อดีบางประการ
ใน Windows คุณสามารถขอให้ตัวกำหนดตารางเวลางานเริ่มแอปให้คุณอีกครั้ง สิ่งนี้มีข้อดีคือการรอระยะเวลาหนึ่งก่อนที่แอปจะรีสตาร์ท คุณสามารถไปที่ตัวจัดการงานและลบงานและหยุดทำซ้ำ
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);
คล้ายกับคำตอบที่ ' ปรับปรุงแล้ว ' ของ Yoda แต่มีการปรับปรุงเพิ่มเติม (ทั้งฟังก์ชันการทำงานการอ่านและการทดสอบ) ขณะนี้สามารถเรียกใช้งานได้อย่างปลอดภัยและรีสตาร์ทได้หลายครั้งตามจำนวนอาร์กิวเมนต์ของโปรแกรมที่กำหนด
JAVA_TOOL_OPTIONS
ตัวเลือก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 Bugfix: null pointer หากไม่ได้ตั้งค่า JAVA_TOOL_OPTIONS
ตัวอย่าง:
$ 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]
$
System.err.println("Someone is Restarting me...");
setVisible(false);
try {
Thread.sleep(600);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
setVisible(true);
ฉันเดาว่าคุณไม่ต้องการหยุดแอปพลิเคชัน แต่ต้องการ "รีสตาร์ท" คุณสามารถใช้สิ่งนี้และเพิ่ม "รีเซ็ต" ของคุณก่อนเข้าสู่โหมดสลีปและหลังหน้าต่างที่มองไม่เห็น