-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi, I am currently using the Zk framework ver 7.0.6.1 for our Web servers. Recently there have been numerous complaints of the servers getting super slow in production. Upon inspecting the logs, we found that the logs were filled with error - "Failed to invoke class org.zkoss.zkplus.util.ThreadLocalListener java.lang.NullPointerException" Now, this issue is very random and we have not been able to figure out a pattern to reproduce it. Nonetheless, a lot of customers have started reporting this issue.
Upon inspecting the ThreadLocalListener class, its constructor tries to retrieve the WebApp with the given line final WebApp app = Executions.getCurrent().getDesktop().getWebApp();
I believe the desktop object here is null, throwing the errors. My question is that although going through the tracker I found this issue to be fixed, it still seems to have cropped back again. What should be the fix for it and what seems to be the reason for it.
Could you paste the exception stack trace?
But enable event thread is deprecated since zk 7. So we don't suggest to enable event thread.
If you don't use event thread, then you don't need to add ThreadLocalListener
.
Use ZK with SpringBoot, please refer to https://www.zkoss.org/wiki/ZKInstallationGuide/QuickStart/CreateandRunYourFirstZKApplicationwithSpringBoot#TheZK-SpringBoot_Demos
Thanks Hawk. Adding stacktrace.
2019-04-12 02:52:28,723 ERROR -
java.lang.NullPointerException
at org.zkoss.zk.ui.impl.EventProcessor.setup(EventProcessor.java:158)
at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.setup(EventProcessingThreadImpl.java:419)
at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.run(EventProcessingThreadImpl.java:452)
2019-04-12 02:52:28,736 ERROR - Failed to invoke class org.zkoss.zkplus.util.ThreadLocalListener
java.lang.NullPointerException
at org.zkoss.zkplus.util.ThreadLocalListener.<init>(ThreadLocalListener.java:98)
at sun.reflect.GeneratedConstructorAccessor133.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:383)
at org.zkoss.zk.ui.util.Configuration.newEventThreadCleanups(Configuration.java:535)
at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.newEventThreadCleanups(EventProcessingThreadImpl.java:525)
at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.run(EventProcessingThreadImpl.java:466)
Also in the current code, the event threads are enabled. I guess this has something to do with the fact that the code was built using 6.5 when event threads were not deprecated and later upgraded to 7.0.2 and then to 7.0.6.1. Also we use quite a few modal dialogs and currently use the getAttribute()
to get responses from it and use it. Without event threads I believe we might have to modify the workflow quite a bit to get things working.
We have the following settings in the zk.xml as of now
<system-config>
<disable-event-thread>false</disable-event-thread>
</system-config>
<listener>
<description>ThreadLocal Synchronization Listener</description>
<listener-class>org.zkoss.zkplus.util.ThreadLocalListener</listener-class>
</listener>
<listener>
<description>Controls the global update thread</description>
<listener-class>com.ourproduct.web.GlobalUpdater</listener-class>
</listener>
<preference>
<name>ThreadLocal</name>
<value>
org.springframework.security.context.ThreadLocalSecurityContextHolderStrategy=contextHolder
</value>
</preference>
Some code snippets from our application just for reference is
try {
window.doModal();
}
catch( SuspendNotAllowedException e ) {
//log
}
catch( UiException e ) {
//log
}
if( !(Boolean) window.getAttribute("stop") ) return;
So if you say that we should disable event threads then there will be no need for the ThreadLocalListener. But in that case what should be the way to listen to messages from the modal window? Apologies for the naive question as I am new to this framework supporting some huge legacy code out there.
Thanks
It won't be hard to rewrite it. Since ThreadLocalListener
is very old (since zk 2.x) and gets no more updated for the event thread was deprecated. I suggest you to remove it.
I think there should be a place (or an event listener) where you set the attribute to a Window like window.setAttribute("stop", false)
. I suppose it would be onClose
event listener. So you can implement your business logic in that listener.
Or you can add a button in the Window and listen to the button onClick
event to execute your business logic and close the modal window.
For other components related to event thread, you can reference: https://www.zkoss.org/wiki/ZKDeveloper%27sReference/UIPatterns/EventThreads
Thanks Hawk for your prompt reply. Just had a query. After I posted the stacktrace for the error, what do you think is the issue in this case. Could you kindly share some insight into the current problem that I am facing.
I suspect that the Desktop
is null
in this case. What do you think and if I am correct, in what scenario is this possible?
The reason I am asking for this possible scenario is because my zk code base is huge and this will help me narrow things out a bit. Also trying to change this code for modal window would require a good amount of regression to be done which might delay the release.
The code at org.zkoss.zk.ui.impl.EventProcessor.setup(EventProcessor.java:158)
is
((ExecutionCtrl)exec).setCurrentPage(getPage());
So the exec
, execution, is null.
if the execution is null, then this line
org.zkoss.zkplus.util.ThreadLocalListener.<init>(ThreadLocalListener.java:98)
will also throw NullPointerException
Normally, a desktop should contain a not-null execution. ZK creates an execution based on HTTP request. Need to find out why there is no related HTTP request.
Thanks Hawk. I am generally facing this issue when a very long running task is left open on the UI. It occurs sometimes and sometimes it does not. But one thing is common that a long running task is underway and that is when it happens.
The problem might be your implementation of that long running operation. If run a long operation in a separate thread, there is no ZK Execution
available in that separate thread. This might be related to your issue.
Please read
remember to activate()
desktop in a separate thread.
Thanks Hawk. We decided to do away with ThreadLocalListener all together. The code changes and testing took sometime but I guess it is well worth the effort.
Thanks!
Asked: 2019-04-12 21:40:33 +0800
Seen: 26 times
Last updated: Jul 29 '19