আমি কীভাবে একটি জাভা অ্যাপ্লিকেশন পুনরায় চালু করতে পারি?


95

আমি কীভাবে জাভা এডাব্লুটি অ্যাপ্লিকেশনটি পুনরায় চালু করতে পারি? আমার একটি বোতাম আছে যা আমি একটি ইভেন্ট হ্যান্ডলার সংযুক্ত করেছি। অ্যাপ্লিকেশনটি পুনরায় চালু করতে আমার কোন কোড ব্যবহার করা উচিত?

আমি Application.Restart()সি সি প্রয়োগে একই জিনিস করতে চাই।


4
আপনার প্রশ্নটি আমি বুঝতে পারি না। আপনি কি চান আপনার অ্যাপ্লিকেশনটিতে একটি বোতাম রয়েছে যা অ্যাপ্লিকেশনটি পুনরায় চালু করবে? সুতরাং, অ্যাপ্লিকেশনটি আর চলার পরে, এটি নিজেই পুনরায় চালু করতে সক্ষম হওয়া উচিত? এটা আমার কাছে অসম্ভব মনে হচ্ছে।
জে

আমি জিজ্ঞাসা করছি না যে জেভিএম থামার পরে, আমি জিজ্ঞাসা করছি যে আমি কীভাবে আমার প্রধান জাভা ফ্রেমটিকে পুনর্বার করতে পারি?
আজফার নিয়াজ

4
অসম্ভব না. আমি দেখছি গ্রহণের ওয়ার্কবেঞ্চ প্রায়শই পুনঃসূচনা হয়, এমনকি উইন্ডোজ আপডেটের পরেও এই কৌশলটি করে। ভ্রান্ত ধারণাটি হ'ল অ্যাপ্লিকেশন হ'ল একমাত্র জিনিস যার নীচে কিছুই নেই। আমাদের পুনঃসূচনা করতে সক্ষম সক্ষম লঞ্চারের প্রয়োজন হবে, সমস্ত ভাবে কচ্ছপ।
হোয়ানটিক

সি # অ্যাপ্লিকেশনের মতো ঠিক তেমন পদ্ধতিতেও আপনি সিস্টেম.স্টার্ট () লিখতে পারেন?
আজফার নিয়াজ

@ অ্যানিয়াজ তখন আপনার ফ্রেমটি প্রদর্শন / আড়াল করতে চান তা উল্লেখ করার জন্য আপনার প্রশ্নটি আপডেট করা উচিত। অ্যাপ্লিকেশনটি ফ্রেম নয়।
হোয়ানটিক

উত্তর:


106

অবশ্যই একটি জাভা অ্যাপ্লিকেশন পুনরায় চালু করা সম্ভব।

নিম্নলিখিত পদ্ধতিটি জাভা অ্যাপ্লিকেশনটি পুনরায় চালু করার একটি উপায় দেখায়:

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) শিশু প্রক্রিয়াটি বন্ধ করবে না?
Horcrux7

16
@ ওয়েজার প্রশ্নটি System.exit(0)শিশু প্রক্রিয়াটি সমাপ্ত করে কিনা এই উত্তরটি সত্যই কার্যকর হয় এবং কেন তা একই উত্তর রয়েছে। আপনি যদি নিজের উত্তরের পাশাপাশি বুদ্ধিমান ব্যাখ্যা সরবরাহ করতে না পারেন তবে আপনি একটি খারাপ কাজ করেছেন। উত্তর যা তার চেয়ে বেশি প্রশ্নের জবাব দেয় তা কোনও উত্তরের উত্তরের উদাহরণ নয়। ভাল উত্তরগুলি কেবল কোডটিই দেখায় না তবে তারা কীভাবে এবং কেন কাজ করে, ত্রুটিগুলি কী এবং বিকল্পগুলি কী তা ব্যাখ্যা করে। আপনি এই জিনিসগুলি কভার করার চেষ্টা করেননি।
টোমা জ্যাটো - মনিকা পুনরায় ইনস্টল করুন

8
@ হরক্রাক্স's এর প্রশ্নের উত্তর দিতে হবে কিনা তা নিয়ে বিতর্ক করছে এমন অনেক মন্তব্য। আপনি লোকেরা শুরু থেকেই তার উত্তরটি উত্তর দিতে পারতেন ol ভাল আমি এগিয়ে যাব এবং এটি করব (দেরীতে আমি জানি): না এটি হয় না। সেখানে
ভলডেমর্ট

10
আমার প্রশ্নের নিজের উত্তর। নমুনা কাজ করে না !!! System.exit (0) ক্লায়েন্ট প্রক্রিয়াটি অবিলম্বে সমাপ্ত করে।
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);
    }
}

যারা অসম্ভব বলে তাদের সকলকে উত্সর্গীকৃত।

এই প্রোগ্রামটি মূল কমান্ডলাইনটি পুনর্গঠনের জন্য উপলভ্য সমস্ত তথ্য সংগ্রহ করে। তারপরে, এটি এটি আরম্ভ করে এবং যেহেতু এটি খুব একই আদেশ, তাই আপনার অ্যাপ্লিকেশনটি দ্বিতীয়বার শুরু হয়। তারপরে আমরা আসল প্রোগ্রামটি থেকে প্রস্থান করি, শিশু প্রোগ্রামটি চলমান থাকবে (এমনকি লিনাক্সের অধীনেও) এবং একই জিনিসটি করে।

সতর্কতা : আপনি যদি এটি চালনা করেন তবে সচেতন থাকুন যে এটি কাঁটা বোমার মতো নতুন প্রক্রিয়া তৈরি করা কখনই শেষ হয় না ।


সম্ভাব্য উন্নতি ManagementFactory.getRuntimeMXBean().getInputArguments() কেবল আপনাকে জেভিএমকে দেওয়া ইনপুট আর্গুমেন্ট দেবে। এটি আপনার অ্যাপ্লিকেশনটিতে পাস করা প্যারামিটারগুলি মিস করে। যেমন java -jar start.jar -MISSED_PARAM=true,। একটি ওরাকল জেভিএম এ, আপনি ব্যবহার করে সেই পরামিতিগুলি পুনরুদ্ধার করতে পারেন System.getProperty("sun.java.command")
ক্রিস

4
পিতা-মাতার ভিএম শেষ হতে পারে যদি শিশু ভিএম এবং পিতা-মাতা ভিএম একে অপরের সাথে পাইপগুলির সাথে সংযুক্ত না হয়, যা শিশু ভিএম শুরু করার পথে ঘটেছিল। ব্যবহার করে ProcessBuilderএবং inheritIO(), শিশু ভিএম এমনভাবে শুরু করা যেতে পারে যাতে পিতা বা মাতা ভিএম শেষ হয়।
খ্রিস্টান হুজার

4
আমি এই যাওয়ার একটি সংস্করণ পেয়েছি এই মন্তব্যটি কীভাবে এটি বন্ধ করতে হবে তা আপনাকে জানাতে হবে: জাভা.এক্সে থাকা পথে এমন কোনও কিছুর নামকরণ করুন।
ডেল

এটি পুনরায় আরম্ভ না করে কঠোরভাবে কথা বলছে তবে এটির মতো একই যুক্তি সহ একটি নতুন জেভিএম চালু করছে।
থোরবজর্ন রাভন অ্যান্ডারসন

4
পার্থক্য কি? কোনও পিসি পুনরায় চালু করার এবং ওএস + এটি আবার বুট করে বন্ধ করার মধ্যে কী পার্থক্য রয়েছে?
মাইনারসবার

29

মূলত, আপনি পারবেন না। কমপক্ষে নির্ভরযোগ্য উপায়ে নয়। তবে আপনার দরকার নেই to

পারবনা অংশ

একটি জাভা প্রোগ্রামটি পুনঃসূচনা করতে আপনার জেভিএম পুনরায় চালু করতে হবে। জেভিএম পুনরায় চালু করতে আপনার প্রয়োজন

  1. নির্ণয় করুন javaলঞ্চার যে ব্যবহার করা হয়েছে। আপনি চেষ্টা করে দেখতে পারেন System.getProperty("java.home")তবে কোনও গ্যারান্টি নেই যে এটি আপনার অ্যাপ্লিকেশন লঞ্চ করতে ব্যবহৃত লঞ্চারটির দিকেই নির্দেশ করবে। (প্রত্যাবর্তিত মানটি অ্যাপ্লিকেশন আরম্ভ করার জন্য ব্যবহৃত জেআরইতে নির্দেশিত হতে পারে বা এটি দ্বারা ওভাররাইড করা যেতে পারে -Djava.home))

  2. আপনি সম্ভবতঃ মূল মেমরি সেটিংস ইত্যাদি (সম্মান করতে চান -Xmx, -Xms, ...) তাই আপনি চিত্রে আউট যা সেটিংস যেখানে ব্যবহৃত প্রথম জেভিএম শুরু করার জন্য প্রয়োজন। আপনি ব্যবহার করার চেষ্টা করতে পারেন ManagementFactory.getRuntimeMXBean().getInputArguments()তবে এর কোনও গ্যারান্টি নেই যে এটি ব্যবহৃত সেটিংস প্রতিফলিত করবে। এমনকি এই পদ্ধতির নথিতে এটি বানানও রয়েছে :

    সাধারণত, java কমান্ডের সমস্ত কমান্ড-লাইন বিকল্প জাভা ভার্চুয়াল মেশিনে দেওয়া হয় না। সুতরাং, ফিরে আসা ইনপুট আর্গুমেন্টগুলিতে সমস্ত কমান্ড-লাইন বিকল্প অন্তর্ভুক্ত নাও হতে পারে।

  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()যদি অ্যাপ্লিকেশনটি এমনভাবে শুরু করা দরকার যে কেবল অ্যাপ্লিকেশনটি বন্ধ করা হয়েছিল এবং কেবল তখনই সত্যটি ফিরে আসে।


4
আরও ভাল নকশা পরামর্শের জন্য +1; যদিও, কখনও কখনও এটি সম্ভব হয় না, বিশেষত উদাহরণস্বরূপ জেএনআই ব্যবহার করে।
ম্যারিক্স

ঠিক আছে, একটি নেটিভ লাইব্রেরি বিশ্বব্যাপী রাষ্ট্রটি সংশোধন করতে পারে যা জেএনআই ইন্টারফেস থেকে সংশোধন করা যায় না, সুতরাং প্রক্রিয়া পুনরায় চালু না করে প্রোগ্রামের অবস্থা "পুনঃসূচনা" করার উপায় থাকবে না। অবশ্যই, নেটিভ গ্রন্থাগারটি আরও ভালভাবে ডিজাইন করা উচিত তবে কখনও কখনও আপনি এমন জিনিসগুলির উপর নির্ভর করেন যা আপনি নিয়ন্ত্রণ করতে পারবেন না।
ম্যারিক্স

ঠিক আছে, তবে সেই যুক্তি সহ আপনার কিছু অভ্যন্তরীণ স্থিতিশীল ভেরিয়েবলগুলি সংশোধন করে খাঁটি জাভা-লাইব্রেরি থাকতে পারে। এটি যাইহোক একটি ডিজাইনের ত্রুটি হবে এবং ভাল লিখিত লাইব্রেরিতে না ঘটে।
আইয়ুব

4
আপনার উত্তরটি ভুল, যেহেতু এটি মেইনবার্বার এবং আমার নিজের উত্তর হিসাবে প্রদর্শিত বাহ্যিক অ্যাপ্লিকেশন / ডেমন ছাড়াই পুরোপুরি সম্ভব। এবং স্ব-আপডেট করার উদ্দেশ্যে একটি অ্যাপ্লিকেশন পুনরায় চালু করা একটি ভাল সমাধান, সুতরাং অ্যাপ্লিকেশনগুলিকে আবারও চালু করার প্রয়োজন রয়েছে।
ভিগার

4
কিন্তু আপনি কি একটি বহিরাগত অ্যাপ্লিকেশন ব্যবহার করুন: java! আপনি ভুলে যাচ্ছেন যে জাভা কোনও ভাষা নয়, কোনও প্রোগ্রাম নয়, যদি আমি উদাহরণস্বরূপ ক্যাফের মতো আরও কিছু জেভিএম ব্যবহার করে আপনার প্রোগ্রামটি চালিত করি ? যাইহোক আমার উত্তর আপডেট করুন :-)
আইয়ুব

10

কড়া কথায় বলতে গেলে, একটি জাভা প্রোগ্রাম নিজেকে পুনরায় আরম্ভ করতে পারে না তাই এটি অবশ্যই জেভিএম চালিয়ে যাবে এবং এটি আবার শুরু করতে হবে, তবে একবার জেভিএম আর চালিত (নিহত) না হলে কোনও পদক্ষেপ নেওয়া যায় না।

আপনি কাস্টম ক্লাসলোডারদের সাথে আবার এডাব্লিউটি উপাদানগুলি লোড, প্যাক করতে এবং শুরু করতে কিছু কৌশল করতে পারেন তবে এটি জিইউআই ইভেন্টের লুপের ক্ষেত্রে প্রচুর মাথা ব্যথার কারণ হতে পারে।

অ্যাপ্লিকেশনটি কীভাবে চালু হয় তার উপর নির্ভর করে আপনি জেভিএমকে একটি মোড়ক স্ক্রিপ্টে শুরু করতে পারেন যার মধ্যে ডু / উইন্ড লুপ রয়েছে যা জেভিএম নির্দিষ্ট কোড সহ প্রস্থান করার সময় অব্যাহত থাকে, তবে এডাব্লুটি অ্যাপ্লিকেশনটিকে কল করতে হবে 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 অ্যাপ্লিকেশনটি JVM থেকে "সাধারণ" সমাপ্তির জন্য RESTART_CODE ব্যতীত অন্য কিছু দিয়ে প্রস্থান করা উচিত যা পুনরায় আরম্ভের প্রয়োজন হয় না।


খুব আকর্ষণীয় সমাধান। ওএসএক্সের সমস্যাটি হ'ল, সাধারণত, জাভা অ্যাপ্লিকেশনগুলি একটি সংকলিত থেকে চালিত হয় JavaApplicationStub... এর আশপাশে কোনও সহজ উপায় আছে কিনা তা নিশ্চিত নয়।
ড্যান রোজনস্টার্ক

7

একটি প্লাগইন ইনস্টল হওয়ার পরে সাধারণত গ্রহন পুনঃসূচনা হয়। তারা উইন্ডোজের জন্য একটি মোড়ক 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);
}

/ মিনিট হ্রাস উইন্ডোতে স্ক্রিপ্ট শুরু করতে

^ & সমাপ্তির পরে সেন্টিমিডি উইন্ডোটি বন্ধ করতে প্রস্থান করুন

একটি নমুনা সেমিডি স্ক্রিপ্ট হতে পারে

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

4

কেবল এমন তথ্য যুক্ত করা যা অন্য উত্তরে উপস্থিত নেই।

যদি procfs /proc/self/cmdline উপলব্ধ থাকে

আপনি যদি এমন পরিবেশে চলছেন যা প্রোফগুলি সরবরাহ করে এবং সেইজন্য /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। কমান্ড লাইনটি বর্তমান জেভিএম প্রক্রিয়াটির একটির অনুরূপ হবে।

জিএনইউ / লিনাক্স (অ্যান্ড্রয়েড সহ) সহ অনেকগুলি ইউনিক্স সিস্টেমে আজকাল প্রোফস রয়েছে তবে ফ্রিবিএসডি-র মতো কিছু ক্ষেত্রে, এটি অবনতিযুক্ত এবং পর্যায়ক্রমে চলে গেছে। ম্যাক ওএস এক্স এই অর্থে একটি ব্যতিক্রম যে এটি প্রোফস নেইউইন্ডোজ এছাড়াও নেই জন্য procfs । Cygwin হয়েছে জন্য procfs কিন্তু এটি জাভা অদৃশ্য কারণ এটি শুধুমাত্র Windows সিস্টেম কল Cygwin ডিএলএল ব্যবহার অ্যাপ্লিকেশন পরিবর্তে কাছে দৃশ্যমান, এবং জাভা Cygwin অবিদিত নয়।

ব্যবহার করতে ভুলবেন না ProcessBuilder.inheritIO()

ডিফল্টটি হ'ল যে stdin/ stdout/ stderr(জাভাতে বলা System.in/ System.out/ System.err) প্রবর্তিত প্রক্রিয়াটি পাইপে সেট করা থাকে যা বর্তমানে চলমান প্রক্রিয়াটিকে সদ্য শুরু হওয়া প্রক্রিয়াটির সাথে যোগাযোগের সুযোগ দেয় allow আপনি যদি বর্তমান প্রক্রিয়াটি পুনরায় চালু করতে চান তবে এটি সম্ভবত আপনি চান তা নয় । পরিবর্তে আপনি চাইবেন যে stdin/ stdout/ stderrবর্তমান ভিএম এর সমান। এই বলা হয় উত্তরাধিকার সূত্রে । আপনি inheritIO()নিজের ProcessBuilderউদাহরণটি কল করে এটি করতে পারেন ।

উইন্ডোতে পিটফল

কোনও restart()ফাংশনের ঘন ঘন ব্যবহারের ক্ষেত্রে আপডেটের পরে অ্যাপ্লিকেশনটি পুনরায় চালু করা হয়। উইন্ডোজে সর্বশেষবার চেষ্টা করার সময় এটি সমস্যাযুক্ত ছিল। .jarনতুন সংস্করণে অ্যাপ্লিকেশনটির ফাইলটি ওভাররোট করার সময় অ্যাপ্লিকেশনটি দুর্ব্যবহার করা এবং .jarফাইলটি সম্পর্কে ব্যতিক্রম দেওয়া শুরু করে । আমি কেবল বলছি, যদি এটি আপনার ব্যবহারের ক্ষেত্রে হয়। এরপরে আমি ব্যাচ ফাইলে অ্যাপ্লিকেশনটি গুটিয়ে রেখে ব্যাচ ফাইলে System.exit()জিজ্ঞাসা করেছি এবং এর পরিবর্তে ব্যাচ ফাইলটি পুনরায় অ্যাপ্লিকেশনটি পুনঃসূচনা করার জন্য ব্যাচ ফাইলে অ্যাপ্লিকেশনটি গুটিয়ে রেখে সমস্যার সমাধান করেছি।


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

}

এখানে একটি খুব সুবিধাজনক জিনিস হ'ল একই স্ক্রিপ্টটি প্রাথমিক অ্যাপ্লিকেশন শুরু করার পাশাপাশি পুনরায় আরম্ভের জন্য ব্যবহৃত হয়।


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বিকল্পের জমে নেই ।
  • স্বয়ংক্রিয়ভাবে প্রধান শ্রেণীর সন্ধান করে।
  • বর্তমান স্টাডাউট / স্টাডারকে উত্তরাধিকারী

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
ব্যবহারকারী কেবল উইন্ডোটি লুকান এবং প্রদর্শন না করে অ্যাপ্লিকেশনটি পুনরায় চালু করতে বলে।
আম্র লটফাই
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.