Primefaces lazy datascroller calling load twice - jsf-2

I'm trying to use a Datascroller with a LazyDataModel and the load method from lazy data model is getting called twice.
Appart from thinking that it is not so good to call the load method multiple times (that may perform costly server/DB roundtrips), since my lazy data model not idempotent (meaning, two consecutive calls to the model on the same window/page size returns different outcomes) the fact that it's being called twice means: the presented results are not correct.
Is it normal for the load method in datascroller to be called twice?
If so, any workarounds suggested for my alternative to work correctly? (appart from changing from statefull to stateless data model)
Using Primefaces 5.1, JSF2, Glassfish 4.1

No, this is not normal. This is indeed a bug in PrimeFaces. We also discovered it a while ago when using it at zeef.com. We bypassed it by creating a custom renderer extending DataScrollerRenderer and overriding only encodeMarkup() method with the original implementation copypasted and then only the following piece outcommented:
// BUGFIX: outcommented as this is already done in loadChunk() later on.
/*if(ds.isLazy()) {
loadLazyData(ds, 0, chunkSize);
}*/
You can get it to run by registering it as below in webapp's faces-config.xml:
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.DataScrollerRenderer</renderer-type>
<renderer-class>com.example.YourDataScrollerRenderer</renderer-class>
</renderer>
</render-kit>

Since the header facet, in BalusC post, is not correctly rendered if the first load (commented section) does not run, a slightly different implementation is needed
public class DataScrollerRenderer2 extends DataScrollerRenderer {
#Override
protected void encodeMarkup(FacesContext context, DataScroller ds, int chunkSize) throws IOException {
// ...
boolean alreadyLoaded = false;
if (ds.isLazy()) {
alreadyLoaded = true;
loadLazyData(ds, 0, chunkSize);
}
// ...
loadChunk(context, ds, 0, chunkSize, alreadyLoaded);
// ...
}
#Override
protected void loadChunk(FacesContext context, DataScroller ds, int start, int size) throws IOException {
loadChunk(context, ds, start, size, false);
}
private void loadChunk(FacesContext context, DataScroller ds, int start, int size, boolean alreadyLoaded) throws IOException {
// ...
if (ds.isLazy() && !alreadyLoaded) {
loadLazyData(ds, start, size);
}
// ...
}
}
Not sure if this is the best implementation, but it worked.
EDIT: an issue has been filed in PrimeFaces GitHub

Related

waitForConfirmsOrDie vs PublisherCallbackChannel.Listener

I need to achieve the impact of waitForConfirmsOrDie in core java implementation in spring . In core java it is achievable request wise ( channel.confirmSelect , set Mandatory , publish and Channel.waitForConfirmsOrDie(10000) will wait for 10 sec)
I implemented template.setConfirmCallback ( hope it is same as PublisherCallbackChannel.Listener) and it works great , but ack/nack is at a common place ( confirm call back ) , for the individual sender no idea like waitForConfirmsOrDie , where he is sure within this time ack hasn't came and can take action
do send methods wait for specified period internally like waitForConfirmsOrDie in spring if ack hasn't came and if publisherConfirms is enabled.
There is currently no equivalent of waitForConfirmsOrDie in the Spring API.
Using a connection factory with publisher confirms enabled calls confirmSelect() on its channels; together with a template confirm callback, you can achieve the same functionality by keeping a count of sends yourself and adding a method to your callback to wait - something like...
#Autowired
private RabbitTemplate template;
private void runDemo() throws Exception {
MyCallback confirmCallback = new MyCallback();
this.template.setConfirmCallback(confirmCallback);
this.template.setMandatory(true);
for (int i = 0; i < 10; i++) {
template.convertAndSend(queue().getName(), "foo");
}
confirmCallback.waitForConfirmsOrDie(10, 10_000);
System.out.println("All ack'd");
}
private static class MyCallback implements ConfirmCallback {
private final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
#Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
queue.add(ack);
}
public void waitForConfirmsOrDie(int count, long timeout) throws Exception {
int remaining = count;
while (remaining-- > 0) {
Boolean ack = queue.poll(timeout, TimeUnit.MILLISECONDS);
if (ack == null) {
throw new TimeoutException("timed out waiting for acks");
}
else if (!ack) {
System.err.println("Received a nack");
}
}
}
}
One difference, though is the channel won't be force-closed.
Also, in a multi-threaded environment, you either need a dedicated template/callback per thread, or use CorrelationData to correlate the acks to the sends (e.g. put the thread id into the correlation data and use it in the callback).
I have opened AMQP-717 for us to consider providing something like this out of the box.

Measure the render time of a JSF view after a server request

I would like to measure the rendering time of a JSF application. Because of out of my power reasons, the application can't be populated with logs.
Therefore, my question would be, is there any way in which I can measure the rendering time of the application after doing a certain action that includes a back-end(server) call using any browser?
So far,after using the Chrome Developer Tools,I spotted the following. On the Network tab, each request has the "Time" displayed. In addition, after selecting a certain entry, on the "Timing" tab, a more detailed visualization it's displayed.
Now, I can tell from that that the "Waiting" that the round-trip to the server it's captured here, but what about the actual rendering time.
Assuming that the whole request took 1sec, and the Waiting section it's 500ms, can I deduct that the rendering it's the 1sec-500ms ? I assume not, thats why I am asking this question.
Long story short, I would need to know from the browser, for a certain request how long was the server processing and how long was the actual UI rendering.
Any tips would be greatly appreciated. Thank you.
You can do that with a custom ViewDeclarationLanguage whereby you measure the createView(), buildView(), renderView() and if necessary restoreView() methods.
Here's a kickoff example:
public class VdlLogger extends ViewDeclarationLanguageWrapper {
private static final Logger logger = Logger.getLogger(VdlLoggerFactory.class.getName());
private ViewDeclarationLanguage wrapped;
public VdlLogger(ViewDeclarationLanguage wrapped) {
this.wrapped = wrapped;
}
#Override
public UIViewRoot createView(FacesContext context, String viewId) {
long start = System.nanoTime();
UIViewRoot view = super.createView(context, viewId);
long end = System.nanoTime();
logger.info(String.format("create %s: %.6fms", viewId, (end - start) / 1e6));
return view;
}
#Override
public void buildView(FacesContext context, UIViewRoot view) throws IOException {
long start = System.nanoTime();
super.buildView(context, view);
long end = System.nanoTime();
logger.info(String.format("build %s: %.6fms", view.getViewId(), (end - start) / 1e6));
}
#Override
public void renderView(FacesContext context, UIViewRoot view) throws IOException {
long start = System.nanoTime();
super.renderView(context, view);
long end = System.nanoTime();
logger.info(String.format("render %s: %.6fms", view.getViewId(), (end - start) / 1e6));
}
#Override
public ViewDeclarationLanguage getWrapped() {
return wrapped;
}
}
To get it to run, create the below factory:
public class VdlLoggerFactory extends ViewDeclarationLanguageFactory {
private ViewDeclarationLanguageFactory wrapped;
public VdlLoggerFactory(ViewDeclarationLanguageFactory wrapped) {
this.wrapped = wrapped;
}
#Override
public ViewDeclarationLanguage getViewDeclarationLanguage(String viewId) {
return new VdlLogger(wrapped.getViewDeclarationLanguage(viewId));
}
#Override
public ViewDeclarationLanguageFactory getWrapped() {
return wrapped;
}
}
And register it as below in faces-config.xml:
<factory>
<view-declaration-language-factory>com.example.VdlLoggerFactory</view-declaration-language-factory>
</factory>
The createView() is the step of creating the concrete UIViewRoot instance based on <f:view> and <f:metadata> present in the view files. When using Facelets (XHTML) as view, during this step all associated XHTML files will be parsed by the SAX parser and cached for a time as defined in javax.faces.FACELETS_REFRESH_PERIOD. So it may happen that it's one time relatively slow and the other time blazing fast.
The buildView() is the step of populating the JSF component tree (the getChildren() of UIViewRoot) based on the view (XHTML) composition. During this step, all taghandlers (JSTL and friends) are executed and all EL expressions in those taghandlers and component's id and binding attributes are evaluated (for detail, see also JSTL in JSF2 Facelets... makes sense?). So if backing beans are constructed for first time during view build time and invoking business logic during #PostConstruct, then it may happen that this is time consuming.
The renderView() is the step of generating the HTML output based on JSF component tree and the model, starting with UIViewRoot#encodeAll(). So if backing beans are constructed for first time during view render time and invoking business logic during #PostConstruct, then it may happen that this is time consuming.
If backing beans are incorrectly performing business logic in getter methods instead of in #PostConstruct or any other one-time-occurring life cycle event listener, then it may happen that this consumes yet more time. See also Why JSF calls getters multiple times.

CodenameOne Connection Request hangs when repeated

I have the following Codename One code for accessing a network resource. It is almost an exact copy of the Codename One tutorial for this use case.
public void executeRequest(){
String url = "http://www.random.net";
InfiniteProgress prog = new InfiniteProgress();
final Dialog dlg = prog.showInifiniteBlocking();
ConnectionRequest r = new ConnectionRequest() {
#Override
protected void postResponse() {
//handle changes to my form
}
#Override
protected void readResponse(InputStream input)
throws IOException {
//handle parsing data
}
#Override
protected void handleIOException(IOException err) {
super.handleIOException(err);
}
};
r.setUrl(url);
r.setPost(false);
r.addArgument("arg", "2");
r.setDuplicateSupported(true);
r.setDisposeOnCompletion(dlg);
NetworkManager.getInstance().addToQueue(r);
}
The first time I run it - no problem. If I try to "refresh" my data by calling the same method over again, the app will hang up with the InfiniteProgress dialog spinning forever. Its almost like the first network request is not ever really completing, and then the second one kind of conflicts. Any ideas what I'm doing wrong?
By default duplicate requests to the exact same URL are disabled, try invoking setDuplicatesSuppotred(true) on the connection request.
For future reference, what fixed this for me was to use
NetworkManager.getInstance().addToQueueAndWait(r);
instead. That cleared up most of my problems.
I stucked with the same problem and none of solutions worked. However, I did it this way:
final NetworkManager nm = NetworkManager.getInstance();
nm.setTimeout(3000);
then
protected void postResponse() {
...
nm.shutdown();
}
and call was made as
nm.addToQueueAndWait(request);
Maybe the fact that NetworkManager was made final did the job, but I put "shutdown" just for sure. It worked for me

PrimeFaces DataTable: (Multi)selection does not work for dynamically built tables giving only nulls

I'm working with the multiple row selection to give a user ability to delete the selecting records. According to the PDF documentation, and the ShowCase Labs, I must use the code translated to the Java like that:
final DataTable = new DataTable();
...
// (1)
dataTable.setSelectionMode("multiple");
// (2)
dataTable.setValueExpression("selection", createValueExpression(DbeBean.class, "selection", Object[].class));
// (3)
dataTable.setValueExpression("rowKey", createValueExpression("#{" + VARIABLE + ".indexKey}", Object.class));
...
final ClientBehaviorHolder dataTableAsHolder = dataTable;
...
// (4)
dataTableAsHolder.addClientBehavior("rowSelect", createAjaxBehavior(createMethodExpression(metaData.controllerBeanType, "onRowSelect", void.class, new Class<?>[] {SelectEvent.class})));
multiple - This line features the multiple selection, works fine visually at the front-end.
selection - Being invoked, the #{dbeBean.selection} is really bound and the public void setSelection(T[] selection) is only invoked.
rowKey - Being invoked, works fine, the getIndexKey() is invoked and returns the necessary result.
rowSelect - This event handler is invoked too, DbeBean.onRowSelect(SelectEvent e).
I also use lazy data model (I don't really believe it may be the reason but who knows?; by the way, it returns List<T> though setSelection() requires T[] -- why it's like that?):
public abstract class AbstractLazyDataSource<T extends IIndexable<K>, K> extends LazyDataModel<T> {
...
#Override
public final List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
...
final IResultContainer<T> resultContainer = getData(querySpecifier);
final List<T> data = resultContainer.getData();
setRowCount(resultContainer.getTotalEntitiesCount());
return getPage(data, first, pageSize);
}
...
#Override
public final K getRowKey(T object) {
return object.getIndexKey(); // T instanceof IIndexable<K>, have to return a unique ID
}
...
However, the handlers do not work as they are expected to work. Please help me to understand why (2) DbeBean.setSelection(T[] selection) & (4) DbeBean.onRowSelect(SelectEvent e) get only the null value: T[] selection = null, and SelectEvent: e.getObject = null, respectively. What am I doing wrong?
Thanks in advance.
PrimeFaces 3.2
Mojarra 2.1.7
I've got it to work: I simply removed the rowKey property during to the dynamic p:dataTable creation (DataTable), and simply overloaded getRowData in lazy data model. Now it works.

Monodroid GREF problem best practice?

I have the following test code (based on standard monodroid HelloWorld)
namespace TestGREF
{
[Activity (Label = "TestGREF", MainLauncher = true)]
public class Activity1 : Activity
{
int count = 1;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate {
button.Text = string.Format ("{0} clicks!", count++);
for(int i=0;i<10000;i++){
new Java.Lang.Object(new System.IntPtr(i));
//...some stuff here. Instead of Java.Lang.Object may be
//something much more useful.
}
//If uncomment here, looks ok
//GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
};
}
}
}
If I click the button 5-6 times, application crashes.
I know this happens because of global refences (GREF) limit (described here, "Unexpected NullReferenceExceptions" section). The question is: what to do with it? What is the best practice? If possible, with code example please
If uncomment GC.Collect() call, all seems working, but calling GC too often is too exspensive for performance. Another popular design is to put new statement put of loop, but it is not always possible cause of program logic.
Any more ideas?
You need to release all unmanaged objects when they no longer needed. All classes that inherits from Android.Runtime.IJavaObject also inherits IDisposable so you need to dispose them.
Here is part from my project
private Spinner _spType;
private ArrayAdapter _arrayAdapter;
protected override void OnCreate(Android.OS.Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
_spType = FindViewById<Spinner>(Resource.Id.spinnerType);
_arrayAdapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleSpinnerItem, new[] {"1","2","3","4","5"});
_spType.Adapter = _arrayAdapter;
}
public override void Finish()
{
if (_spType != null)
_spType.Dispose();
if (_arrayAdapter != null)
_arrayAdapter.Dispose();
base.Finish();
}
for(int i=0;i<10000;i++){
var obj = new Java.Lang.Object(new System.IntPtr(i));
//...some stuff here. Instead of Java.Lang.Object may be
//something much more useful.
obj.Dispose(); //Deletes an object and GREF too.
//Cannot be used if object is still used in dalvik VM
}
If you cannot use Dispose() (for example, unmanaged object is a part of layout, which will be used by android lated, but not by C# code), use GC.Collect() wisely. GC.Collect() kills all the GREFs to variables, which are out of usage by Mono Environment and out of current scope.
Here is article about GC and memory management in monodroid. It can be helpful for you
http://docs.xamarin.com/android/advanced_topics/garbage_collection

Resources