wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

XPiNC development insights


I am developing a rather large XPiNC application for IBM internal use. One application and parameter database pushes data around 10 backend databases. Part of the databases might be local (depending on the user), some might be on the server and not all users have access to all databases. Most of my business logic lives in Java code, both in classes, beans and managed beans. In the course of the development I stumbled over a series of insights a XPiNC developer should be aware of. Here it goes, in no specific order:
  • FacesContext.getCurrentInstance() might return null when called in your Java class, depending on when you call it. I had calls to the FacesContext in some of my managed bean property calls which failed on page load with a Error 500 that the standard error page couldn't trap. You need the FacesContext to resolve any variable e.g. getting a handle on a different managed bean. In conclusion I rearchitected my beans to have only one managed bean per context modeled as Facade pattern that provides a single access point to all classes needed
  • The ExtlibUtil.getCurrentSession() uses the FacesContext under the hood, so there is a distinct risk of getting a null session. So using the dependency injection pattern all calls requiring a NotesSession have a NotesSession as calling parameter. This requires a bean design that is populated elsewhere (e.g. DataContext, ObjectDataSource), so you can have getters and setters without parameters
  • Longer running operations (stuff we typically do in an agent) will time out. You don't have the luxury in XPiNC to use agent.runOnServer(), so you need a different approach (and anyway I despise mixing XPages and agents). With the help of a friend and the ever impeccable Dublin team I figured a way to run Notes backend accessing code as a thread (subject to another story)
  • Debugging is way less comfortable than in XPages. You have to put the whole client into debug mode, not just connect to the http task. So I tend to start my Notes client with -RPARAM -consoleso I see what System.out and System.err are producing. I also tend to keep my code in Java to make it more testable easily
  • The XPages Debug Toolbar works well in XPiNC
  • There is no way to restart the XPiNC task like you can restart the http task or the web preview task in Designer. When you use external jars and update them, you have to restart your client to test it successfully
  • In a data source you can specify databases by replica id. This is nice since you might not know where a local replica is located. However you only can specify the replica id and unless NotesDatabase.openByReplicaId() not the server. So you never know which database you might get (local or one of the known server). So I compute once (and keep it in the sessionScope) the actual filepath, trying local first, and use server/filepath instead of replica id for data sources
  • The Java Collection framework is your friend. You can use them nicely as source for a repeat control. Just keep in mind: a list will give you the entry in your instance variable, while a map will give you they key only. Of course a key can be any Java object, so some creative key creation goes a long way
  • A very popular way in Notes applications was the use of NotesDocument.computeWithForm(). When connecting to existing applications you will be tempted (or actually required) to use it too. When the computeWithForm tries to trigger some UI interaction in the @Formula, your XPiNC tab will lose focus to a native tab (I haven't figured out which one gets selected) and a externalContext.redirect() will simply not happen
  • In an XPiNC application sessionScope and applicationScope are local to the current user. So status exchange via applicationScope won't work in XPiNC. After all you run a local JEE server instance in your local Expeditor framework (a.k.a Notes client). This even applies when you load a server based NSF (hardly a good idea in XPiNC). This changes when you configure XPiNC to run on the server, then the applicationScope is for all users.
  • Since XPiNC applications load all Java classes from the NSF into the JEE server memory, its best to load them from a local NSF, even for applications that need to have current data for all users. Here XPages' ability to use data from a different database comes in handy and you would load your data NSF from the server - I'll prepare some code snippets for future posts
As usual YMMV

Posted by on 21 July 2013 | Comments (6) | categories: XPages

Comments

  1. posted by Sean Cull on Sunday 21 July 2013 AD:
    Stephan, this is really useful, thanks for sharing.
  2. posted by Mark Barton on Sunday 21 July 2013 AD:
    Stephan,

    The threaded stuff would be great. Would it work the same way on the server?

    I can't get the openntf threads sample to work on 9.

    I am trying to create a websocket server for push notifications.

    Mark
  3. posted by mark roden on Monday 22 July 2013 AD:
    Thanks for sharing Stephan - I expect this will become a well used reference.

    From our experience at PSC I would also add:

    xAgents run slower than on the web because every getNextEntry goes back to the server. Mitigate in R9 by using run on server option.

    Use firebug lite for debugging but if including in the final product remember to include the files in the db if you need it offline.

    XPiNC performance degrades very quickly as the number of DOM elements increases. Be careful if you are using external libraries which create a lot of extra code.

    OpenByReplicaId will open a local replica if the user has one and not the server copy - that can be really interesting especially in testing.

    I am sure there are more :)
  4. posted by Paul Withers on Monday 22 July 2013 AD:
    An excellent and very useful checklist. For getting the session in Java, how about ExtLibUtil.resolveVariable() and resolving "session"?

    The other gotcha is paths for images and other resources external to the NSF (e.g. View icons), which are different for XPiNC compared to web. For view icons, Extension Library has a new @Function, @ViewIconUrl. The source code will show the Java version.
  5. posted by Rami Jundi on Tuesday 23 July 2013 AD:
    Thanks a lot for sharing.

    We are starting my first XPiNC application for same client albeit a relatively simple application. Glad to know others are actually using XPinc inside of here.


  6. posted by Stephan H. Wissel on Tuesday 23 July 2013 AD:
    @All: Thx for stopping by

    @Mark Database.openByReplicaId(server, replicaid) can be steered to local or server, I think you mean providing a replicaId in a data source? I haven't been able to verify, but it either prefers the local or actually the top of the stack of your stacked icons on the workspace.
    And true: I try to run local as much as possible.

    @Paul: resolveVariable() also uses the Context which might or might not return null. Dependency injection seems more reliable