Win a copy of Beginning Java 17 Fundamentals: Object-Oriented Programming in Java 17 this week in the Java in General forum!

Saul Tocsin

Greenhorn
+ Follow
since Feb 25, 2012
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Saul Tocsin

Hi,

I am trying to read a volume via Java. I mean, in Windows terms, something like obtaining a "volume handle" so that I can read the volume from front to back.

The pertinent code looks like this:



Note also that I have added to the java.policy file these lines:



When I run the program I get the following:

Exception in thread "main" java.io.FileNotFoundException: \\.\C: (Access is denied)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)

However, when I run the Windows command shell "as administrator," it works.

Does anyone know how I might get this to work without having to run as administrator?

Thanks.

-Saul

9 years ago
Follow up question for you, Martin:

In using this form



do you then follow it with a call to ThreadInfo.getStackTrace() ?

Put otherwise, where does the information you displayed come from, e.g.,

"Thread-6" Id=28 BLOCKED on java.lang.Object@1fc7b3a owned by "Thread-5" Id=27
at xxx.Tests$1Deadlock.run(Tests.java:530)
- blocked on java.lang.Object@1fc7b3a
- locked java.lang.Object@fe2509
at java.lang.Thread.run(Unknown Source)

Thanks.

-Saul

Ah, screw-up (misinterpretation) on my part.

Thanks again, Martin.

-Saul

On the other hand: unless JVM is stopped for the duration of obtaining this info (which I doubt), it seems you cannot get an internally consistent snapshot of all threads' state.



Hmm...are you saying that internal consistency of threads' states not possible via dumpAllThreads?

Do you still think we have consistency via the form of getThreadInfo that you recommended?

-Saul
Martin,

That is very good news - thank you!

I will look into it more closely this afternoon.

-Saul
Hi Mohamed,

Thank you for the reply.

Can you say more concerning "....the JVMTI Agent (.dll/so) would not impact the function of the java application it is monitoring"?

My immediate concern is the state of monitored thread when the JVM calls back into the agent (JVMTI client). Specifically, if the monitored thread continues to run - and so change state - then information gathered about that thread is incoherent, and therefore useless.

Other concerns are:

a. is there a call I can make from my agent into the JVM that will allow me to suspend a thread's execution so that I can get a coherent picture of its state?
b. if the JVM makes a call back to a method in my agent, can that method safely call into the JVM?

Thanks again.

-Saul
Hi Martin,

Thanks for the reply.

I am using not the variant of getThreadInfo that you describe. Rather, I am using

I had looked at the variant you recommend, but wasn't sure if it accomplishes what I want. If I understand the API docs correctly, using

does not give me information about what the thread is waiting on (see ThreadInfo.getLockInfo()). Rather, it shows me monitors and ownable synchronizers that are "currently locked by the thread." My goal is to try to figure exactly what a waiting thread is waiting on.

This whole issure arose as I executed this code:



I get NPEs in these calls if the target thread (represented by the ThreadInfo variable ti) has ended. So it seemed to me that the array of ThreadInfo objects returned by the call to getThreadInfo did NOT, as I had hoped, contain all of the state needed to resolve the calls inside the for loop. That is, those calls might require interrogating the thread itself. Such interrogation against a dead thread leads to the NPE.

This behavior, which can only occur at thread termination, got me thinking more generally about the relationship between the ThreadInfo object and the actual Thread instance. And it was here that the more troubling concern arose, namely that I couldn't be sure that the ThreadInfo was consistent with the current state of the thread, i.e., its state after the getThreadInfo() call completes. Specifically, if ThreadInfo.getThreadState() shows me Thread.State of BLOCKED, will a subsequent call to ThreadInfo.getLockInfo() return the LockInfo object that the thread was BLOCKED on at the time of the getThreadInfo() call; or, because the the thread is now RUNNABLE, will it return null?

Thank you for considering this matter. I find this issue troubling and would like to get to the bottom of it without having to resort to a JVMTI approach.

-Saul
Hi All,

I'm not sure where to post this because I see no forum expressly devoted to debugging. So I'll post it here, alongside my last post because they are related.

Not convinced that the JMX-based approach I outlined
in my other post is sufficient, I began to look at the JVM Tool Interface.

Fundamental questions about JVMTI: when the JVM calls back into the client ("agent") DLL or .so, are the threads I might be interested in monitoring suspended? And by "suspended" I don't mean in the Thread.State sense. I mean only, will they change while I am trying to inquire about why they are BLOCKED (for example)?

Related question: if I call into JVMTI's getThreadState which, I think, is NOT a call back function, will the JVM's threads continue to run which the JVM processes this call?

Thanks.

-Saul
Hi All,

In putting together a "state sampling" monitor (periodically wake up and inquire about the state of application threads known to the JVM), I came upon something troubling, and perhaps unavoidable.

The issue is quite simple:

a. call ThreadMXBean.getThreadInfo to populate a ThreadInfo[] for threads I find interesting (my application's threads).
b. iterate over this array calling a few of the ThreadInfo methods (e.g., getThreadId, getThreadName, getThreadState).
c. find a thread in BLOCKED state (Thread.State)
d. try to inquire further about the blocked thread, e.g., call getLockInfo

But by the time (d) fires, the thread is no longer in BLOCKED state and the call to getLockInfo returns null.

I think I need some kind of "snapshot" of the entirety of thread state. I mean something that will return a picture of the thread at a given point in time; and NOT require me to call methods that query the live thread.

Questions:

1. of what use is ThreadInfo in a situation like this?
2. is there some way of obtaining the "snapshot" I described?

Thanks, All.

-Saul

All, turns out this was a dumb mistake on my part.

Thread ID 1 terminated and that's why it's no longer visible. I incorrectly thought that it was blocking when, in fact, it started up a listener as a distinct thread and then terminated.

-P
Hi All,

I wasn't quite sure in which forum to post something related to JMX. A search revealed a few JMX posts in this forum....

I have a relatively simple Java class that I start on Node2 as follows:

java -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=Node2 -jar amqpConsumer.jar

When this class starts, it obtains and displays its thread ID. The threadID value displayed is "1". The thread then blocks, waiting for messages to be sent by an AMQP producer.

While the thread on Node2 is waiting, I fire up on Node1 a JMX client that I copied from a very helpful example I found on the Web. The core of this JMX client code looks like this:



Pretty much everything seems to work: the client on Node1 connects to the agent on Node2 and displays threadID, thread name, and thread state for each thread:

45:JMX server connection timeout 45 / TIMED_WAITING
44:RMI TCP Connection(41)-71.100.15.51 / RUNNABLE
43:RMI TCP Connection(40)-71.100.15.51 / RUNNABLE
18:RMI Scheduler(0) / TIMED_WAITING
16: DestroyJavaVM / RUNNABLE
15:AMQP Connection 71.100.100.90:5672 / RUNNABLE
14:SimpleAsyncTaskExecutor-1 / TIMED_WAITING
13:AMQP Connection 71.100.100.90:5672 / RUNNABLE
12:RMI TCP Accept-0 / RUNNABLE
11:RMI TCP Accept-9999 / RUNNABLE
10:RMI TCP Accept-0 / RUNNABLE
5:Attach Listener / RUNNABLE
4:Signal Dispatcher / RUNNABLE
3:Finalizer / WAITING
2:Reference Handler / WAITING


But notice that there is no threadID 1.

Perhaps incorrectly, I have assumed that in talking to the JVM's JMX agent, I should be able to enumerate all of the threads known to that JVM. So I am presently baffled as to why I don't see my thread returned by

Is there some way in which I must instrument my class so that it becomes visible to the JVM's JMX agent?

Thank you for your help.

-Paul

Henry Wong wrote:
Not sure what you mean by "the kernel can always cancel one of its tasks". All the issues mentioned, like hung on I/O also applies at the OS layer, and the same techniques also needs to be used. Or do you mean something specific that hasn't been mentioned yet?



Hi Henry,

Simply that the kernel can:

a. detect that a task is not dispatchable, i.e., not runnable because it's "blocked" waiting for something
b. impose a policy that says "cancel a task if it is blocked for N minutes"; or notify the operator and let him cancel the task from without
c. remove the canceled task's entry from the dispatch queue
d. reclaim resources associated with the canceled task

I don't mean that the kernel can resolve the initial cause of the hang, e.g., a malfunctioning device.

The JVM architecture seems deficient re (b) and (d). There seems to be no way to cancel such a hung task, etc. Please note that this post is not meant as an "indictment" of the JVM architecture! I only bring it up because I am struck by what seems to me to be a liability. I agree that it's a difficult problem.

I am just trying to find a graceful and not too labored solution to it.

Thanks again.

-Saul

-Saul
Hi Henry,

Thank you for the welcome, and for the reply.

The difficulty here is that I don't have much control over the I/O layer. Imagine that the thread in question is in the "business" layer and that it calls into the lower DAO/Persistence layer via some kind of CRUD procedure call connector. So I don't think that my Java thread is in a position to create and benefit from an InterruptibleChannel in presenting such a call to the layer below (please correct me if you think otherwise).

More generally, I meant the "blocked in I/O" merely as an example. The general problem is "thread hung;" don't know why, it's just not responding.

Thanks.

-Saul
Hi All,

I've spent time browsing this forum, but this is my first post.

I am trying to think through a scenario that sees a long-running thread, started by an Executor, get "permanently" hung. We don't know why this happens. Maybe it's blocked in I/O. Consider it a "given." Supposing that one can detect that the thread is hung, how can one truly cancel it?

I am familiar with the reasons behind the deprecation of Thread.stop(). The replacement approach seems to rely on the target thread (the one you want to stop) being active, i.e., the target thread periodically checks a variable that is shared with another thread and simply exits its run method. But this doesn't work for a hung thread. Moreover, it is simply not the case that a thread is always able to see a Thread.interrupt() presented by another thread.

To wax philosphic for a moment, the JVM has in some sense replaced the real OS. That is, it functions as a mediating and insulating layer between our Java progams and the kernel. But the kernel can always cancel one of its tasks. I have the sense that the JVM is deficient in this regard and that there really is no graceful solution to certain types of thread states.

So I am interested in hearing folks' thoughts about ways of handling this problem. I looked into creating the long-running task as a Future in the hope that its cancel() method might be of some help. But even here I sense some uncertainty, e.g., the docs say: "Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason." (emphasis mine).

Thanks.

-Saul