আমি কীভাবে আমার জাভা প্রক্রিয়াটির আইডি পেতে পারি?
আমি জানি যে প্ল্যাটফর্ম নির্ভর অনেক হ্যাক রয়েছে তবে আমি আরও জেনেরিক সমাধানটি পছন্দ করব।
আমি কীভাবে আমার জাভা প্রক্রিয়াটির আইডি পেতে পারি?
আমি জানি যে প্ল্যাটফর্ম নির্ভর অনেক হ্যাক রয়েছে তবে আমি আরও জেনেরিক সমাধানটি পছন্দ করব।
উত্তর:
প্ল্যাটফর্ম-স্বতন্ত্র উপায় নেই যা সমস্ত jvm বাস্তবায়নে কাজ করার গ্যারান্টিযুক্ত হতে পারে।
ManagementFactory.getRuntimeMXBean().getName()
সেরা (নিকটতম) সমাধানের মতো দেখায় looks এটি সংক্ষিপ্ত, এবং সম্ভবত বিস্তৃত ব্যবহারের প্রতিটি বাস্তবায়নে কাজ করে।
লিনাক্স + + Windows এ এটা পছন্দ একটি মান ফেরায় 12345@hostname
( 12345
প্রক্রিয়া ID হচ্ছে)। ডক্স অনুসারে সাবধান থাকুন , এই মান সম্পর্কে কোনও গ্যারান্টি নেই:
চলমান জাভা ভার্চুয়াল মেশিনের প্রতিনিধিত্বকারী নামটি দেয়। প্রত্যাবর্তিত নামের স্ট্রিংটি যেকোন স্বেচ্ছাসেবী স্ট্রিং হতে পারে এবং একটি জাভা ভার্চুয়াল মেশিন বাস্তবায়ন ফেরত নামের স্ট্রিংয়ে প্ল্যাটফর্ম-নির্দিষ্ট দরকারী তথ্য এম্বেড করা চয়ন করতে পারে। প্রতিটি চলমান ভার্চুয়াল মেশিনের আলাদা নাম থাকতে পারে।
জাভা 9 এ নতুন প্রক্রিয়া এপিআই ব্যবহার করা যেতে পারে:
long pid = ProcessHandle.current().pid();
আপনি জেএনএ ব্যবহার করতে পারেন । দুর্ভাগ্যক্রমে বর্তমান প্রক্রিয়া আইডি পাওয়ার জন্য কোনও সাধারণ জেএনএ এপিআই নেই তবে প্রতিটি প্ল্যাটফর্মটি বেশ সহজ:
আপনার অবশ্যই তা নিশ্চিত করুন 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 এর অধীনে নতুন প্রক্রিয়া এপিআই বর্তমান প্রসেস আইডি পেতে ব্যবহার করা যেতে পারে। প্রথমে আপনি বর্তমান প্রক্রিয়াটিতে একটি হ্যান্ডেল ধরুন, তারপরে পিআইডিটিকে জিজ্ঞাসা করুন:
long pid = ProcessHandle.current().pid();
getpid()
সমাধান এছাড়াও OS X এর জন্য কাজ করে, "সিস্টেম" লাইব্রেরিতে একটি JNA কলের মাধ্যমে।
error: cannot find symbol
jdk9
এখানে একটি ব্যাকডোর পদ্ধতি যা এর পারে সব ভার্চুয়াল মেশিনের সঙ্গে কাজ করে না কিন্তু (উভয় লিনাক্স এবং উইন্ডোজ কাজ করা উচিত এখানে মূল উদাহরণস্বরূপ ):
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);
getDeclaredMethod
ফিরে আসা অবজেক্টটি সম্পাদন করুন jvm.get(runtime)
।
সিগার চেষ্টা করুন । খুব বিস্তৃত এপিআই অ্যাপাচি 2 লাইসেন্স।
private Sigar sigar;
public synchronized Sigar getSigar() {
if (sigar == null) {
sigar = new Sigar();
}
return sigar;
}
public synchronized void forceRelease() {
if (sigar != null) {
sigar.close();
sigar = null;
}
}
public long getPid() {
return getSigar().getPid();
}
নিম্নলিখিত পদ্ধতিটি থেকে পিআইডি উত্তোলনের চেষ্টা করে 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>")
উদাহরণস্বরূপ কেবল কল করুন ।
পুরানো জেভিএমের জন্য, লিনাক্সে ...
private static String getPid() throws IOException {
byte[] bo = new byte[256];
InputStream is = new FileInputStream("/proc/self/stat");
is.read(bo);
for (int i = 0; i < bo.length; i++) {
if ((bo[i] < '0') || (bo[i] > '9')) {
return new String(bo, 0, i);
}
}
return "-1";
}
int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
। অতিরিক্ত গাইরেশন কেন?
getCanonicalFile()
পদ্ধতিতে এমন এক ধরণের যাদু যা "স্ব" কে পিআইডিতে রূপান্তর করে?
আপনি আমার প্রকল্পটি যাচাই করতে পারেন: গিটিহাবের জাভাসিসমন । এটি প্রক্রিয়া আইডি এবং অন্যান্য স্টাফগুলির একটি গুচ্ছ (সিপিইউ ব্যবহার, মেমরির ব্যবহার) ক্রস প্ল্যাটফর্ম সরবরাহ করে (বর্তমানে উইন্ডোজ, ম্যাক ওএসএক্স, লিনাক্স এবং সোলারিস)
জাভা 9-এর পরে একটি পদ্ধতি রয়েছে প্রসেস.জিটপিড () যা কোনও প্রক্রিয়ার নেটিভ আইডি প্রদান করে:
public abstract class Process {
...
public long getPid();
}
বর্তমান জাভা প্রক্রিয়াটির প্রসেস আইডি পেতে কেউ ProcessHandle
ইন্টারফেসটি ব্যবহার করতে পারে :
System.out.println(ProcessHandle.current().pid());
স্কালায়:
import sys.process._
val pid: Long = Seq("sh", "-c", "echo $PPID").!!.trim.toLong
জাভা 9 প্রকাশিত না হওয়া পর্যন্ত এটি আপনাকে ইউনিক্স সিস্টেমে একসাথে কাজ করবে। (আমি জানি, প্রশ্নটি জাভা সম্পর্কে ছিল, তবে যেহেতু স্কালার জন্য কোনও সমতুল্য প্রশ্ন নেই, তাই আমি এটি স্কালার ব্যবহারকারীদের জন্য রেখে যেতে চেয়েছিলাম যারা একই প্রশ্নে হোঁচট খায়)
সম্পূর্ণতার জন্য স্প্রিং বুটে একটি মোড়ক রয়েছে
String jvmName = ManagementFactory.getRuntimeMXBean().getName();
return jvmName.split("@")[0];
সমাধান। যদি কোনও পূর্ণসংখ্যার প্রয়োজন হয়, তবে এটি ওয়ান-লাইনার পর্যন্ত যোগ করা যেতে পারে:
int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
যদি কেউ ইতিমধ্যে স্প্রিং বুট ব্যবহার করে তবে সে org.springframework.boot ব্যবহার করতে পারে
ApplicationPid pid = new ApplicationPid();
pid.toString();
টোস্ট্রিং () পদ্ধতিটি পিড বা '???' মুদ্রণ করে।
ম্যানেজমেন্টফ্যাক্টরি ব্যবহার করে গুহাগুলি ইতিমধ্যে অন্যান্য উত্তরে আলোচনা করা হয়েছে।
সর্বশেষ যেটি আমি সন্ধান করেছি তা হ'ল একটি সিস্টেম সম্পত্তি রয়েছে যা sun.java.launcher.pid
অন্তত লিনাক্সে উপলব্ধ। আমার পরিকল্পনা এটি ব্যবহার করার এবং যদি এটি ব্যবহার করার সন্ধান না পাওয়া যায় JMX bean
।
আপনি কোথা থেকে তথ্য অনুসন্ধান করছেন তা নির্ভর করে।
আপনি যদি কনসোল থেকে তথ্য সন্ধান করছেন আপনি jps কমান্ডটি ব্যবহার করতে পারেন। কমান্ডটি ইউনিক্স পিএস কমান্ডের অনুরূপ আউটপুট দেয় এবং জেডিকে নিয়ে আসে যেহেতু আমি 1.5 বিশ্বাস করি
আপনি যদি প্রক্রিয়াটি থেকে সন্ধান করেন তবে রানটাইম এমএক্সবিয়ান (যেমন ওয়াউটার কোকার্টস বলেছেন) সম্ভবত আপনার সেরা পছন্দ। উইন্ডোজে সান জেডিকে 1.6 ইউ 7 ব্যবহার করে উইটনেম () থেকে আউটপুটটি [PROCESS_ID] @ [MACHINE_NAME] আকারে রয়েছে। তবে আপনি জেপিএস চালানোর চেষ্টা করতে এবং এর থেকে ফলাফলটি বিশ্লেষণ করতে পারেন:
String jps = [JDK HOME] + "\\bin\\jps.exe";
Process p = Runtime.getRuntime().exec(jps);
কোনও বিকল্প ছাড়াই চালিত হলে আউটপুটটি নামের পরে প্রক্রিয়া আইডি হওয়া উচিত।
এটি কোড জে কনসোল এবং সম্ভাব্য জেপিএস এবং ভিজুয়ালভিএম ব্যবহার করে। এটি sun.jvmstat.monitor.*
প্যাকেজ থেকে ক্লাস ব্যবহার করে
, থেকে tool.jar
।
package my.code.a003.process;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;
public class GetOwnPid {
public static void main(String[] args) {
new GetOwnPid().run();
}
public void run() {
System.out.println(getPid(this.getClass()));
}
public Integer getPid(Class<?> mainClass) {
MonitoredHost monitoredHost;
Set<Integer> activeVmPids;
try {
monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null));
activeVmPids = monitoredHost.activeVms();
MonitoredVm mvm = null;
for (Integer vmPid : activeVmPids) {
try {
mvm = monitoredHost.getMonitoredVm(new VmIdentifier(vmPid.toString()));
String mvmMainClass = MonitoredVmUtil.mainClass(mvm, true);
if (mainClass.getName().equals(mvmMainClass)) {
return vmPid;
}
} finally {
if (mvm != null) {
mvm.detach();
}
}
}
} catch (java.net.URISyntaxException e) {
throw new InternalError(e.getMessage());
} catch (MonitorException e) {
throw new InternalError(e.getMessage());
}
return null;
}
}
কয়েকটি ক্যাচ আছে:
tool.jar
একটি লাইব্রেরি ওরাকল JDK কিন্তু JRE সঙ্গে বিতরণ করা হয়!tool.jar
মাভেন রেপো থেকে পেতে পারবেন না ; মাভেনের সাথে এটি কনফিগার করা কিছুটা জটিলtool.jar
সম্ভবত প্ল্যাটফর্ম নির্ভরশীল (নেটিভ?) কোড রয়েছে তাই এটি সহজে বণ্টনযোগ্য নয়আপডেট: আমি ঠিক দ্বিগুণ পরীক্ষা করে দেখেছি যে জেপিএস এইভাবে ব্যবহার করে, এটি হল জেভিএমস্ট্যাট লাইব্রেরি (টুল.জারের অংশ)। সুতরাং জেপিএসকে বাহ্যিক প্রক্রিয়া হিসাবে কল করার দরকার নেই, আমার উদাহরণ হিসাবে দেখায় সরাসরি জেভিএমস্ট্যাট লাইব্রেরি কল করুন। আপনি এইভাবে লোকালহোস্টে সমস্ত জেভিএম রান্নিনের তালিকা পেতে পারেন। জেপিএস উত্স কোড দেখুন :
আমি অন্যান্য সমাধানে এটি যুক্ত করছি।
process id
final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final long pid = runtime.getPid();
out.println("Process ID is '" + pid);
অ্যাপাচি ২.০ লাইসেন্সবিহীন সম্পর্কে আশ্বিন জয়প্রকাশের উত্তর (+১) এর উপর ভিত্তি করে SIGAR
, আমি কীভাবে এটি বর্তমান প্রক্রিয়ার পিআইডি পেতে ব্যবহার করি:
import org.hyperic.sigar.Sigar;
Sigar sigar = new Sigar();
long pid = sigar.getPid();
sigar.close();
যদিও এটি সমস্ত প্ল্যাটফর্মগুলিতে কাজ করে না, এটি লিনাক্স, উইন্ডোজ, ওএস এক্স এবং বিভিন্ন ইউনিক্স প্ল্যাটফর্মগুলিতে এখানে তালিকাভুক্ত হিসাবে কাজ করে ।
আপনি চেষ্টা করতে পারেন getpid()
মধ্যে জুনিয়র-Posix ।
এটিতে একটি উইন্ডোজ POSIX মোড়ক রয়েছে যা getpid () কে libc অফ বলে।
আমি জানি এটি একটি পুরানো থ্রেড, তবে আমি পিআইডি পাওয়ার জন্য সেই API টি কল করতে চেয়েছিলাম (পাশাপাশি রানটাইমের সময় জাভা প্রক্রিয়াটির অন্যান্য হেরফের) জেডিকে 9: http: // ওপেনজেডকে প্রসেস ক্লাসে যুক্ত করা হচ্ছে । java.net/jeps/102
আমি এমন একটি সমাধান পেয়েছি যা কিছুটা প্রান্তের কেস হতে পারে এবং আমি উইন্ডোজ 10 এর চেয়ে অন্য ওএসে চেষ্টা করিনি, তবে আমি মনে করি এটি লক্ষ্য করার মতো।
আপনি যদি নিজেকে J2V8 এবং নোডেজের সাথে কাজ করে দেখেন তবে আপনি জাভা প্রক্রিয়াটির পিড ফিরিয়ে একটি সাধারণ জাভাস্ক্রিপ্ট ফাংশন পরিচালনা করতে পারেন।
এখানে একটি উদাহরণ:
public static void main(String[] args) {
NodeJS nodeJS = NodeJS.createNodeJS();
int pid = nodeJS.getRuntime().executeIntegerScript("process.pid;\n");
System.out.println(pid);
nodeJS.release();
}
এখানে আমার সমাধান:
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;
}
আমার যখন অনুরূপ প্রয়োজনীয়তা ছিল তখন এটিই আমি ব্যবহার করি। এটি জাভা প্রক্রিয়াটির পিআইডি সঠিকভাবে নির্ধারণ করে। আপনার জাভা কোডটি একটি পূর্বনির্ধারিত পোর্ট নম্বরে একটি সার্ভার তৈরি করতে দেয় এবং তারপরে পোর্টে পিআইডি শোনার জন্য ওএস কমান্ডগুলি কার্যকর করে। লিনাক্সের জন্য
netstat -tupln | grep portNumber
bash -c 'echo $PPID'
বা উপরের উত্তরগুলি কিনতে পারেন