Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Bizarre InterruptedException thrown if threads are interrupted

Reply
Thread Tools

Bizarre InterruptedException thrown if threads are interrupted

 
 
Daniel
Guest
Posts: n/a
 
      12-03-2003
Hi,

I've just run into some really strange behavior with the Sun JVM
(using Java 1.4.2 on Windows). If I have a few threads performing
certain security or JCE operations simultaneously (e.g. generating key
pairs), and if one or more of those threads' state is "interrupted",
then I receive an InterruptedException out of the blue! I'm not sure
if this problem is limited to the JCA/JCE or not.. it doesn't seem to
be cryptography-related to me. The following short program illustrates
the problem:

import java.security.KeyPairGenerator;

public class GenerateKeyTest extends Thread
{
public void run()
{
try
{
interrupt(); // Comment out this line and it works OK
System.out.println("About to generate keys");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
kpg.generateKeyPair();
System.out.println("Keys successfully generated");
}
catch (Exception e)
{
e.printStackTrace();
}
}

public static void main(String[] args)
{
for (int i = 0; i < 5; i++)
new GenerateKeyTest().start();
}
}


It simply generates 5 key pairs "simultaneously" in 5 different
threads. It works fine if the threads are not interrupted, but if you
call interrupt() before doing the operation (as in the above program),
the following exception stack trace results:


java.lang.InterruptedException
at COM.rsa.jsafe.SunJSSE_df.j(DashoA6275)
at COM.rsa.jsafe.SunJSSE_df.c(DashoA6275)
at com.sun.net.ssl.internal.ssl.JS_KeyPairGenerator.g enerateKeyPair(DashoA6275)
at java.security.KeyPairGenerator$Delegate.generateKe yPair(KeyPairGenerator.java:475)
at GenerateKeyTest.run(GenerateKeyTest.java:13)


My two main questions are:

1) Has anyone run into this before, or does anyone have any idea what
can possibly be going on here?

2) Can such behavior even "legally" happen in Java?
InterruptedException is a checked exception (i.e. not a
RuntimeException or an Error) so how can it possibly be thrown and
propogate all the way up to my run() method? If any of the methods in
the stack trace threw an InterruptedException, they would have to
declare it in a "throws" clause, and I would be forced to catch it.

If no one has any further insights, I'll file a bug report. Thanks in
advance for any help,

Daniel

P.S. This happens with other JCE calls as well (e.g. Getting a key
factory while performing asymmetric decryption) and possibly in other
scenarios too. It also occurs when using the Bouncy Castle provider
instead of the SunJCE provider.
 
Reply With Quote
 
 
 
 
xarax
Guest
Posts: n/a
 
      12-03-2003
Sigh...

"Daniel" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Hi,
>
> I've just run into some really strange behavior with the Sun JVM
> (using Java 1.4.2 on Windows). If I have a few threads performing
> certain security or JCE operations simultaneously (e.g. generating key
> pairs), and if one or more of those threads' state is "interrupted",
> then I receive an InterruptedException out of the blue! I'm not sure
> if this problem is limited to the JCA/JCE or not.. it doesn't seem to
> be cryptography-related to me. The following short program illustrates
> the problem:
>
> import java.security.KeyPairGenerator;
>
> public class GenerateKeyTest extends Thread
> {
> public void run()
> {
> try
> {
> interrupt(); // Comment out this line and it works OK
> System.out.println("About to generate keys");
> KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
> kpg.initialize(1024);
> kpg.generateKeyPair();
> System.out.println("Keys successfully generated");
> }
> catch (Exception e)
> {
> e.printStackTrace();
> }
> }
>
> public static void main(String[] args)
> {
> for (int i = 0; i < 5; i++)
> new GenerateKeyTest().start();
> }
> }
>
>
> It simply generates 5 key pairs "simultaneously" in 5 different
> threads. It works fine if the threads are not interrupted, but if you
> call interrupt() before doing the operation (as in the above program),
> the following exception stack trace results:
>
>
> java.lang.InterruptedException
> at COM.rsa.jsafe.SunJSSE_df.j(DashoA6275)
> at COM.rsa.jsafe.SunJSSE_df.c(DashoA6275)
> at

com.sun.net.ssl.internal.ssl.JS_KeyPairGenerator.g enerateKeyPair(DashoA6275)
> at

java.security.KeyPairGenerator$Delegate.generateKe yPair(KeyPairGenerator.java:47
5)
> at GenerateKeyTest.run(GenerateKeyTest.java:13)
>
>
> My two main questions are:
>
> 1) Has anyone run into this before, or does anyone have any idea what
> can possibly be going on here?


Yes, you called interrupt() to interrupt the current Thread.

> 2) Can such behavior even "legally" happen in Java?
> InterruptedException is a checked exception (i.e. not a
> RuntimeException or an Error) so how can it possibly be thrown and
> propogate all the way up to my run() method? If any of the methods in
> the stack trace threw an InterruptedException, they would have to
> declare it in a "throws" clause, and I would be forced to catch it.


The run() method doesn't have to declare checked exceptions,
which is why you can encounter such exceptions anywhere in
the callstack of the thread.

> If no one has any further insights, I'll file a bug report. Thanks in
> advance for any help,


File the bug report to yourself, because it's your code
that's broken.

> Daniel
>
> P.S. This happens with other JCE calls as well (e.g. Getting a key
> factory while performing asymmetric decryption) and possibly in other
> scenarios too. It also occurs when using the Bouncy Castle provider
> instead of the SunJCE provider.


The pending interrupt that you created by calling interrupt()
will be thrown at the next opportunity (usually when calling
an I/O service).


--
----------------------------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS!


 
Reply With Quote
 
 
 
 
Chris Uppal
Guest
Posts: n/a
 
      12-03-2003
Daniel wrote:

> java.lang.InterruptedException
> at COM.rsa.jsafe.SunJSSE_df.j(DashoA6275)
> at COM.rsa.jsafe.SunJSSE_df.c(DashoA6275)
> at ....


> 1) Has anyone run into this before, or does anyone have any idea what
> can possibly be going on here?


You've set the interupted flag in the thread before you start processing (in
your example code, I don't know how that flag gets set in your real code).
That means that the next time the thread does one of a class of "long lived"
operations it will be interrupted. See the javadoc for Thread.interrupt() for
a list of the operations that check the flag. My guess is that the crypto
stuff is either doing some IO (reading property files or keyrings or something)
or possible doing a wait() while another thread collects entropy, and so the
system is checking the interrupted flag and throwing the exception.


> 2) Can such behavior even "legally" happen in Java?
> InterruptedException is a checked exception (i.e. not a
> RuntimeException or an Error) so how can it possibly be thrown and
> propogate all the way up to my run() method?


Well, just because the Java compiler would reject code that does this, doesn't
mean that it can't happen. The Java compiler is *not* the same as the JVM and
the compiler's rules are irrelevant at runtime. As it happens the JVM has no
concept of checked exception declarations, so there's nothing to stop code
circumenting the Java *language's* rules. Exactly how it's doing it, I don't
know, but there are many possibilities, for instance it could be being thrown
from JNI.

Just guesses, of course....

-- chris


 
Reply With Quote
 
Daniel
Guest
Posts: n/a
 
      12-05-2003
"xarax" <(E-Mail Removed)> wrote in message news:<bvlzb.26612$(E-Mail Removed) link.net>...
> Sigh...


Sigh? What is that for..?

> > 1) Has anyone run into this before, or does anyone have any idea what
> > can possibly be going on here?

>
> Yes, you called interrupt() to interrupt the current Thread.
>


I am unaware of any documentation stating the dangers of leaving a
thread in the interrupted state while calling other API methods. In
fact, the documentation that talks about situations where methods may
catch an unexpected InterruptedException recommends code similar to
the following:

if (Thread.interrupted()) // ignore interrupts while waiting
wasInterrupted = true;
....
if (wasInterrupted) // reassert interrupt status on exit
current.interrupt();

Code such as this is on both Sun's site, as well as Doug Lea's.

> > 2) Can such behavior even "legally" happen in Java?
> > InterruptedException is a checked exception (i.e. not a
> > RuntimeException or an Error) so how can it possibly be thrown and
> > propogate all the way up to my run() method? If any of the methods in
> > the stack trace threw an InterruptedException, they would have to
> > declare it in a "throws" clause, and I would be forced to catch it.

>
> The run() method doesn't have to declare checked exceptions,
> which is why you can encounter such exceptions anywhere in
> the callstack of the thread.
>


Your argument here is flawed on 2 levels. Firstly, your statement that
the run method doesn't have to declare checked exceptions is
incorrect. Try compiling code for a thread with the following run
method:

public void run()
{
throw new Exception();
}

Secondly, even if your incorrect statement happened to be true, it
does nothing to prove your point. The exception is *not* thrown from
the run() method, but somewhere in the JCA/JCE classes, and these
obviously have to declare any checked exceptions in a throws clause.
The fact that none of the KeyPairGenerator methods are declared to
throw InterruptedException implies that I should not receive it when
calling these methods.

> > If no one has any further insights, I'll file a bug report. Thanks in
> > advance for any help,

>
> File the bug report to yourself, because it's your code
> that's broken.
>


How about being a little more polite, especially when it's you that
has your facts upside down. I didn't come out here accusing anyone of
anything, I'm just trying to understand the situation better.

> The pending interrupt that you created by calling interrupt()
> will be thrown at the next opportunity (usually when calling
> an I/O service).


No, interrupt() should not affect any normal I/O operations. It will
only affect nio operations, and I'm sure that none of these are being
called (since I have verified this behavior on a 1.1 JVM as well). The
other non-I/O Java operations that an interrupt() will affect are
wait, join, and sleep. All 3 of these are declared to throw an
InterruptedException. Therefore if the exception wasn't being caught
and dealt with (or ignored) at any of the methods between the
exception's source and my run method, then it would have to be
declared in a throws clause in one of the KeyPairGenerator methods
(which it isn't).

Daniel
 
Reply With Quote
 
Daniel
Guest
Posts: n/a
 
      12-05-2003
Hi Chris,

"Chris Uppal" <(E-Mail Removed)-THIS.org> wrote in message news:<3fcdee5b$0$92729$(E-Mail Removed) t>...

> You've set the interupted flag in the thread before you start processing (in
> your example code, I don't know how that flag gets set in your real code).


This is not really a "real-app situation", but something I came across
when doing some testing for a multi-threaded server type app. In the
particular test program, it was not really necessary to "synchronize"
interrupts() with sleeps() and other methods, so there were certain
times where a thread could be in the interrupted state just before
doing a lot of crypto code. In the real app everything is nicely
synchronized, so I don't actually experience this problem. But, as I
mentioned in my reply to Jeffrey, I'm not aware that's it considered
wrong for a thread in the interrupted state to call a Java API method.
Is it? I'd be interested to find any docs on this...

> That means that the next time the thread does one of a class of "long lived"
> operations it will be interrupted. See the javadoc for Thread.interrupt() for
> a list of the operations that check the flag. My guess is that the crypto
> stuff is either doing some IO (reading property files or keyrings or something)
> or possible doing a wait() while another thread collects entropy, and so the
> system is checking the interrupted flag and throwing the exception.
>


I'm aware of all these situations where an InterruptedException will
be thrown, but none of them seem feasible to me for the following
reason: these methods are all declared to throw an
InterruptedException. This would *have* to be caught and dealt with,
ignored, or reasserted (by calling thread.interrupt()) at the
exception's source, or they would have to be declared in a throws
clause. The fact that none of the KeyPairGenerator methods throw an
InterruptedException means that if an InterruptedException was thrown
for any of these reasons, then it should have been dealt with,
ignored, or reasserted somewhere along the way before coming back to
my run() method.

>
> > 2) Can such behavior even "legally" happen in Java?
> > InterruptedException is a checked exception (i.e. not a
> > RuntimeException or an Error) so how can it possibly be thrown and
> > propogate all the way up to my run() method?

>
> Well, just because the Java compiler would reject code that does this, doesn't
> mean that it can't happen. The Java compiler is *not* the same as the JVM and
> the compiler's rules are irrelevant at runtime. As it happens the JVM has no
> concept of checked exception declarations, so there's nothing to stop code
> circumenting the Java *language's* rules.


Right. Perhaps I was a little vague here.. I know the JVM can do
whatever it wants. My question should have been something along the
lines of "you shouldn't be able to write and compile Java code to do
this, under normal circumstances (i.e. not hacking class files,
etc.)?".

> Exactly how it's doing it, I don't
> know, but there are many possibilities, for instance it could be being thrown
> from JNI.


Yeah I thought about that.. it's a little odd though, since I've also
received this exception with a stack trace originating in the Bouncy
Castle BigInteger class... which is definitely 100% Java. Other than
JNI, I have no other guesses about where it could come from. (I'm not
really sure about JNI either.. one would hope that native methods obey
Java's general exception "rules").

>
> Just guesses, of course....
>
> -- chris


Thanks for your input/guesses Chris I still feel this is a bug
since a checked exception shouldn't come from nowhere.. I guess it
just depends on one's point of view.

Regards,
Daniel
 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      12-05-2003
Daniel wrote:

> Yeah I thought about that.. it's a little odd though, since I've also
> received this exception with a stack trace originating in the Bouncy
> Castle BigInteger class... which is definitely 100% Java.


Can you find a (statistically) reproducible case that doesn't use the Java
crypto stuff (which has the disadvantage of being obfuscated) ?

I looked at this a little more, and now I'm as confused as you The stack
trace you posted doesn't make sense to me at all; the methods in question
aren't doing any IO or anything like it (as far as I can tell through the fog
of obfuscation) and it does indeed look as if the VM is triggering the
exception at a random point in the code.

I tried your example on my system (Sun JDK 1.4.2 / Win XP) and I don't get the
same results as you -- it consistently (more or less) produces:

java.lang.InterruptedException
at
java.security.KeyPairGenerator.getInstance(KeyPair Generator.java:146)
at Test.run(Test.java:12)

However, KeyPairGenerator.getInstance() isn't doing *anything* that could
possibly cause that exception, so I can only presume that the exception is
happening elsewhere (perhaps in a AccessController.doPrivileged() block) and
the reported stack trace is just not properly representing that.

I did find that if I generated a key pair before entering the loop that starts
the threads, then everything works OK, so it must be something to do with the
initialisation phase that's doing something that trips the interrupt.

So, my best guess is as follows:

The initialisation phase of the crypto stuff (by some unguessed-at magic) uses
facilities that trigger the InterruptedException in a context where
Java-the-language wouldn't allow it. Possibly because of the use of that
magic, and quite probably compounded by the use of an
AccessController.doPrivileged() block, the VM is unable to create an accurate
stack trace for the InterruptedException. The exception percolates back out to
your user-level code because nothing traps it (since the checked exception is
not declared, they don't realise they "have" to) where you trap it. When you
print out the stack trace, the results are misleading, suggesting that the
exception was thrown from code that had already executed with no problems.

Ugh!

-- chris



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: InterruptedException handling Alessio Stalla Java 1 09-06-2009 02:47 AM
In Mutex.aquire why do we need to throw InterruptedException puzzlecracker Java 3 05-12-2008 03:49 PM
A bug of JMF(when JMF is playing video, InterruptedException occurs after the "refresh" button of IE is clicked)? taowang.gml@gmail.com Java 1 07-19-2006 11:21 PM
InterruptedException - what to do with it ? Ben_ Java 2 01-11-2006 08:42 AM
InterruptedException and I/O? Russell Gold Java 3 02-13-2004 02:43 PM



Advertisments