मैं जावा एप्लिकेशन को कैसे पुनः आरंभ कर सकता हूं?


94

मैं Java AWT एप्लिकेशन को कैसे पुनः आरंभ कर सकता हूं? मेरे पास एक बटन है जिससे मैंने एक इवेंट हैंडलर संलग्न किया है। एप्लिकेशन को पुनरारंभ करने के लिए मुझे किस कोड का उपयोग करना चाहिए?

मैं वही काम करना चाहता हूं Application.Restart()जो C # एप्लिकेशन में करता हूं।


2
शायद मैं आपके सवाल को नहीं समझ पा रहा हूँ। आप चाहते हैं कि आपके एप्लिकेशन में एक बटन हो जो एप्लिकेशन को पुनरारंभ करता हो? इसलिए, ऐप के चलने के बाद, यह स्वयं को पुनरारंभ करने में सक्षम होना चाहिए? यह मेरे लिए असंभव लगता है।
जे

मैं यह नहीं पूछ रहा हूं कि जेवीएम बंद होने के बाद, मैं यह पूछ रहा हूं कि मैं अपने मुख्य जावा फ्रेम का जवाब कैसे दे सकता हूं?
अज़फर नियाज़

2
असंभव नहीं। मुझे लगता है कि ग्रहण कार्यक्षेत्र अक्सर पुनरारंभ होता है, यहां तक ​​कि विंडोज़ भी अपडेट के बाद इस चाल को करता है। झूठी धारणा यह है कि आवेदन केवल एक चीज है जो इसके नीचे कुछ भी नहीं के साथ चल रहा है। हमें फिर से सक्षम लांचर की आवश्यकता होगी, सभी तरह से नीचे कछुए होंगे।
13

ठीक उसी तरह जिस तरह C # एप्लीकेशन में, जहाँ आप ऐसा करने के लिए System.restart () लिख सकते हैं?
अज़फर नियाज़

@aniaz तब आपको उस फ़्रेम को दिखाने / छिपाने के लिए इंगित करने के लिए प्रश्न को अपडेट करना चाहिए। आवेदन फ्रेम नहीं है।
13

जवाबों:


105

बेशक यह जावा एप्लिकेशन को पुनरारंभ करना संभव है।

निम्नलिखित विधि जावा एप्लिकेशन को पुनरारंभ करने का एक तरीका दिखाती है:

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);
}

मूल रूप से यह निम्न कार्य करता है:

  1. जावा निष्पादन योग्य खोजें (मैंने यहां जावा बाइनरी का इस्तेमाल किया, लेकिन यह आपकी आवश्यकताओं पर निर्भर करता है)
  2. एप्लिकेशन खोजें (मेरे मामले में एक जार, MyClassInTheJarजार स्थान को खोजने के लिए कक्षा का उपयोग करके )
  3. जार को पुनरारंभ करने के लिए एक कमांड बनाएँ (इस मामले में जावा बाइनरी का उपयोग करके)
  4. इसे निष्पादित करो! (और इस प्रकार वर्तमान एप्लिकेशन को समाप्त करके इसे फिर से शुरू करना)

5
क्या एक छोटी समय सीमा नहीं है जिसमें एक ही ऐप के दो संस्करण एक ही समय में चल रहे हैं?
मोनीर

5
क्या System.exit (0) बच्चे की प्रक्रिया को समाप्त नहीं करेगा?
होरक्रक्स 7

16
@Veger प्रश्न कि क्या System.exit(0)बाल प्रक्रिया को समाप्त करने का एक ही उत्तर है कि क्या यह उत्तर वास्तव में काम करता है और क्यों। यदि आप अपने उत्तर के साथ समझदार स्पष्टीकरण नहीं दे सकते हैं, तो आपने एक बुरा काम किया है। उत्तर जो उत्तर से अधिक प्रश्न प्रदान करता है, वह पूर्ण उत्तर का उदाहरण नहीं है। अच्छे उत्तर केवल कोड नहीं दिखाते हैं, बल्कि यह भी बताते हैं कि वे कैसे और क्यों काम करते हैं, कि कमियां क्या हैं और विकल्प क्या हैं। आपने इन चीजों को कवर करने की कोशिश भी नहीं की।
टॉम ज़ातो - मोनिका

8
@ Horcrux7 के प्रश्न का उत्तर देना है या नहीं, इस पर बहस करते हुए कई टिप्पणियां। तुम लोग बस उसे शुरुआत से जवाब दे सकते थे। ठीक है, मैं आगे जाऊंगा और यह करूँगा (मुझे पता है देर से): नहीं, यह नहीं है। वहाँ।
वोल्डेमॉर्ट

10
मेरे सवालों का जवाब देने के लिए स्व। नमूना काम नहीं करता है !!! System.exit (0) क्लाइंट प्रक्रिया को तत्काल समाप्त करता है।
होरक्रक्स ru

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);
    }
}

उन सभी को समर्पित जो कहते हैं कि यह असंभव है।

यह कार्यक्रम मूल कमांडलाइन के पुनर्निर्माण के लिए उपलब्ध सभी जानकारी एकत्र करता है। फिर, यह इसे लॉन्च करता है और चूंकि यह एक ही कमांड है, इसलिए आपका एप्लिकेशन दूसरी बार शुरू होता है। फिर हम मूल कार्यक्रम से बाहर निकलते हैं, बच्चा प्रोग्राम चलता रहता है (लिनक्स के तहत भी) और यही काम करता है।

चेतावनी : यदि आप इसे चलाते हैं, तो ध्यान रखें कि यह कांटा बम के समान नई प्रक्रियाओं का निर्माण कभी नहीं करता है ।


संभावित सुधार ManagementFactory.getRuntimeMXBean().getInputArguments() आपको केवल JVM को दिए गए इनपुट तर्क देगा। यह आपके आवेदन के लिए दिए गए मापदंडों को याद करता है। जैसे, java -jar start.jar -MISSED_PARAM=true। एक ओरेकल जेवीएम पर, आप उन मापदंडों का उपयोग करके पुनः प्राप्त कर सकते हैं System.getProperty("sun.java.command")
क्रिस

1
यदि बच्चा VM शुरू कर दिया जाता है तो बच्चे के वीएम और पैरेंट वीएम एक दूसरे से जुड़े नहीं होंगे, यदि बच्चा वीएम शुरू होता है, तो माता-पिता वीएम समाप्त हो सकता है। का उपयोग करके ProcessBuilderऔर inheritIO(), बच्चे VM को इस तरह से शुरू किया जा सकता है कि मूल VM समाप्त हो जाएगा।
क्रिश्चियन हुजेर

1
मुझे इसके जाने का एक संस्करण मिला। यह टिप्पणी आपको यह बताने के लिए है कि इसे कैसे रोकें: java.exe वाले पथ में कुछ नाम बदलें।
डेल

यह कड़ाई से पुनः आरंभ नहीं बोल रहा है, लेकिन यह एक ही तर्क के साथ एक नया JVM लॉन्च कर रहा है।
थोरबजोरन रेव एंडरसन

4
क्या फर्क पड़ता है? क्या पीसी को पुनरारंभ करने और ओएस + को बंद करने और फिर से इसे बूट करने के बीच कोई अंतर है?
मीनर्सबर

27

असल में, तुम नहीं कर सकते। कम से कम एक विश्वसनीय तरीके से नहीं। हालाँकि, आपको इसकी आवश्यकता नहीं होनी चाहिए।

नहीं कर सकते हैं हिस्सा

जावा प्रोग्राम को पुनरारंभ करने के लिए, आपको जेवीएम को पुनरारंभ करना होगा। जेवीएम को पुनः आरंभ करने के लिए आपको आवश्यक है

  1. javaउपयोग किए गए लॉन्चर का पता लगाएँ । आप के साथ प्रयास कर सकते हैं, System.getProperty("java.home")लेकिन इस बात की कोई गारंटी नहीं है कि यह वास्तव में उस लांचर को इंगित करेगा जो आपके एप्लिकेशन को लॉन्च करने के लिए उपयोग किया गया था। (लौटाया गया मान उस JRE को इंगित नहीं कर सकता है जिसका उपयोग एप्लिकेशन लॉन्च करने के लिए किया गया था या इसके द्वारा ओवरराइड किया जा सकता था -Djava.home।)

  2. आप मूल स्मृति सेटिंग्स आदि ( ,…) का सम्मान करना चाहते हैं -Xmx, -Xmsइसलिए आपको यह पता लगाने की आवश्यकता है कि पहले जेवीएम शुरू करने के लिए कौन सी सेटिंग्स का उपयोग किया जाता था। आप उपयोग करने का प्रयास कर सकते हैं ManagementFactory.getRuntimeMXBean().getInputArguments()लेकिन इसकी कोई गारंटी नहीं है कि यह उपयोग की गई सेटिंग्स को प्रतिबिंबित करेगा। यह उस विधि के प्रलेखन में भी लिखा गया है :

    आमतौर पर, जावा वर्चुअल मशीन को 'जावा' कमांड के सभी कमांड-लाइन विकल्प पास नहीं किए जाते हैं। इस प्रकार, दिए गए इनपुट तर्कों में सभी कमांड-लाइन विकल्प शामिल नहीं हो सकते हैं।

  3. यदि आपका प्रोग्राम Standard.inमूल स्टड से इनपुट पढ़ता है , तो पुनरारंभ में खो जाएगा।

  4. इन चालों और हैक के बहुत सारे एक की उपस्थिति में विफल हो जाएगा 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()यदि एप्लिकेशन को इस तरह से बंद कर दिया गया था कि उसे फिर से शुरू करने की जरूरत है, तो उसे सच होने दें।


3
बेहतर डिजाइन सलाह के लिए +1; हालांकि, कभी-कभी यह संभव नहीं होता है, खासकर अगर जेएनआई का उपयोग करना, उदाहरण के लिए।
मैरिकिक्स

ठीक है, एक देशी पुस्तकालय वैश्विक राज्य को संशोधित कर सकता है जिसे जेएनआई इंटरफ़ेस से संशोधित नहीं किया जा सकता है, इसलिए प्रक्रिया को पुनरारंभ करने के अलावा कार्यक्रम की स्थिति को "पुनरारंभ" करने का कोई तरीका नहीं होगा। बेशक, देशी पुस्तकालय को बेहतर डिज़ाइन किया जाना चाहिए लेकिन कभी-कभी आप उन चीजों पर निर्भर होते हैं जिन्हें आप नियंत्रित नहीं कर सकते हैं।
मैरिकिक्स

ठीक है, लेकिन उस तर्क के साथ, आप बस कुछ आंतरिक स्थैतिक चर को संशोधित करने वाला शुद्ध जावा-पुस्तकालय कर सकते हैं। यह हालांकि एक डिजाइन दोष होगा और अच्छी तरह से लिखित पुस्तकालयों में नहीं होना चाहिए।
Aioobe

1
आपका उत्तर गलत है, क्योंकि यह बाहरी अनुप्रयोगों / डेमन के बिना भी पूरी तरह से संभव है जैसा कि मीनर्सबर्क और मेरे अपने उत्तर द्वारा दिखाया गया है। और किसी अनुप्रयोग को पुनः आरंभ करने के लिए स्व-अद्यतन उद्देश्यों के लिए एक अच्छा समाधान है, इसलिए वास्तव में अनुप्रयोगों को फिर से शुरू करने की आवश्यकता है।
वीगर

1
लेकिन आप एक बाहरी अनुप्रयोग का उपयोग करते हैं java:! आप भूल रहे हैं कि जावा एक भाषा विनिर्देश है, न कि एक कार्यक्रम। क्या होगा यदि मैं उदाहरण के लिए कुछ अन्य jvm, जैसे कि कैफ का उपयोग करके आपका कार्यक्रम चलाता हूं ? वैसे भी मेरे जवाब को नवीनीकृत :-)
aioobe

9

कड़ाई से बोलते हुए, एक जावा प्रोग्राम स्वयं को पुनरारंभ नहीं कर सकता क्योंकि ऐसा करने के लिए उसे जेवीएम को मारना होगा जिसमें यह चल रहा है और फिर इसे फिर से शुरू करें, लेकिन एक बार जेवीएम अब नहीं चल रहा है (मारा गया) तो कोई कार्रवाई नहीं की जा सकती।

आप कस्टम क्लास लोडर के साथ कुछ चालें कर सकते हैं लोड करने, पैक करने और AWT घटकों को फिर से शुरू करने के लिए लेकिन इससे GUI इवेंट लूप के संबंध में बहुत सारे सिरदर्द हो सकते हैं।

अनुप्रयोग कैसे लॉन्च किया जाता है, इसके आधार पर, आप जेवीएम को एक रैपर स्क्रिप्ट में शुरू कर सकते हैं जिसमें एक डू / जबकि लूप होता है, जो जारी रहता है जबकि जेवीएम एक विशेष कोड के साथ बाहर निकलता है, तो AWT ऐप को कॉल करना होगा System.exit(RESTART_CODE)। उदाहरण के लिए, स्क्रिप्टिंग स्यूडोकोड में:

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

AWT ऐप को "सामान्य" समाप्ति पर RESTART_CODE के अलावा किसी अन्य चीज़ के साथ JVM से बाहर निकलना चाहिए, जिसे पुनरारंभ करने की आवश्यकता नहीं है।


बहुत दिलचस्प समाधान। OSX पर समस्या यह है कि, आम तौर पर, जावा ऐप्स एक संकलित से चलाए जाते हैं JavaApplicationStub... यकीन नहीं होता कि अगर इसके आसपास कोई आसान तरीका है।
दान रोसेनस्टार्क

7

एक प्लगइन स्थापित होने के बाद ग्रहण आम तौर पर पुनरारंभ होता है। वे विंडोज़ के लिए एक रैपर eclipse.exe (लॉन्चर ऐप) का उपयोग करके ऐसा करते हैं। यह एप्लिकेशन कोर एक्लिप्स रनर जार निष्पादित करता है और यदि एक्लेवा जावा एप्लिकेशन एक रिले कोड के साथ समाप्त हो जाता है, तो eclipse.exe कार्यक्षेत्र को पुनरारंभ करता है। पुनरारंभ को प्राप्त करने के लिए आप एक समान बिट कोड, शेल स्क्रिप्ट या अन्य जावा कोड आवरण बना सकते हैं।


5

खिड़कियाँ

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 नींद सोएं


4

यदि आपको अपने ऐप को पुनः आरंभ करने की आवश्यकता है, तो आप इसे शुरू करने के लिए एक अलग ऐप लिख सकते हैं ...

यह पृष्ठ विभिन्न परिदृश्यों के लिए कई अलग-अलग उदाहरण प्रदान करता है:

http://www.rgagnon.com/javadetails/java-0014.html


4

यद्यपि यह प्रश्न पुराना है और उत्तर दिया गया है, मैं कुछ समस्याओं के साथ एक समस्या में फंस गया हूं और अपने सुझाव को मिश्रण में जोड़ने का निर्णय लिया है।

कुछ समाधानों के साथ समस्या यह है कि वे एकल कमांड स्ट्रिंग का निर्माण करते हैं। यह समस्या पैदा करता है जब कुछ मापदंडों में रिक्त स्थान होता है, विशेष रूप से java.home

उदाहरण के लिए, खिड़कियों पर, रेखा

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();
        }
    }

3

मैं इस विषय पर खुद ही शोध कर रहा था।

इस तथ्य के बावजूद कि जवाब पहले से ही स्वीकार किया जाता है, मैं अभी भी पूर्णता के लिए एक वैकल्पिक दृष्टिकोण की पेशकश करना चाहूंगा। विशेष रूप से, अपाचे चींटी ने एक बहुत ही लचीले समाधान के रूप में कार्य किया।

मूल रूप से, एक चींटी स्क्रिप्ट फ़ाइल के लिए सब कुछ एक ही जावा निष्पादन कार्य ( यहाँ और यहां देखें ) के साथ एक जावा कोड ( यहां देखें) से उकसाया जाता है । यह जावा कोड, जो एक विधि लॉन्च हो सकता है, उस एप्लिकेशन का एक हिस्सा हो सकता है जिसे फिर से शुरू करने की आवश्यकता है। आवेदन को अपाचे चींटी पुस्तकालय (जार) पर निर्भरता की आवश्यकता है।

जब भी एप्लिकेशन को पुनरारंभ करने की आवश्यकता होती है, तो उसे विधि लॉन्च को कॉल करना चाहिए और वीएम से बाहर निकलना चाहिए । चींटी जावा कार्य में विकल्प कांटे और स्पॉन सेट करने के लिए सही होना चाहिए ।

यहाँ एक एंटी स्क्रिप्ट का एक उदाहरण है:

<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);

}

यहां एक बहुत ही सुविधाजनक बात यह है कि एक ही स्क्रिप्ट का उपयोग प्रारंभिक एप्लिकेशन स्टार्ट के साथ-साथ पुनरारंभ के लिए भी किया जाता है।


3

केवल उन सूचनाओं को जोड़ना जो अन्य उत्तरों में मौजूद नहीं हैं।

यदि procfs /proc/self/cmdline उपलब्ध है

यदि आप एक ऐसे वातावरण में चल रहे हैं जो procfs प्रदान करता है और इसलिए /procफ़ाइल सिस्टम उपलब्ध है (जिसका अर्थ है कि यह एक पोर्टेबल समाधान नहीं है), तो आप जावा /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बाइनरी में पारित सभी जेवीएम विकल्पों का भी ध्यान रखेगा । कमांड लाइन वर्तमान जेवीएम प्रक्रिया में से एक के समान होगी।

GNU / Linux (एंड्रॉइड सहित) सहित कई यूनिक्स सिस्टम आजकल खरीदे गए हैं, हालांकि कुछ पर FreeBSD की तरह, इसे हटा दिया गया है और चरणबद्ध किया जा रहा है। मैक ओएस एक्स इस अर्थ में एक अपवाद है कि इसकी खरीद नहीं होती हैविंडोज में भी प्रोक्योरमेंट्स नहीं हैं । सिग्विन ने खरीद की है लेकिन यह जावा के लिए अदृश्य है क्योंकि यह केवल विंडोज सिस्टम कॉल के बजाय सिग्विन डीएलएल का उपयोग करने वाले अनुप्रयोगों के लिए दिखाई देता है, और जावा साइगविन से अनजान है।

उपयोग करने के लिए मत भूलना ProcessBuilder.inheritIO()

डिफ़ॉल्ट यह है कि stdin/ stdout/ stderr(शुरू में जावा System.in/ System.out/ System.err) शुरू की प्रक्रिया पाइपों में सेट होती है जो वर्तमान में चल रही प्रक्रिया को नई शुरू की गई प्रक्रिया के साथ संवाद करने की अनुमति देती है। यदि आप वर्तमान प्रक्रिया को पुनः आरंभ करना चाहते हैं, तो यह सबसे अधिक संभावना है कि आप क्या चाहते हैं । इसके बजाय आप चाहते हैं कि stdin/ stdout/ stderrवर्तमान वीएम के समान हो। इसे वंशानुगत कहा जाता है । आप inheritIO()अपने ProcessBuilderउदाहरण को कॉल करके ऐसा कर सकते हैं ।

विंडोज पर नुकसान

किसी restart()फ़ंक्शन का लगातार उपयोग मामला अद्यतन के बाद एप्लिकेशन को पुनरारंभ करना है। पिछली बार जब मैंने विंडोज पर यह कोशिश की थी तो यह समस्याग्रस्त थी। जब .jarनए संस्करण के साथ एप्लिकेशन की फ़ाइल को ओवरराइड किया गया , तो एप्लिकेशन ने दुर्व्यवहार करना शुरू कर दिया और .jarफ़ाइल के बारे में अपवाद देना शुरू कर दिया । मैं सिर्फ यह बता रहा हूं, यदि यह आपका उपयोग मामला है। वापस तो मैंने एक बैच फ़ाइल में एप्लिकेशन को लपेटकर और उस मैजिक रिटर्न मान का उपयोग करके समस्या को हल किया, System.exit()जिसे मैंने बैच फ़ाइल में क्वेर किया था और बैच फ़ाइल के बजाय एप्लिकेशन को पुनरारंभ किया था।


2

पुराना सवाल और वह सब। लेकिन यह अभी तक एक और तरीका है जो कुछ फायदे प्रदान करता है।

विंडोज पर, आप कार्य अनुसूचक को आपके लिए अपना ऐप फिर से शुरू करने के लिए कह सकते हैं। इससे ऐप के पुनः आरंभ होने से पहले एक निश्चित समय तक प्रतीक्षा करने का लाभ है। आप कार्य प्रबंधक पर जा सकते हैं और कार्य को हटा सकते हैं और यह दोहराना बंद कर देता है।

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

योदा के ' बेहतर ' उत्तर के समान, लेकिन आगे के सुधार (कार्यात्मक, पठनीयता और परीक्षणशीलता दोनों) के साथ। यह अब चलाने के लिए सुरक्षित है, और जितनी बार प्रोग्राम तर्कों के लिए दिया गया है, उतनी बार पुनः आरंभ करें।

  • JAVA_TOOL_OPTIONSविकल्पों का संचय नहीं ।
  • स्वचालित रूप से मुख्य वर्ग पाता है।
  • वर्तमान stdout / stderr में प्रवेश करता है।

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 बगफिक्स: यदि 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]
$

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

मुझे लगता है कि आप वास्तव में एप्लिकेशन को रोकना नहीं चाहते हैं, लेकिन इसे "पुनरारंभ करें"। उसके लिए, आप इसका उपयोग कर सकते हैं और सोने से पहले और अदृश्य खिड़की के बाद अपना "रीसेट" जोड़ सकते हैं।


4
उपयोगकर्ता ने एप्लिकेशन को पुनरारंभ करने के लिए कहा न कि केवल छिपाएं और एक विंडो दिखाएं।
अमृत ​​लॉट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.