Author |
Message |
14/09/2021 06:54:43
|
mlaggner
Power User
Joined: 19/08/2019 10:56:59
Messages: 28
Offline
|
Hi there,
I have discovered a weird behaviour. If i use long polling (e.g. LongOperationWithObserverPopup) and use the ResourceManager.getRuntimeInstance().readProperty(...) to read some localized text, the access to HttpSessionAccess.getCurrentLocale() inside the ResourceManager leads to a null pointer exception.
Take this for example:
Code:
final IObserver observer = LongOperationWithObserverPopup.prepare(ResourceManager.getRuntimeInstance().readProperty("messages", "loading.title"));
// this operation has nothing to do with UI, but can add messages
// to the observer. Within the operation you should not
// use UI operations because this is not the UI thread!
Runnable longOperation = () -> {
// get data
observer.addMessage(ResourceManager.getRuntimeInstance().readProperty("messages", "loading.start"));
};
// this operation is called after the longOperation was finished:
// here you are within a real request/response processing, i.e.
// you have full access to all UI operations.
Runnable finishOperation = () -> {
// dummy
};
LongOperationWithObserverPopup.run(longOperation, finishOperation);
I've debugged that until ResourceManager.readProperty(String resourceName, String property, boolean withError) where your code tries to get the current Locale via the HttpSessionAccess.getCurrentLocale() where the FacesContext.getCurrentInstance() returns a null value
I hope the description is clear enough to reproduce the issue ;)
br
Manuel
|
Manuel Laggner, FRITZ EGGER GmbH & Co. OG |
|
|
14/09/2021 07:45:43
|
CaptainCasa
Power User
Joined: 21/11/2007 12:23:06
Messages: 5518
Offline
|
Hi Manuel,
the answer is part of your code ;-)...:
Code:
// this operation has nothing to do with UI, but can add messages
// to the observer. Within the operation you should not
// use UI operations because this is not the UI thread!
ResourceManger.getRuntimeInstance() requires to be run in the context of the normal request/response thread, while here it is executed in a parallel, processing thread.
Way out:
Read the instance of ResourceMager.getRuntimeInstance() in the request/response thread, store it in a final variable and use this in your parallel thread.
Code:
final ResourceManager myResourceManagerInstance = ResourceManager.getRuntimeInstance();
final IObserver observer = LongOperationWithObserverPopup.prepare(ResourceManager.getRuntimeInstance().readProperty("messages", "loading.title"));
// this operation has nothing to do with UI, but can add messages
// to the observer. Within the operation you should not
// use UI operations because this is not the UI thread!
Runnable longOperation = () -> {
// get data
observer.addMessage(myResourceManagerInstance.readProperty("messages", "loading.start"));
};
// this operation is called after the longOperation was finished:
// here you are within a real request/response processing, i.e.
// you have full access to all UI operations.
Runnable finishOperation = () -> {
// dummy
};
Kind regards, Björn
|
Björn Müller, CaptainCasa GmbH |
|
|
14/09/2021 08:02:22
|
mlaggner
Power User
Joined: 19/08/2019 10:56:59
Messages: 28
Offline
|
thanks for the quick answer! Well this is not exactly the problem, because the access to HttpSessionAccess.getCurrentLocale() is inside the ResourceManager (and not accessible by me). The ResourceManager itself can be accessed from inside the long polling thread
But if that is simply not possible in that special case, I need to re-write the access to the ResourceBundle by a direct access to the ResourceManager.readProperty(String resourceName, String property, Locale locale, boolean withError) with the Locale I can get from the HttpSessionAccess.getCurrentLocale() outside of the long polling manager (should work, but not as reusable/clean as it should be):
Code:
final Locale locale = HttpSessionAccess.getCurrentLocale();
final IObserver observer = LongOperationWithObserverPopup.prepare(ResourceManager.getRuntimeInstance().readProperty("messages", "loading.title", locale));
// this operation has nothing to do with UI, but can add messages
// to the observer. Within the operation you should not
// use UI operations because this is not the UI thread!
Runnable longOperation = () -> {
// get data
observer.addMessage(ResourceManager.getRuntimeInstance().readProperty("messages", "loading.start", locale));
};
// this operation is called after the longOperation was finished:
// here you are within a real request/response processing, i.e.
// you have full access to all UI operations.
Runnable finishOperation = () -> {
// dummy
};
LongOperationWithObserverPopup.run(longOperation, finishOperation);
|
Manuel Laggner, FRITZ EGGER GmbH & Co. OG |
|
|
14/09/2021 09:02:20
|
CaptainCasa
Power User
Joined: 21/11/2007 12:23:06
Messages: 5518
Offline
|
...yes + agree!
Please also note: since Dec 2012 there is a "blocker info" mechanism which is muchchch easier to use for long operations and which does not push the processing in some non-UI-thread: http://www.captaincasa.com/docu/eclnt_changelog/all.html#improvementprogressmessageoutputduringserverprocessing
Please check: web sockets need to be allowed within your environment to use this function.
Regards! Björn
|
Björn Müller, CaptainCasa GmbH |
|
|
14/09/2021 13:10:28
|
mlaggner
Power User
Joined: 19/08/2019 10:56:59
Messages: 28
Offline
|
thanks for the suggestion - But I like the "history" of the messages more in this case ;)
I could solve my issue with the code above - thanks for your help
|
Manuel Laggner, FRITZ EGGER GmbH & Co. OG |
|
|
|