Java thread dump: BLOCKED thread without "waiting to lock ..." - java

I'm having difficulties in understanding the thread dump I got from jstack for a Spring MVC web application running on Tomcat 6 (java 1.6.0_22, Linux).
I see blocking threads (that cause other threads to wait) which are blocked themselves, however the thread dump doesn't tell me why or for which monitor they are waiting.
Example:
"TP-Processor75" daemon prio=10 tid=0x00007f3e88448800 nid=0x56f5 waiting for monitor entry [0x00000000472bc000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.Class.initAnnotationsIfNecessary(Class.java:3067)
- locked <0x00007f3e9a0b3830> (a java.lang.Class for org.catapultframework.resource.ResourceObject)
at java.lang.Class.getAnnotation(Class.java:3029)
...
I.e. I am missing the "waiting to lock ..." line in the stack trace. Apparently the thread locks a Class object, but I don't see why the thread itself is blocked.
The thread-dump does not contain any hints for deadlocks.
What can I do to identify the locking monitor?
Thanks,
Oliver

Apparently the situation where we observed these kinds of blocked threads were related to heavy memory consumption and therefore massive garbage collection.
This question Java blocking issue: Why would JVM block threads in many different classes/methods? describes a similar situation, so I believe these threads were simply blocked by the garbage collector.
(Anyway, after solving the memory issue this problem with the blocking threads was gone.)

Check if the finalizer thread is blocked or waiting.
During a GC sweep, the GC will "stop the world" to perform its cleanup. The definition of "world" depends on the garbage collector being used and context. It may be a small cluster of threads or all of them. Before officially collecting garbage, GC will invoke the object's finalize().
If you are in the undesirable situation where you are implementing finalizer methods, the finalization code may be blocking it from finishing and the 'world' stays stopped.
This is most obvious when seeing lots of threads being permanently-blocked by some unknown magic force: Look up the code where the blocking occurs and it will make no sense; there is no blocking code to be found anywhere near it and the dumps will not divulge what monitor it is waiting on because there isn't one. The GC has paused the threads.

I had a similar problem just now using an Applet in Google Chrome.
In short:
The BLOCKED threads can be blocked when the VM needs to load a class.
When the process of loading the class itself is blocked by something a freeze for the whole app can occur.
In Detail:
I had the following scenario:
I am using an Applet in Chrome with codebase = folder to single class-files (no jar)
The Website passes focus-events to the applet using LiveConnect
The incoming JS-calls are using an Executor with new Runnable() ... to detach the calls in order to reduce the wait times and thus hangs in JS.
That's where the problem occured!
Explanation:
The new Runnable() is an annonymous inner class which was not loaded before the JS call happened.
The JS call therefore triggers the class load.
But now the class loader is blocked because it needs to talk to the browser (i am guessing) via the same queue or mechanism that is processing the incoming JS call.
Here is the blocked thread that is trying to load the class:
"Thread-20" daemon prio=4 tid=0x052e8400 nid=0x4608 in Object.wait() [0x0975d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at sun.plugin2.message.Queue.waitForMessage(Unknown Source)
- locked <0x29fbc5d8> (a sun.plugin2.message.Queue)
at sun.plugin2.message.Pipe$2.run(Unknown Source)
at com.sun.deploy.util.Waiter$1.wait(Unknown Source)
at com.sun.deploy.util.Waiter.runAndWait(Unknown Source)
at sun.plugin2.message.Pipe.receive(Unknown Source)
at sun.plugin2.main.client.MessagePassingExecutionContext.doCookieOp(Unknown Source)
at sun.plugin2.main.client.MessagePassingExecutionContext.getCookie(Unknown Source)
at sun.plugin2.main.client.PluginCookieSelector.getCookieFromBrowser(Unknown Source)
at com.sun.deploy.net.cookie.DeployCookieSelector.getCookieInfo(Unknown Source)
at com.sun.deploy.net.cookie.DeployCookieSelector.get(Unknown Source)
- locked <0x298da868> (a sun.plugin2.main.client.PluginCookieSelector)
at sun.net.www.protocol.http.HttpURLConnection.setCookieHeader(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
- locked <0x2457cdc0> (a sun.net.www.protocol.http.HttpURLConnection)
at com.sun.deploy.net.HttpUtils.followRedirects(Unknown Source)
at com.sun.deploy.net.BasicHttpRequest.doRequest(Unknown Source)
at com.sun.deploy.net.BasicHttpRequest.doGetRequestEX(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.checkUpdateAvailable(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.isUpdateAvailable(Unknown Source)
at com.sun.deploy.cache.DeployCacheHandler.get(Unknown Source)
- locked <0x245727a0> (a java.lang.Object)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
- locked <0x24572020> (a sun.net.www.protocol.http.HttpURLConnection)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
- locked <0x299726b8> (a sun.plugin2.applet.Applet2ClassLoader)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
- locked <0x299726b8> (a sun.plugin2.applet.Applet2ClassLoader)
at java.lang.ClassLoader.loadClass(Unknown Source)
As you can see it is waiting for a message --> waitForMessage().
At the same time there is our incoming JS call being BLOCKED here:
"Applet 1 LiveConnect Worker Thread" prio=4 tid=0x05231800 nid=0x1278 waiting for monitor entry [0x0770e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at MyClass.myMethod(MyClass.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin.javascript.Trampoline.invoke(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$LiveConnectWorker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Additional other threads were blocked in the same manner. I suppose all subsequent class-load requests were blocked by the first blocked class-loading thread.
As mentioned before, my guess is that the class-loading process is blocked by the pending JS call, which by itself is blocked by the missing class to be loaded.
Solutions:
Trigger loading all relevant classes in the constructor of the applet before any calls can be made from JS.
It might help if the class-files are not being loaded individually, but from a jar-file. The theory behind this is: The class loader does not need to talk to the browser to load the classes from the jar-file (which would be
In combination with 1.: Use a dynamic Proxy class to wrap all incoming JS calls and run them independently in an Executor.
My implementation for #3:
public class MyClass implements JsCallInterface
{
private final JsCallInterface jsProxy;
private final static interface JsCallInterface
{
public void myMethod1Intern(String param1, String param2);
}
private final class JsCallRunnable implements Runnable
{
private final Method method;
private final Object[] args;
private JsCallRunnable(Method method, Object[] args)
{
this.method = method;
this.args = args;
}
public void run()
{
try
{
method.invoke(MyClass.this, args);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public MyClass()
{
MyUtilsClass.class.getName(); // load class
JsCallRunnable.class.getName(); // load class
InvocationHandler jsCallHandler = new InvocationHandler()
{
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable
{
MyUtilsClass.executeInExecutor(new JsCallRunnable(method, args));
return null;
}
};
jsProxy = (JsCallInterface) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class<?>[] { JsCallInterface.class }, jsCallHandler);
}
public void myMethod1(String param1, String param2)
{
jsProxy.myMethod1Intern(param1, param2);
// needs to be named differently than the external method or else the proxy will call this method recursively
// alternatively the target-class in "method.invoke(MyClass.this, args);" could be a different instance of JsCallInterface
}
public void myMethod1Intern(String param1, String param2)
{
// do actual work here
}
}

This is a cosmetic bug in Oracle's HotSpot JVM - in your stack trace where you see - locked <0x00007f3e9a0b3830> it should actually say - waiting to lock <0x00007f3e9a0b3830>.
See this bug for more details.

Related

How to choose an AWT-EventQueue thread, when there are several of them

I successfully injected my own Java code in a running Oracle Forms application, using DLL Injection and some jni trickery. (Windows 7, 32 bits, Oracle Forms 11, JRE Java 8)
I am able to traverse the tree of Components and to query and set values in some basic Java objects, such as those from class oracle.forms.ui.VTextField
I am stuck when trying to simulate user click on a oracle.apps.fnd.ui.Button
I tried 2 things :
call the simulatePush method of the AbstractButton class
call the activate method of the PushButton class
(the 2 classes are in the class hierarchy for Button)
Results were identical:
1. At first, it works fine: when the button is a "Search" button, the search is done and the results are displayed.
2. Then, it immediately breaks the application, with a pop-up saying FRM-92100 Your connection to the Server was interrupted.
From there, the Application is hung.
Update:
It seems that the error which cause a disconnection from the Server is:
java.lang.SecurityException: this KeyboardFocusManager is not
installed in the current thread's context at
java.awt.KeyboardFocusManager.checkCurrentKFMSecurity(Unknown Source)
at java.awt.KeyboardFocusManager.getGlobalFocusOwner(Unknown Source)
at
java.awt.KeyboardFocusManager.processSynchronousLightweightTransfer(Unknown
Source) at
sun.awt.windows.WComponentPeer.processSynchronousLightweightTransfer(Native
Method) at sun.awt.windows.WComponentPeer.requestFocus(Unknown
Source) at java.awt.Component.requestFocusHelper(Unknown Source) at
java.awt.Component.requestFocusHelper(Unknown Source) at
java.awt.Component.requestFocus(Unknown Source) at
oracle.forms.handler.UICommon.updateFocus(Unknown Source) at
oracle.forms.handler.UICommon.setFVP(Unknown Source) at
oracle.forms.handler.UICommon.setFVP(Unknown Source) at
oracle.forms.handler.UICommon.onUpdate(Unknown Source) at
oracle.forms.handler.ComponentItem.onUpdate(Unknown Source) at
oracle.forms.handler.JavaContainer.onUpdate(Unknown Source) at
oracle.forms.handler.UICommon.onUpdate(Unknown Source) at
oracle.forms.engine.Runform.onUpdateHandler(Unknown Source) at
oracle.forms.engine.Runform.processMessage(Unknown Source) at
oracle.forms.engine.Runform.processSet(Unknown Source) at
oracle.forms.engine.Runform.onMessageReal(Unknown Source) at
oracle.forms.engine.Runform.onMessage(Unknown Source) at
oracle.forms.engine.Runform.processEventEnd(Unknown Source) at
oracle.ewt.lwAWT.LWComponent.redispatchEvent(Unknown Source) at
oracle.ewt.lwAWT.LWComponent.processEvent(Unknown Source) at
oracle.ewt.button.PushButton.activate(Unknown Source) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at
java.lang.reflect.Method.invoke(Unknown Source) at
CustomAWT.run(CustomAWT.java:34) at
java.awt.event.InvocationEvent.dispatch(Unknown Source) at
java.awt.EventQueue.dispatchEventImpl(Unknown Source) at
java.awt.EventQueue.access$400(Unknown Source) at
java.awt.EventQueue$2.run(Unknown Source) at
java.awt.EventQueue$2.run(Unknown Source) at
java.security.AccessController.doPrivileged(Native Method) at
java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown
Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown
Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at
java.awt.EventDispatchThread.run(Unknown Source)
My code is here: CustomAWT.run(CustomAWT.java:34) and is called with invokeLater. Problem is probably: when calling the oracle.ewt.button.PushButton.activate method, I am NOT in the right EDT.
Using "List Threads" in the Java Console, I got:
Dump thread list ...
Group main,ac=30,agc=2,pri=10
main,5,alive
traceMsgQueueThread,5,alive,daemon
Timer-0,5,alive
Java Plug-In Pipe Worker Thread (Client-Side),5,alive,daemon
AWT-Shutdown,5,alive
AWT-Windows,6,alive,daemon
AWT-EventQueue-0,6,alive
SysExecutionTheadCreator,5,alive,daemon
CacheMemoryCleanUpThread,5,alive,daemon
CacheCleanUpThread,5,alive,daemon
Browser Side Object Cleanup Thread,5,alive
JVM[id=0]-Heartbeat,5,alive,daemon
Windows Tray Icon Thread,5,alive
Thread-13,5,alive
Group Plugin Thread Group,ac=3,agc=0,pri=10
AWT-EventQueue-1,6,alive
TimerQueue,5,alive,daemon
ConsoleWriterThread,6,alive,daemon
Group http://xxxx.xxxx.xxxxx.xx:8001/OA_JAVA/-threadGroup,ac=13,agc=0,pri=4
Applet 1 LiveConnect Worker Thread,4,alive
AWT-EventQueue-2,4,alive
thread applet-oracle/apps/fnd/formsClient/FormsLauncher.class-1,4,alive
Applet 2 LiveConnect Worker Thread,4,alive
thread applet-oracle.forms.engine.Main-2,4,alive
Forms-StreamMessageReader,4,alive
Forms-StreamMessageWriter,4,alive
HeartBeat,4,alive
Busy indicator,1,alive,daemon
TaskScheduler timer,4,alive
CursorIdler,4,alive
Thread-14,4,alive
Flush Queue,4,alive
Done.
So, there is THREE AWT-EventQueue threads... Question is now: How to query/retrieve the right one, and how to make the Runnable passed to invokeLater to run in the "Good Thread" (I guess that the good one is the last one (AWT-EventQueue-2)
After a lot of experimentation and google searches with keywords like EventQueue and ThreadGroup I have finally found a solution (in the Works For Me category, mind you).
I use the sun.awt.AppContext class. Some documentation and sources here (grepcode.com)
Get a Collection of the running AppContext's using the getAppContexts method.
For each retrieved AppContext, get his ThreadGroup using the getThreadGroup method.
With the ThreadGroup object, Use the getName method.
When the name of the Thread Group starts with the http: address of your Forms Application, retrieve the Object property with key name sun.awt.AppContext.EVENT_QUEUE_KEY, using the get method of AppContext.
The retrieved object is an EventQueue. Create an java.awt.event.InvocationEvent object, passing your Runnable to the CTOR, and use the postEvent method of EventQueue.
Your run method will be executed in the right thread.
Remarks:
This answer is a specific, works for me, solution for an Oracle Forms Application launched via an Internet Explorer link, and running in a java.exe process. In that situation, the 3 Thread Groups are as shown in the question: main, Plugin Thread Group, and http://xxxx.xxxx.xxxxx.xx:8001/OA_JAVA/-threadGroup Your mileage may vary.
If you don't use full reflection, but instead do import sun.awt.AppContext, the compiler may emit warnings in the form warning: sun.awt.AppContext is Sun proprietary API and may be removed in a future release That's not very cool, but I will live with that, for the time being.
In the run method, I tested OK with the simulatePush method of oracle.ewt.lwAWT.AbstractButton.
The method emulated here is invokeLater. For invokeAndWait, more code is needed around the postEvent call. See some sources for the EventQueue class, as a starting point.
To get the correct EDT thread regardless of your thread group, you can use SunToolkit.targetToAppContext(Object target), and for the parameter you can feed it the AWT component you intend to act on. Example source.
Then get the EventQueue using EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext);
Finally, create a new InvocationEvent with your runnable and call postEvent on the EQ.
You should be able to extend VButton class
Your class definition should be something like:
public class AmazingButton extends VButton implements FocusListener
Then you need an init class like:
public void init(IHandler handler)
{
m_handler = handler;
super.init(handler);
addMouseListener(new ButtonMouseAdapter());
addFocusListener(this);
}
And then afterwards you need to implement the listeners and do some stuff in it:
public void focusGained(FocusEvent e)
{
if (e.getComponent() == this)
{
// put the focus on the component
e.getComponent().requestFocus();
bFocus = true ;
}
}
public void focusLost(FocusEvent e)
{
bFocus = false ;
}
/**
* Private class to handle user mouse actions
*/
class ButtonMouseAdapter extends MouseAdapter
{
/**
* User moved the mouse over the button
*/
public void mouseEntered(MouseEvent me)
{
bFocus=true ;
mouseON();
}
/**
* User moved the mouse out of the button
*/
public void mouseExited(MouseEvent me)
{
bFocus=false ;
mouseOFF();
}
/**
* User moved the mouse out of the button
*/
public void mousePressed(MouseEvent me)
{
bPressed = true ;
}
/**
* User moved the mouse out of the button
*/
public void mouseReleased(MouseEvent me)
{
bPressed = false ;
}
}
I hope this code works for you.
Regards
I successfully injected my own Java code in a running Oracle Forms application, using DLL Injection and some jni trickery.
That is the real problem here, IMO.
You are suffering from target fixation, which means that you, the programmer, has a fixed mental idea of what kind of solution they want and this blinds you to everything else. Target fixation has resulted in plane crashes, as even highly experienced and intelligent pilots ( in fact whole cockpits ! ) have become so fixated on one issue in one mindset that they let other disasters slip right by.
Get out of this frame of mind.
Your desired solution is not working out, so move on and try something else. Like the sensible option already presented to you by #nightfox79 and variations on that.
You are trying to circumvent a complex object class, when you should probably simply be extending the existing class you are trying to hack your way around. That's the whole basis of OOPs development.
DLL/JNI Trickery has no place in a sensible solution, IMO.
And I pity the person who has to maintain and repair any code solution based on a DLL/JNI hack. That way madness lies.
Your theory that invokeLater() is not running under the right EDT is probably wrong. invokeLater() will, according to the documentation, always queue the code you request onto the pending code list for the AWT Event handler, which is precisely where it should be. Trying to bypass that is almost certain to cause ghastly problems. The entire purpose of invokeLater() is to defer heavyweight processing in the EDT you invoke it from, and run it later on the exact same thread. It's a bug in invokeLater() if it does not, IMO.
If, however, you wish to check what thread code is running in then the only test I know of is to use this in your code ;
if (SwingUtilities.isEventDispatchThread())
{
System.err.println("Is running on EDT");
}
else
{
System.err.println("Is not running on EDT");
}

Java 8, using .parallel in a stream causes OOM error

In the book Java 8 In Action, section 7.1.1, the authors state that a stream can benefit from parallel processing by adding the function .parallel(). They provide a simple method called parallelSum(int) to illustrate this. I was curious to see how well it worked so I executed this code:
package lambdasinaction.chap7;
import java.util.stream.Stream;
public class ParallelPlay {
public static void main(String[] args) {
System.out.println(parallelSum(100_000_000));
}
public static long parallelSum(long n) {
return Stream.iterate(1L, i -> i + 1)
.limit(n)
.parallel()
.reduce(0L, Long::sum);
}
}
To my surprise, I received this error:
Exception in thread "main" java.lang.OutOfMemoryError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.util.concurrent.ForkJoinTask.getThrowableException(Unknown Source)
at java.util.concurrent.ForkJoinTask.reportException(Unknown Source)
at java.util.concurrent.ForkJoinTask.invoke(Unknown Source)
at java.util.stream.SliceOps$1.opEvaluateParallelLazy(Unknown Source)
at java.util.stream.AbstractPipeline.sourceSpliterator(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.reduce(Unknown Source)
at lambdasinaction.chap7.ParallelPlay.parallelSum(ParallelPlay.java:15)
at lambdasinaction.chap7.ParallelPlay.main(ParallelPlay.java:8)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.stream.SpinedBuffer.ensureCapacity(Unknown Source)
at java.util.stream.Nodes$SpinedNodeBuilder.begin(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.SliceOps$SliceTask.doLeaf(Unknown Source)
at java.util.stream.SliceOps$SliceTask.doLeaf(Unknown Source)
at java.util.stream.AbstractShortCircuitTask.compute(Unknown Source)
at java.util.concurrent.CountedCompleter.exec(Unknown Source)
at java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(Unknown Source)
at java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
at java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
I am running Java 1.8.0_45 on Windows 7, SP1 with a four-core processor. What's going on?
Here you create an infinite stream and limit it afterwards. There are known problems about processing infinite streams in parallel. In particular there's no way to split the task to equal parts effectively. Internally some heuristics are used which are not well suitable for every task. In your case it's much better to create the finite stream using LongStream.range:
import java.util.stream.LongStream;
public class ParallelPlay {
public static void main(String[] args) {
System.out.println(parallelSum(100_000_000));
}
public static long parallelSum(long n) {
return LongStream.rangeClosed(1, n).parallel().sum();
}
}
In this case Stream engine knows from the very beginning how many elements you have, so it can split the task effectively. Also note that using the LongStream is more effecient as you will have no unnecessary boxing.
In general avoid infinite streams if you can solve your task with finite ones.

Why does calling this method on the EDT cause a compilation error?

I am trying to pop up a custom dialog box. When I try calling the method to do that on the EDT I get the following error:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problem:
at danind.com.gmail_coem.ui.CredentialEditor.promptPossibleDialog(CredentialEditor.java:29)
at danind.com.gmail_coem.ui.HomeScreen$ConfigureDatabase.<init>(HomeScreen.java:281)
at danind.com.gmail_coem.ui.HomeScreen.configureDatabase(HomeScreen.java:230)
at danind.com.gmail_coem.ui.HomeScreen.lambda$1(HomeScreen.java:105)
at danind.com.gmail_coem.ui.HomeScreen$$Lambda$7/2092062410.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
After cleaning up my project in Eclipse, and doing some isolation tests I figured out that calling the method on the EDT was what caused the problem. When I moved the method to the background thread it worked, but I don't want that since I want to create my dialog GUI on the EDT.
//Creates compilation error
private class ConfigureDatabase extends SwingWorker<Void, String[]>
{
private CredentialEditor instance;
public ConfigureDatabase()
{ //Runs on EDT
this.instance = CredentialEditor.promptPossibleDialog(true);
}
#Override
protected Void doInBackground()
{ //Runs in background thread
try(Database database = CredentialEditor.getCredentials(instance))
{
//code
}
}
}
vs
//Runs just fine, but dialog GUI is not on EDT
private class ConfigureDatabase extends SwingWorker<Void, String[]>
{
#Override
protected Void doInBackground()
{ //Runs in background thread
try(Database database = CredentialEditor.getCredentials(CredentialEditor.promptPossibleDialog(true)))
{
//code
}
}
}
The method in question:
public static CredentialEditor promptPossibleDialog(boolean reset)
{
if(reset || ConnectionPool.getInstance() == null)
{ //Checks to see if a dialog box needs to be created.
if(SwingUtilities.isEventDispatchThread())
{ //Checks to make sure the thread is on the EDT.
return new CredentialEditor();
}
else
{ //If it's not on the EDT throw an exception warning.
throw new IllegalStateException("Must run on EDT!");
}
}
return null; //If no dialog box needs to be created return nothing.
}
To be more detailed about the problem it seems simply just calling the method causes problems. It's not setting the instance variable or anything inside the method, it's just calling that static method in the EDT specifically. In fact, the stacktrace points to the line where it's simply stating the method, as in, the line where it says public static CredentialEditor promptPossibleDialog(boolean reset)
So what is causing the error and if I can't get around it how can I run my GUI code on the EDT even if the method for it is being called on a background thread?
Try running your dialog directly on EDT.
public ConfigureDatabase()
{
//some code
this.instance = CredentialEditor.promptPossibleDialog(true); //This is line 281
}
This means you are running the dialog in the worker thread, which is not a good idea. Worker Threads are mostly, afaik, for non interactive background tasks. if you must run a dialog from within a worker thread, you must separately start it of in the EDT like:
public ConfigureDatabase()
{
SwingUtilities.invokeLater(new Runnable() { //or if you must wait for its end, use invokeAndWait
public void run() {
CredentialEditor.promptPossibleDialog(true); //This is line 281
}
});
}
This should work. It would be more helpful if would provide a full SSCE, at first how you execute your Worker.
Also dialogs are for interacting with the user and bringing back a result. Saving the dialog in an instance is therefor not the best thing to do. instead store its result or rethink your design.
see here, an example:
Note: calling get on the Event Dispatch Thread blocks all events,
including repaints, from being processed until this SwingWorker is
complete.
When you want the SwingWorker to block on the Event Dispatch Thread we
recommend that you use a modal dialog.
For example:
class SwingWorkerCompletionWaiter extends PropertyChangeListener {
private JDialog dialog;
public SwingWorkerCompletionWaiter(JDialog dialog) {
this.dialog = dialog;
}
public void propertyChange(PropertyChangeEvent event) {
if ("state".equals(event.getPropertyName())
&& SwingWorker.StateValue.DONE == event.getNewValue()) {
dialog.setVisible(false);
dialog.dispose();
}
}
}
Run as:
JDialog dialog = new JDialog(owner, true);
swingWorker.addPropertyChangeListener(
new SwingWorkerCompletionWaiter(dialog));
swingWorker.execute();
//the dialog will be visible until the SwingWorker is done
dialog.setVisible(true);
Specified by: get in interface Future Returns: the computed result
Throws: InterruptedException - if the current thread was interrupted
while waiting ExecutionException - if the computation threw an
exception
You are stumbling over the Eclipse feature of allowing to run code even if it has compile errors, which does more harm than any good, imho. You may consider turning it off. However, what you have to understand is that there is no use in looking at the line number of the stack trace as that won’t necessarily tell you the line number of the compilation error but the line number where the exception has been generated at runtime.
There is no attempt to compile your code when it runs. Instead the compiler has generated code that will throw that exception unconditionally once the execution reaches the piece of code which Eclipse couldn’t compile. And so it hasn’t anything to do with the thread your code runs in. Since the spurious compiler error appears within CredentialEditor it’s unbelievable that modifications made at the caller shall change whether it compiles correctly or not. However since the code throws IllegalStateException when called in the background threads but you say that it works in your second scenario it seems that there are changes you didn’t tell us about.
On the other hand, the behavior doesn’t have to look logical if it’s caused by a bug. Normally, the exception contains the compiler error but the empty line in you stack trace perfectly matches the observed behavior that the IDE didn’t tell you about that error. So you hit a bug where there either a compiler error is assumed where none exists or that a compiler error exists for which the message is missing.
Hitting a compiler bug is not that surprising considering what you failed to mention, that you are using Java 8 and even actively use the new features. Eclipse’s Java 8 support is … well … has much room for improvements. Just check whether you are really using the most recent Eclipse version. If you are using or if the problem remains after updating I recommend you create a minimal example that reproduces the problem and doesn’t depend on any other (3rd party) classes and file a bug report to the Eclipse team.

How can I work around this apparent EhCache deadlock?

Using ehCache 2.4.4, I seem to have gotten into a deadlock on the ehCache Segment object. From other logging, I know that the 'waiting thread', 1694 last ran anything 9 hours before this stack trace was generated. In the meantime, 1696 has gone and done a lot of other work, so this lock is definitely being held errantly.
I'm pretty confident that I am not directly locking any Segment instances directly, so I assume this is some kind of issue internal to the library. Any ideas?
"Model Executor - 1696" Id=1696 in TIMED_WAITING on lock=java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#92eb1ed
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(Unknown Source)
at java.util.concurrent.PriorityBlockingQueue.poll(Unknown Source)
at com.rtrms.application.modeling.local.BlockingTaskList.takeTask(BlockingTaskList.java:20)
at com.rtrms.application.modeling.local.ModelExecutor.executeNextTask(ModelExecutor.java:71)
at com.rtrms.application.modeling.local.ModelExecutor.run(ModelExecutor.java:46)
Locked synchronizers: count = 1
- java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync#4a3d767f
"Model Executor - 1694" Id=1694 in WAITING on lock=java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync#4a3d767f
owned by Model Executor - 1696 Id=1696
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(Unknown Source)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock(Unknown Source)
at net.sf.ehcache.store.compound.Segment.unretrievedGet(Segment.java:248)
at net.sf.ehcache.store.compound.CompoundStore.unretrievedGet(CompoundStore.java:191)
at net.sf.ehcache.store.compound.impl.DiskPersistentStore.containsKeyInMemory(DiskPersistentStore.java:72)
at net.sf.ehcache.Cache.searchInStoreWithStats(Cache.java:1884)
at net.sf.ehcache.Cache.get(Cache.java:1549)
at com.rtrms.amoeba.cache.DistributedModeledSecurities.get(DistributedModeledSecurities.java:57)
at com.rtrms.amoeba.modeling.AssertPersistedModeledSecurities.get(AssertPersistedModeledSecurities.java:44)
at com.rtrms.application.modeling.tasks.ExpandableModelingTask.getNextUnexecutedTask(ExpandableModelingTask.java:35)
at com.rtrms.application.modeling.local.BlockingTaskList.takeTask(BlockingTaskList.java:36)
at com.rtrms.application.modeling.local.ModelExecutor.executeNextTask(ModelExecutor.java:71)
at com.rtrms.application.modeling.local.ModelExecutor.run(ModelExecutor.java:46)
Locked synchronizers: count = 0
Turns out that calls like Cache.acquireWriteLockOnKey end up obtaining a lock on the internal Segment, so this apparent deadlock was caused by a .unlock call that wasn't in a finally block.
Editorial comment: It also implies that you can get contention trying to lock two different keys that just happened to be in the same Segment, which is pretty unfortunate.

How can I decouple java to javascript calls? Applet is waiting on itself!

I am having trouble avoiding a sporadic crash in my applet that appears to be caused by a thread waiting on itself. Strangely, this only seems to happen in google chrome.
30-second read:
Applet.methodA() calls JSObject.javascriptMethod()
javascriptMethod() makes a Applet.methodB() call
Applet.methodB() waits for Applet.methodA() to release its lock, which never happens..
What I've Tried:
using setTimeout in javascriptMethod. no luck there.
using JSObject.eval() instead of JSObject.call()
Also possible:
that i've totally misinterpreted the thread dump. Here it is for inspection.
My understanding:
The sequencer thread calls applet.notifyPosition
notifyPosition calls a javascript method
javascript method calls applet.pause
applet.pause needs to lock the sequencer, but can't because it's busy calling notifyposition..
"Java Sound Sequencer" prio=8 tid=0x189de400 nid=0x86c in Object.wait() [0x1c6ae000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x099c50e0> (a java.lang.Object)
at com.sun.media.sound.RealTimeSequencer$PlayThread.stop(Unknown Source)
- locked <0x099c50e0> (a java.lang.Object)
- locked <0x099c50e8> (a com.sun.media.sound.RealTimeSequencer$PlayThread)
at com.sun.media.sound.RealTimeSequencer.implStop(Unknown Source)
at com.sun.media.sound.RealTimeSequencer.stop(Unknown Source)
- locked <0x099c8ca8> (a com.sun.media.sound.RealTimeSequencer)
at net.alphatab.midi.MidiPlayer.pause(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport.doObjectOp(Unknown Source)
at sun.plugin2.main.client.MessagePassingJSObject.waitForReply(Unknown Source)
at sun.plugin2.main.client.MessagePassingJSObject.call(Unknown Source)
at net.alphatab.midi.MidiPlayer.notifyPosition(Unknown Source)
at net.alphatab.midi.MidiPlayer.access$200(Unknown Source)
at net.alphatab.midi.MidiPlayer$1.controlChange(Unknown Source)
at net.alphatab.midi.TickNotifierReceiver.send(Unknown Source)
at com.sun.media.sound.AbstractMidiDevice$TransmitterList.sendMessage(Unknown Source)
- locked <0x0982d8e8> (a java.util.ArrayList)
at com.sun.media.sound.RealTimeSequencer$DataPump.dispatchMessage(Unknown Source)
at com.sun.media.sound.RealTimeSequencer$DataPump.pump(Unknown Source)
- locked <0x09a56ae8> (a com.sun.media.sound.RealTimeSequencer$DataPump)
at com.sun.media.sound.RealTimeSequencer$PlayThread.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Here we see the part that looks like a problem:
"Java Sound Sequencer" prio=8 tid=0x189de400 nid=0x86c in Object.wait() [0x1c6ae000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x099c50e0> (a java.lang.Object)
at com.sun.media.sound.RealTimeSequencer$PlayThread.stop(Unknown Source)
- locked <0x099c50e0> (a java.lang.Object)
This waiting on <0x099c50e0> does not mean that the thread waits to get the lock, but it had the lock, and called wait() on this object, meaning that it temporarily gave the lock away and waits until some other thread will call .notify() or .notifyAll() on this same object.
Thus, this single stack trace does not show a deadlock.
Of course, it could be that the actual calls from applet to JavaScript and from JavaScript back to applet are on different threads, which could show the behavior you describe. But the stack trace you have here does not seem to indicate this (I suppose the alphatab classes are your's).
The problem is simply that nobody is calling notify() for some reason. Maybe there was some synchronization error, so the notify actually came before the wait. Or some other thread is waiting on some other lock before notifying (this would be a real dead lock).

Categories

Resources