java - কশন - জাভা ফ্রেমওয়ার্ক




কিভাবে একটি জাভা প্রোগ্রাম নিজস্ব প্রক্রিয়া আইডি পেতে পারেন? (15)

Scala মধ্যে:

import sys.process._
val pid: Long = Seq("sh", "-c", "echo $PPID").!!.trim.toLong

জাভা 9টি মুক্তি না হওয়া পর্যন্ত এটি আপনাকে ইউনিক্স সিস্টেমগুলিতে একটি কার্যকর কাজ করবে। (আমি জানি, প্রশ্নটি জাভা সম্পর্কে ছিল, কিন্তু স্কালার জন্য সমান প্রশ্ন নেই, তাই আমি Scala ব্যবহারকারীদের জন্য এটি ছেড়ে দিতে চেয়েছিলাম যারা একই প্রশ্নে পড়ে যেতে পারে।)

আমি কিভাবে আমার জাভা প্রক্রিয়া আইডি পেতে পারি?

আমি অনেক প্ল্যাটফর্ম নির্ভর হ্যাক আছে জানেন, কিন্তু আমি একটি আরো জেনারিক সমাধান পছন্দ করবে।


অন্যান্য সমাধান যোগ করা হচ্ছে।

জাভা 10 দিয়ে, process id পেতে

final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final long pid = runtime.getPid();
out.println("Process ID is '" + pid);

আপনি JNA ব্যবহার করতে পারেন। দুর্ভাগ্যবশত বর্তমান প্রক্রিয়া আইডি পেতে এখনো কোন সাধারণ জেএনএ API নেই, তবে প্রতিটি প্ল্যাটফর্মটি বেশ সহজ:

উইন্ডোজ

আপনি jna-platform.jar তারপর নিশ্চিত করুন:

int pid = Kernel32.INSTANCE.GetCurrentProcessId();

ইউনিক্স

ঘোষণা:

private interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);   
    int getpid ();
}

তারপর:

int pid = CLibrary.INSTANCE.getpid();

জাভা 9

জাভা 9 এর অধীনে বর্তমান প্রক্রিয়া আইডি পেতে নতুন প্রক্রিয়া API ব্যবহার করা যেতে পারে। প্রথমে আপনি বর্তমান প্রক্রিয়াতে একটি হ্যান্ডেল ধরবেন, তারপর PID অনুসন্ধান করুন:

long pid = ProcessHandle.current().pid();

আপনি আমার প্রকল্প চেক আউট করতে পারেন: GitHub এ JavaSysMon । এটি প্রক্রিয়া আইডি এবং অন্যান্য স্টাফগুলির একটি গুচ্ছ প্রদান করে (CPU ব্যবহার, মেমরি ব্যবহার) ক্রস প্ল্যাটফর্ম (বর্তমানে উইন্ডোজ, ম্যাক OSX, Linux এবং Solaris)


আমি জানি এটি একটি পুরানো থ্রেড, তবে আমি পিআইডি পাওয়ার জন্য সেই API টি (এবং রানটাইম এ জাভা প্রসেসের অন্যান্য ম্যানিপুলেশন) পাওয়ার জন্য কল করতে চেয়েছিলাম JDK 9: openjdk.java.net/jeps/102 এ প্রসেস ক্লাসে openjdk.java.net/jeps/102


এই একই প্রয়োজন ছিল যখন আমি কি ব্যবহার করা হয়। এটি জাভা প্রক্রিয়াটির PID সঠিকভাবে নির্ধারণ করে। আপনার জাভা কোডটি একটি পূর্ব-সংজ্ঞায়িত পোর্ট নাম্বারে একটি সার্ভার স্পন করুন এবং তারপরে পোর্টে পড শোনার জন্য OS কমান্ডগুলি চালান। লিনাক্সের জন্য

netstat -tupln | grep portNumber

এখানে আমার সমাধান:

public static boolean isPIDInUse(int pid) {

        try {

            String s = null;
            int java_pid;

            RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
            java_pid = Integer.parseInt(rt.getName().substring(0, rt.getName().indexOf("@")));

            if (java_pid == pid) {
                System.out.println("In Use\n");
                return true;
            }
        } catch (Exception e) {
            System.out.println("Exception:  " + e.getMessage());
        }
        return false;
    }

এখানে একটি ব্যাকডোর পদ্ধতি যা সমস্ত ভিএমগুলির সাথে কাজ করে না তবে এটি লিনাক্স এবং উইন্ডোজ ( এখানে আসল উদাহরণ ) উভয় ক্ষেত্রেই কাজ করা উচিত:

java.lang.management.RuntimeMXBean runtime = 
    java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =  
    (sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =  
    mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);

int pid = (Integer) pid_method.invoke(mgmt);

জাভা 9 এর থেকে একটি পদ্ধতি হল Process.getPid () যা একটি প্রক্রিয়ার নেটিভ আইডি প্রদান করে:

public abstract class Process {

    ...

    public long getPid();
}

বর্তমান জাভা প্রক্রিয়াটির প্রক্রিয়া আইডি পেতে ProcessHandle ইন্টারফেস ব্যবহার করতে পারেন:

System.out.println(ProcessHandle.current().pid());

নিম্নলিখিত পদ্ধতিটি java.lang.management.ManagementFactory থেকে PID বের করার চেষ্টা করে। java.lang.management.ManagementFactory :

private static String getProcessId(final String fallback) {
    // Note: may fail in some JVM implementations
    // therefore fallback has to be provided

    // something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
    final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
    final int index = jvmName.indexOf('@');

    if (index < 1) {
        // part before '@' empty (index = 0) / '@' not found (index = -1)
        return fallback;
    }

    try {
        return Long.toString(Long.parseLong(jvmName.substring(0, index)));
    } catch (NumberFormatException e) {
        // ignore
    }
    return fallback;
}

উদাহরণস্বরূপ, getProcessId("<PID>") কল করুন।


সম্পূর্ণতা জন্য স্প্রিং বুট একটি মোড়ক আছে

String jvmName = ManagementFactory.getRuntimeMXBean().getName();
return jvmName.split("@")[0];

সমাধান। একটি পূর্ণসংখ্যা প্রয়োজন হলে, এটি এক-মাছ ধরার নৌকা পর্যন্ত সংক্ষেপ করা যেতে পারে:

int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);

কেউ ইতিমধ্যে স্প্রিং বুট ব্যবহার করে, সে / তিনি org.springframework.boot.plicationPid ব্যবহার করতে পারে

ApplicationPid pid = new ApplicationPid();
pid.toString();

ToString () পদ্ধতিটি পিড বা '???' প্রিন্ট করে।

ManagementFactory ব্যবহার করে ক্যাভিট ইতিমধ্যে অন্যান্য উত্তর আলোচনা করা হয়।


সর্বশেষটি পাওয়া গেছে যে sun.java.launcher.pid নামে একটি সিস্টেমের সম্পত্তি রয়েছে যা অন্তত লিনাক্সে পাওয়া যায়। আমার পরিকল্পনাটি ব্যবহার করা হয় এবং যদি এটি JMX bean ব্যবহার না পাওয়া যায়।


SIGAR 2.0 লাইসেন্সের SIGAR সম্পর্কে অশ্বিন জয়প্রকাশের answer (+1) এর উপর ভিত্তি করে, এখানে আমি কীভাবে বর্তমান প্রক্রিয়াটির PID পাওয়ার জন্য এটি ব্যবহার করব:

import org.hyperic.sigar.Sigar;

Sigar sigar = new Sigar();
long pid = sigar.getPid();
sigar.close();

যদিও এটি সমস্ত প্ল্যাটফর্মগুলিতে কাজ করে না তবে এটি লিনাক্স, উইন্ডোজ, ওএস এক্স এবং বিভিন্ন ইউনিক্স প্ল্যাটফর্মগুলিতে এখানে তালিকাবদ্ধ হিসাবে কাজ করে


কোন প্ল্যাটফর্ম-স্বাধীন উপায় নেই যা সমস্ত জেভিএম বাস্তবায়নে কাজ করার জন্য নিশ্চিত হতে পারে। ManagementFactory.getRuntimeMXBean().getName() সর্বোত্তম (সবচেয়ে কাছের) সমাধানের মতো দেখায়। এটি সংক্ষিপ্ত, এবং সম্ভবত ব্যাপক ব্যবহারের প্রতিটি বাস্তবায়নে কাজ করে।

লিনাক্স + উইন্ডোতে এটি [email protected] মত একটি মান প্রদান করে ( 12345 প্রক্রিয়া আইডি)। যদিও ডক্স অনুসারে , এই মান সম্পর্কে কোন নিশ্চয়তা নেই:

চলমান জাভা ভার্চুয়াল মেশিন প্রতিনিধিত্ব করে নামটি প্রদান করে। প্রত্যাবর্তিত নাম স্ট্রিং কোনও নির্বিচারে স্ট্রিং হতে পারে এবং জাভা ভার্চুয়াল মেশিন বাস্তবায়ন ফিরতি নাম স্ট্রিংয়ে প্ল্যাটফর্ম-নির্দিষ্ট দরকারী তথ্য এম্বেড করতে পারে। প্রতিটি চলমান ভার্চুয়াল মেশিন একটি ভিন্ন নাম থাকতে পারে।

জাভা 9 এ নতুন প্রক্রিয়া API ব্যবহার করা যেতে পারে:

long pid = ProcessHandle.current().pid();

java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split("@")[0]





pid