I've been trying to find ways to obtain the Thread Dump from a Java Application on my Windows server running on jre 1.8.0_144.
Non of the monitoring utilities like jcmd jstack jconsole are available in either the bin or lib folders of the Java environment directory.
I have come across several applications online that claim to perform the same task but haven't found a reliable one yet.
Changing the JRE version, unfortunately, has been ruled out as an option
There is a way if you are running with tools.jar available, that is running from a JDK instead of a stock JRE. However given that you don't have the jcmd, jstack, jconsole tools available, this is unlikely.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
// You need to add tools.jar to the classpath to get this
import com.sun.tools.attach.VirtualMachine;
public class Main {
public static void main(String[] args) throws Exception {
// Here you will need to use JNI or JNA to get the current process' PID
// because the JRE version you are using doesn't have any other way.
long pid = getCurrentPid(); // you need to create this method
VirtualMachine vm = VirtualMachine.attach(""+pid);
Method m = vm.getClass().getMethod("remoteDataDump", Object[].class);
InputStream in = (InputStream) m.invoke(vm, new Object[] { new Object[0] } ); // awkward due to nested var-args
try (BufferedReader buffer = new BufferedReader(new InputStreamReader(in))) {
buffer.lines().forEach(System.out::println);
}
}
}
Related
Is there a way to check if a specific program is installed on Windows using Java?
I'm trying to develop a Java program that automatically creates zip archives by using the code line command from 7-Zip.
So, I would like to check in Java if on my windows OS '7-Zip' is already installed. No check for running apps or if OS is Windows or Linux. I want to get a bool (true/false) if '7-Zip' is installed on Windows.
The library Apache Commons has a class called SystemUtils - full documentation is available at https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SystemUtils.html.
In this library you have the following static boolean properties at your disposal:
SystemUtils.IS_OS_LINUX
SystemUtils.IS_OS_WINDOWS
The unix-like solution would be to simply try to run the program with --version flag (on windows probably the /? or - like in the 7zip case - without any at all) and check whether it fails, or what the return code will be.
Something like:
public boolean is7zipInstalled() {
try {
Process process = Runtime.getRuntime().exec("7zip.exe");
int code = process.waitFor();
return code == 0;
} catch (Exception e) {
return false;
}
}
I assume that you're talking about Windows. As Java is intended to be a platform-independent language and the way how to determine it differs per platform, there's no standard Java API to check that. You can however do it with help of JNI calls on a DLL which crawls the Windows registry. You can then just check if the registry key associated with the software is present in the registry. There's a 3rd party Java API with which you can crawl the Windows registry: jRegistryKey.
Here's an SSCCE with help of jRegistryKey:
package com.stackoverflow.q2439984;
import java.io.File;
import java.util.Iterator;
import ca.beq.util.win32.registry.RegistryKey;
import ca.beq.util.win32.registry.RootKey;
public class Test {
public static void main(String... args) throws Exception {
RegistryKey.initialize(Test.class.getResource("jRegistryKey.dll").getFile());
RegistryKey key = new RegistryKey(RootKey.HKLM, "Software\\Mozilla");
for (Iterator<RegistryKey> subkeys = key.subkeys(); subkeys.hasNext();) {
RegistryKey subkey = subkeys.next();
System.out.println(subkey.getName()); // You need to check here if there's anything which matches "Mozilla FireFox".
}
}
}
If you however intend to have a platformindependent application, then you'll also have to take into account the Linux/UNIX/Mac/Solaris/etc. (in other words: anywhere where Java is able to run) ways to detect whether FF is installed. Else you'll have to distribute it as a Windows-only application and do a System#exit() along with a warning whenever System.getProperty("os.name") is not Windows.
Sorry, I don't know how to detect in other platforms whether FF is installed or not, so don't expect an answer from me for that ;)
NOTE: Please run the exact code below; no adaptations of it, in particular, do not use File, as this bug is tied to the new java.nio.file API
OK, this is not really a "question which is in need of an answer" but rather a call for witnesses...
Scenario:
have a directory on your OS, whatever it is, which you know you have privileges to access -- in Unix parlance, you have at least read access to it (which means you can list the entries in it); in the code below, it is supposed that the path represented by System.getProperty("java.io.tmpdir") fits the bill;
have a Oracle JDK, or OpenJDK, 7+ installed; so that you have java.nio.file at your disposal.
Now, what the code below does is pretty simple: it tries to open a new InputStream on this directory using Files.newInputStream(). Code (also available here; added comments mine):
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public final class Main
{
public static void main(final String... args)
throws IOException
{
final Path path = Paths.get(System.getProperty("java.io.tmpdir"));
try (
final InputStream in = Files.newInputStream(path); // FAIL_OPEN
) {
final byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buf)) != -1) // FAIL_READ
System.out.printf("%d bytes read\n", bytesRead);
}
}
}
OK, now when you run that code, this is what happens for the following JRE/OS combinations:
Linux x86_64, Oracle JDK 1.8.0_25: IOException (is a directory) at FAIL_READ;
Linux x86_64, Oracle JDK 1.7.0_72: IOException (is a directory) at FAIL_READ;
Mac OS X x86_64, Oracle JDK 1.8.0_25: IOException (is a directory) at FAIL_READ;
Windows 7, Oracle JDK 1.8.0_25: AccessDeniedException at FAIL_OPEN (!!).
Honestly, I don't know what to do with that piece of code. As I said in the introduction, I am looking for witnesses here. I will certainly open a bug to OpenJDK about this, it seems pretty serious. I also mailed the nio-dev mailing list about this problem.
Well, as to a question I'd have one: what about a IsDirectoryException in the JDK (inheriting FileSystemException)? I have actually defined it in one of my projects to account for such a problem. I am not sure why this problem was not considered by the "Java guys"...
My observations (sorry, no other systems around here atm, later I might add ARM):
JDK 1.8.0_25, Linux x86_64: java.io.IOException: Is a directory at // FAIL_READ.
I agree that this behavior is unexpected, it should not be possible to create an InputStream from a directory in the first place. I suggest you file this as a bug. Even if Files.newInputStream doesn't state it explicitly, the behavior is inconsistent with the rest of the API.
I want to monitor portable devices attached to my linux OS using jmtp.jar. Below is the code that i am using to do the same. It's working fine in Windows but when i run this code it gives me "Not supported OS exception". do jmtp.jar support linux OS? If not then any alternative solution for linux OS?
Code that i used
import java.io.*;
import java.math.BigInteger;
import jmtp.PortableDevice;
import jmtp.PortableDeviceManager;
import jmtp.PortableDeviceObject;
import jmtp.PortableDeviceStorageObject;
public class Jmtp {
public static void main(String[] args) {
PortableDeviceManager manager = new PortableDeviceManager();
PortableDevice device = manager.getDevices()[0];
device.open();
System.out.println(device.getModel());
System.out.println("---------------");
// Iterate over deviceObjects
for (PortableDeviceObject object : device.getRootObjects()) {
// If the object is a storage object
if (object instanceof PortableDeviceStorageObject) {
PortableDeviceStorageObject storage = (PortableDeviceStorageObject) object;
for (PortableDeviceObject o2 : storage.getChildObjects()) {
System.out.println(o2.getOriginalFileName());
}
}
}
manager.getDevices()[0].close();
}
}
Exception that i got :
Exception in thread "main" java.lang.RuntimeException: not supported os
at jmtp.PortableDeviceManager.<init>(PortableDeviceManager.java:37)
at find_usb.Jmtp.main(Jmtp.java:24)
Google states:
A project aimed at allowing java programs to access MTP compabitble portable
media players. The main target is currently windows, by wrapping the WPD api,
but design decisions have been made to support both linux and mac os x in
the future with the same API. For more information, please see the wiki.
I'm new to Sigar. I would like to run a simple test to know how I can monitor my system.
I added sigar-1.6.4 and log4j as external libraries, but when I go to run it, I face this error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.hyperic.sigar.Sigar.getCpuInfoList()[Lorg/hyperic/sigar/CpuInfo;
at org.hyperic.sigar.Sigar.getCpuInfoList(Native Method)
Here is my code:
import java.util.Map;
import org.hyperic.sigar.CpuInfo;
import org.hyperic.sigar.FileSystem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
Sigar sigar = new Sigar();
CpuInfo[] cpuinfo = null;
try {
cpuinfo = sigar.getCpuInfoList();
} catch (SigarException se) {
se.printStackTrace();
}
System.out.println("---------------------");
System.out.println("Sigar found " + cpuinfo.length + " CPU(s)!");
System.out.println("---------------------");
}
}
Any help would be appreciated.
I understood the problem!
I have to use the following JVM Argument:
-Djava.library.path="./lib"
in Run Configuration, Arguments tab, VM arguments in eclipse, while the contnet of sigar-bin/lib is in lib folder.
Sigar works via JNI. As such, the appropriate .so or .dll file needs to be in the path specified by the java.library.path property.
Check your sigar distribution - the zip file, I mean. Unzip it and copy the contents of
sigar-bin\lib to a location accessible by your Path, PATH, and LD_LIBRARY_PATH environment variables. Usually, only one file needs to be accessible per platform.
That should do the trick, if it doesn't, let me know and I'll see what I can do.
I am a student in IT and i'm still learning java and android developement.
i'm testing with some udp traffic between a desktop app and a android app.
but every time I try to run the android app it gives this error message :
Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/ref/FinalReference
this is the code of the UDP client
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import android.app.Activity;
import android.util.Log;
public class Client extends Activity {
public static void main(String[] args) throws IOException {
try {
int bufSize = 4096;
int port = 12345;
DatagramSocket sock = new DatagramSocket(port);
sock.setReceiveBufferSize(bufSize);
byte[] buffer = new byte[bufSize];
while (true) {
DatagramPacket p = new DatagramPacket(buffer, bufSize);
sock.receive(p);
Log.d("Client", "Received: " + new String(p.getData()));
}
}finally{}
}
}
the code may contain some parts that may not work, but it gives no errors.
I just want to know why the VM won't start.
grtz
Looks like your Java SDK wasn't installed correctly.
Try and see if java is in your system PATH. You can try javac -version command on your terminal. If that produces the same error, then you need to add it to your path.
Also, this guy seems to have had the same problem as yours, check that link:
I found the solution to my error.
I used the android project like a java app, with a main function. this gave the problem of no being able to deploy the vm.
the code hade to be in the oncreate function of the activity instead of in a main function.
thanks for the help.
grtz
Try these steps in order on UBUNTU 12.04LTS:
chmod 755 eclipse.desktop
Check javac -version
Find the correct path for javac
Find correct path for JDK
Add using vi the following lines in the top of file /opt/eclipse/eclipse.ini :
-vm
/usr/bin /*if javac is in /usr/bin */
/usr/share/jdk7/usr/java/jdk1.7.0_25/bin /*if this is the path for JDK */