Mindoo Blog - Cutting edge technologies - About Java, Lotus Notes and iPhone

  • Bleedyellow.com has a new home

    Karsten Lehmann  November 11 2017 12:16:44
    It took some time and the domain transfer is not 100% complete, but bleedyellow.com is on it's way from René Winkelmeyer to Mindoo.

    Our blog is currently configured to be the default website on

    We do not have any plans yet for the domain, but did not want to let it expire. If you have any suggestions, feel free to comment.

    Life sign / Major update for Domino JNA on Github

    Karsten Lehmann  November 10 2017 17:25:35
    Wow - I haven't written a blog post in the last 9 months! It's just so much easier to write a Tweet than to produce long articles, when I split the week between three customers and my family with two children.

    Just wanted to let you know that we are alive and kicking and still doing very much Domino related work! :-)

    Technologies have as always shifted a bit. Most of the time we create pure JavaEE projects now for our customer web apps, developed in Eclipse and not Domino Designer (ok, using it to create lookup views, still working on that part ;-) ).
    A Maven build then collects all moving parts and generates an OSGi update site that can be deployed on the Domino server. So our NSFs contain no code and no further design elements except those lookup views.

    For the frontend, we are mostly using a mix of Bootstrap, React, jQuery and a lot of open source widgets and libraries that we find on the Internet. Some other areas of interest include using ES5/ES6 JavaScript features like async/await and as always exploring what other database systems have to offer.

    The backend of our apps is more and more powered by our Domino JNA project to get the most out of Domino. The project is now used in 7 of our customer web apps and services, of course running on production servers for months.

    Since my last post in January, a lot of work has been done to make the project more powerful and more robust.

    I am happy to announce that version 0.9.9 is now available on Maven Central and as an XPages Extension Library.

    Here are some of the new features:
    • APIs to convert a single richtext item or a whole document to HTML with access to embedded images - NotesNote.convertItemToHtml / NotesNote.convertNoteToHtml()
    • APIs to stop long running code, get progress information and replication progress/results - SignalHandlerUtil
    • APIs to read/write Notes.ini values - NotesIniUtils
    • Utility function to compare Notes names with wildcards (*/Company) - NotesNamingUtils.nameMatchesWildcard()
    • Support to pass open flags when opening a database, e.g. for cluster failover - OpenDatabase enum
    • Method to replicate a database with options and detailed replication stats - NotesDatabase.replicateWithServer()
    • Method NotesNote.setUNID() to change the UNID of a document
    • Utility class to get names of cluster members of a Domino server - ServerUtils

    Performance improvements:
    • Now reading view column names/sortings/formulas using C API in NotesCollection, not having to reopen the DB/View with legacy API (Notes.jar) anymore
    • Improved LMBCS string conversion performance (less copy operations for pure ASCII strings)

    Breaking changes:
    • Removed lotus.domino.Session argument from some of the NotesDatabase constructors (not needed anymore)
    • Using NoteClass enum instead of noteclass bitmask, e.g. for database searches

    I'd love to write more about all the features or product some slides and (re-)appear at conferences, but unfortunately time is very limited. So I see what I can do to at least produce more test cases or make the existing ones work.

    I should have a bit more time now, since there are not many prio 1 topics left on my list that I need to add to the project. :-)

    New APIs for Domino JNA project, now available for XPages development

    Karsten Lehmann  January 16 2017 08:21:26
    It took some time (mainly because I was very busy and my main use case for the project is not XPages), but now the Domino JNA project is available for XPages development.

    That means that there is an XPages Extensibility API plugin available in the project's release section on Github that can be installed both in Domino Designer and on the Domino R9 server to use the API in your own applications.

    After installation, the API classes are available in SSJS and Java code including API source code.
    Since they are integrated with the JSF lifecycle, memory management is automatically handled by the plugin. That means that code using the API does not have to be wrapped in NotesGC.runWithAutoGC() blocks to automatically recycle allocated C handles and memory after a HTTP request.

    If you want to build your own release of the project (or of your own fork), please take a look at the section "Using Domino JNA in XPages applications". The Maven build has been tested on macOS and Windows.

    New features

    Tons of new features have been added to the project during the last months. It's difficult to keep up with test cases and extend code documentation.

    Here are a few highlights:
    • new APIs to use native NSF transactions (atomically create/modify/delete multiple documents in a database, see the Transactions class for known issues/limitations)
    • new APIs to read the ECL for a specific user
    • API to let NSF quickly filter a number of documents with a formula (not just the whole database as in IBM's Java API): NotesIDTable.filter(NotesDatabase db, String formula)
    • support added to direct attachment streaming to quickly skip a number of bytes (can be used to implement partial downloads via Accept-Ranges HTTP header, restricted to uncompressed attachments)
    • APIs to read/write database options with more than 100 available option constants (IBM's Java API contains only 13 of them)
    • Reading selected view rows specified as an ID table now also works on remote servers (use NotesCollection.updateFilters() to push your SelectedList ID table changes to remote servers before reading data)
    • Performance enhancements when inserting many IDs to a NotesIDTable

    To achieve the new functionality, lots of undocumented C API methods have been used that IBM should really add to the public API:
    • NIFReadEntriesExt
    • NIFIsNoteInView
    • NIFIsUpdateInProgress
    • NIFGetIDTableExtended
    • NIFCollectionUpToDate
    • NIFUpdateFilters
    • NIFIsTimeVariantView
    • IDScanBack
    • IDInsertRange
    • IDTableDifferences
    • IDTableReplaceExtended
    • ECLGetListCapabilities
    • NSFSearchExtended3
    • NSFDbGetOptionsExt
    • NSFDbSetOptionsExt
    • NSFTransactionBegin
    • NSFTransactionCommit
    • NSFTransactionRollback
    • extended FIND_XXX flags e.g. FIND_CATEGORY_MATCH to look up category rows in views
    • more than 100 DBOPTBIT_XXX constants to read/write database options

    Please let me know if there are any problems using the API.

    My latest wish list for the Domino Java API

    Karsten Lehmann  November 3 2016 11:10:49
    Last week I sent an email with enhancement ideas for the Domino Java API to IBM development. Most of the stuff listed here (except new @-functions) can be implemented by wrapping existing C API functions or simple copy&paste of already existing code.
    We already did this using our Domino JNA project, but I thought it would be a good idea to add this functionality to the standard API and provide full platform support.

    I don't really have unrealistic expectations whether this will ever be added to the product, given the latest speed new features got in, but I haven't given up hope yet.

    I am posting this here in the blog in case it is interesting for anyone.

    1. ViewNavigator View.createViewNavForSelection(int[] noteIds)
    Filter a view navigator to only return entries with specified note ids, e.g. received via previous lookups.

    Using the C API, this can be done by opening the view with NIFOpenCollection and populating the ID table "rethSelectedList":

    STATUS LNPUBLIC NIFOpenCollection(
    NOTEID ViewNoteID,
    WORD OpenFlags,
    HANDLE hUnreadList,
    HCOLLECTION far *rethCollection,
    NOTEHANDLE far *rethViewNote,
    UNID far *retViewUNID,
    HANDLE far *rethCollapsedList,
    HANDLE far *rethSelectedList);

    To navigate the view, NIFReadEntries would be called with NAVIGATE_NEXT_SELECTED / NAVIGATE_PREV_SELECTED flag.

    2. int[] View.getAllIdsByKey(Object key, boolean exact)
    Convenience function to only read the note ids of view entries matching the lookup key for better performance (less data in the summary buffer returned from NIFReadEntries, so more rows read with one C API call).

    Using the C API, this can be done with NIFReadEntries calls where only READ_MASK_NOTEID is used as return data mask.

    3. View.getViewEntryByKeyWithOptions(Object startKey, int searchOptions)

    This function is already available in the XPages runtime and would need to be copied over to the Domino Java API. The AbstractDominoViewPickerData class in the Extension Library uses it to locate view entries with a search key greater or equal "X":

    ViewEntry ve=null;
    String startKey = options.getStartKey();
    if(startKey!=null) {
            int searchOptions = DominoUtils.FIND_GREATER_THAN|DominoUtils.FIND_EQUAL|DominoUtils.FIND_PARTIAL|DominoUtils.FIND_CASE_INSENSITIVE;
            ve = DominoUtils.getViewEntryByKeyWithOptions(view, startKey, searchOptions);
    } else {

    So this gives us a way to do inequality searches for Strings and Numbers in views and decide if keys need to be case sensitive.

    These functions can be combined to implement powerful view lookups, e.g. filter view entries by multiple column values and sort the result dynamically.

    Here is an example:

    View myView = db.getView("MyView");

    //resort view by first sort column
    myView.resortView("firstsortcolumn", true);

    //get matches for first search key
    int[] noteIdsFirstKey = myView.getAllIdsByKey(firstSearchKey, false);

    //resort view by second sort column
    myView.resortView("secondsortcolumn", true);

    //get matches for second search key
    int[] noteIdsSecondKey = myView.getAllIdsByKey(secondSearchKey, false);

    //intersect both note ids lists: list1 AND list2 using some tool class
    int[] noteIdsFirstAndSecondKey = IDUtil.and(noteIdsFirstKey, noteIdsSecondKey);

    //resort view by third sort column
    myView.resortView("thirdsortcolumn", true);

    //get matches for third search key
    int noteIdsThirdKey = myView.getAllIdsByKey(thirdSearchKey, false);

    //merge intersection of first/second key matches with third: (list1 AND list2) OR list3
    int[] noteIdsFirstAndSecondKeyOrThirdKey = IDUtil.or(noteIdsFirstAndSecondKey, noteIdsThirdKey);

    //and now we produce the final sorting:
    myView.resortView("finalsortcolumn", true);

    //we would need this API to reduce the view to entries with specified note ids with max performance (let NIF skip irrelevant collection entries for us)
    ViewNavigator nav = myView.createViewNavForSelection(noteIdsFirstAndSecondKeyOrThirdKey);
    nav.setCacheGuidance(400, ViewNavigator.VN_CACHEGUIDANCE_READSELECTIVE);

    //skip some view entries to support paging

    //write requested page data (start/count) in JSON format:
    ViewEntry veCurrent = nav.getCurrent();
    while (veCurrent!=null && count>0) {
            if (veCurrent.isValid()) {

            //read next view entry matching our selection list
            ViewEntry veNext = nav.getNext();
            veCurrent = veNext;

    This view lookup technique is already being used by us at a big Domino customer in Germany using C calls (Domino JNA project), but platform support is currently limited to those supported by JNA and this should really be part of the standard API.

    Other useful APIs to add:

    4. @ModifiedInThisFile / @AddedToThisFile (posted in the Design Partner Forum in January 2014)
    Two new @-functions to sort view entries by the date their corresponding documents got added to/modified in the database. Required for synchronization of Domino data with external databases. Using @modified instead would not cover changes coming in via replication that happened before the cutoff date for the current data synchronization. Response to DP forum article in 2014 said the feature will be in 9.0.2, so it seems to be already implemented and would need to be added to a feature pack.

    5. NoteCollection.add(int[] noteIds)
    Fast bulk add function to add many note ids at once to a NoteCollection for better performance.

    6. int[] DocumentCollection.getNoteIDs()
    Fast method to get all note ids stored in a DocumentCollection as an int array. If DocumentCollection is sorted internally, the array should have the same sorting.
    Could be used in combination with "DocumentCollection Database.FTSearch()" to quickly get a note id list of documents matching a fulltext search.

    7. int[] Database.getDeletedDocuments(DateTime since, int noteClass)
    Method to get a list of note ids for documents deleted since the specified datetime. C API function NSFDbGetModifiedNoteTable already returns deleted notes ORed with RRV_DELETED flag. So this function would simply copy this list to an int array.
    Already available method Database.getModifiedDocuments(DateTime since, int noteClass) is no help because it filters out deleted documents.

    Use case is data synchronisation between Domino databases and with external systems.

    Big update for Domino JNA project on Github

    Karsten Lehmann  July 11 2016 23:33:05
    Last weekend, I committed a big update for the

    Here is what's new:

    Note (Document) APIs
    The last weeks since creating the project, I added basic APIs to work with database notes (documents). The main focus was to be able to read the classic note item value types, e.g. String, Number and Date/Time with single or multiple values per item, handle a few rarely known edge cases (e.g. multiline text values that Domino stores with delimiter \0 between the lines instead of platform dependent \n or \r\n), do proper LMBCS/Unicode conversion routines for special characters like Umlauts and provide access to item metadata like the sequence number or the last modified date of an item.

    While reading the note flag documentation, I discovered NOTE_FLAG_READONLY, which Domino automatically adds to the note info area. This note flag can be used to quickly check whether the current Domino user has edit access to a document without all the work of traversing all author items and manually compare the values to @UserNamesList. So that's what is being queried now when you call NotesNote.isReadOnly().

    Attachment streaming
    Another thing I added was support for note attachment streaming. You probably know that IBM's (poor) implementation of EmbeddedObject.getInputStream() internally first extracts the file to a temp directory and then returns an InputStream to this temporary file. Depending on the file size, that may ruin application performance and fill disk space. So the Domino JNA way of reading attachment is to manually decode the $File items and read the file content in small chunks of 16K, the buffer size of the C function to read attachment data.

    The Domino C API provides some easy methods to set item values for selected data types (e.g. single values for text, number and Date/Time). I added them to the Domino JNA as well, but there is still work to do to write multiple values.

    A few other things that are new:

    User spoofing - reader items on steroids
    A NAMES_LIST data structure is what Domino returns when you call NSFBuildNamesList with a Domino username. This NAMES_LIST contains all name variants/wildcards and groups/nested groups on the server for the specified username.
    It is passed as a parameter when you open a database or a view so that Domino can compute document visibility (reader items) and write access rights.

    Ever since writing the code to decode this simple memory data structure, I was asking myself whether it can be built programatically, because it's just the number of names and the null terminated LMBCS encoded list of names.

    And since I need that functionality for an upcoming customer project (Google+ like application with very flexible read access rights for postings), I tried it and it worked like a charm. :-)

    So now you can build your own Domino users at runtime that do not have to be in a Domino directory. Just pass a Java List with name variants in the NotesDatabase constructor and all operations are executed on behalf of that user.

    Unification of view column value reading
    Domino has two ways to read view column data: READ_MASK_SUMMARY which returns programmatic column names and their values in the summary buffer and READ_MASK_SUMMARYVALUES that just returns the column values.

    The latter leaves more space in the summary buffer for data, as the column names never change between view entries. Unfortunately, one new optimized lookup call that IBM added in R9 to atomically look up a key and start reading values, currently only works with READ_MASK_SUMMARY.

    I don't think that developers should care about this difference, so I now handle all that internally in the NotesViewEntryData object and you simply call NotesViewEntryData.get("Firstname") to read a column value.

    Here is a test case to see some sample code for view data reading (the API has changed compared to the initial release).

    Performance optimizations
    I did some profiler sessions and optimized the API for performance. The main optimization was to add an LMBCS string decoder cache that reduces the string conversion operations and to lazily convert strings when they are first needed (e.g. when reading only a few view column values).

    The code on Github was tested on Mac 64 bit and Windows 32 bit clients so far. The next days, I will do further tests with Windows 64 bit servers since we are using the API in multiple customer projects.

    The repository contains various test cases to get started.

    New on Github: Domino JNA - Cross-platform access to IBM Notes/Domino C API methods from Java

    Karsten Lehmann  April 8 2016 19:11:37
    I would like to introduce you to a pet project that I have been working on for the last months:

    Domino JNA -

    Cross-platform access to IBM Notes/Domino C API methods from Java

    As you might have already read in this blog in the past, we have been playing with the Domino C API for some time now and found out that you can speed up view reading dramatically when you talk directly to the C API instead of using IBM's Java classes.

    The C API also provides lots of other functionality for which no Java or LotusScript methods exist yet.

    It has always been possible to build your own DLL with C code calling Domino methods and use it via Java's Native Interface (JNI). We did this in applications developed for customers and partners, e.g. to render Richtext to HTML format, directly stream attachments (IBM's API first stores files temporarily to disk, not a good idea) or replicate databases with a progress callback.

    But the problem has always been that the native code has to be compiled for each platform.

    JNA to the rescue

    Java Native Access is a project that gives Java developers access to native shared libraries without creating their own DLL or library file.
    You simply call Java methods and make sure that your method arguments match those on the C side.

    So I created my first small sample application months ago calling some Domino code, found out that it worked in Windows 32 bit, found out that I had to change something for Windows 64 bit to get more than just crashes, found out that the whole stuff did nothing than crashing in Linux systems, read lots of Domino C API documentation, build testcases, documented the API methods....

    ...and months later I uploaded the whole stuff to Github. :-)

    Here it is:

    An API is nothing without documentation and sample code. And I am working on that, but this takes time. There are already a few testcases available for the view functions.

    Since talking to low level functions is not what everybody likes, I am also creating helper functions that make working with the API easier. I rename stuff, I add stuff and hide stuff. So please be aware that this project is definitely not finish and will change, but I want to share the code today because it already creates value and works quite well for us.

    What does it do already?

    Here are some of the things you can do with the first version:
    • view lookups using different key formats (e.g. strings, numbers, dates, date ranges) and equality/inequality searches (e.g. find less or greater than a search key)
    • decodes all available types of view column data types (string, string list, number, number list, datetime, datetime list) and row data (e.g. just note id, UNID, counts, unread flag etc.)
    • read view data as another Notes user
    • separation of Notes views and their data into multiple databases (like programmatically creating private views and keeping them up-to-date incrementally)
    • special optimized functions for local databases (e.g. when API is running on the server and databases are on the server as well):
      • dynamic filtering of view rows based on a Note id list with paging support (this really rocks!)
      • reading categorized views with expanded/collapsed entries and min/max level
    • read design collection with design elements in a database
    • support for view resorting (changing the collation in C API terms)
    • fulltext index creation with all available options
    • supports incremental synchronization of Domino databases
      by reading noteid lists of modified and deleted documents (IBM's Java API does not return ids of deleted docs)
    • clearing the replication history
    • compute @Usernameslist values for any Notes user


    The Github repository contains a Maven project with the API code and setup instructions. All is available under Apache 2.0 license.

    As next step, I want to add the code to an XPages Extension Library plugin to make it easier to use from XPages code.

    Please provide feedback if the project is working for you.

    Updated on OpenNTF: Release 1.1 of Open Eclipse Update Site with Mac 64 Bit Client support and other cool stuff

    Karsten Lehmann  March 4 2016 01:23:48
    I have updated the OpenNTF project "Open Eclipse Update Site" with release version 1.1 and added the following useful features:
    • added support for the Mac Notes Client with 64 bit
    • new view action to extract selected features as an update site to disk (also available in headless mode via Java agents “(API)” and “(Java-API)“)
    • new view actions to install/uninstall selected features via rcplauncher based deployment, which is used by software distribution systems and should also work on clients where widget deployment is blocked via policy
    • new database icon

    Update: I had to renew the download package on 4th March 2016 and fixed/added the following items:
    • fixed bug where the rcplauncher deployment log could not be written for Notes data directories containing whitespaces
    • added alternative UI which can be activated via role [WidgetUILaunch]. Setting the role displays an install wizard on database open instead of the classic Update Site UI views. The wizard guides the user through a a widget (extension.xml) based plugin installation

    Image:Updated on OpenNTF: Release 1.1 of Open Eclipse Update Site with Mac 64 Bit Client support and other cool stuff

    Image:Updated on OpenNTF: Release 1.1 of Open Eclipse Update Site with Mac 64 Bit Client support and other cool stuff

    Image:Updated on OpenNTF: Release 1.1 of Open Eclipse Update Site with Mac 64 Bit Client support and other cool stuff

    Image:Updated on OpenNTF: Release 1.1 of Open Eclipse Update Site with Mac 64 Bit Client support and other cool stuff

    Notes 9.0.1 64 bit for Mac OS X 10.11 El Capitan now available - warning our customers NOT to update for 30+ days!

    Karsten Lehmann  September 29 2015 10:30:06
    One day before the general availability of Mac OS X 10.11 (El Capitan), IBM released an update for their IBM Notes Client 9.0.1 with 64 bit support:

    Previous versions were using Java 1.6 32 Bit under the hood, which was maintained by Apple for the last 7 years. Since Apple dropped support for Java 1.6 in OS X 10.11, IBM had to update their IBM Mac Notes Client to work with newer JVMs (1.7 and 1.8 are maintained by Oracle and are only available with 64 Bit).

    Unfortunately we now have to warn our customers not to update their OS X version and Notes environment for at least 30 days.

    The reason is that IBM will release the C API toolkit 30 days after the Notes Client availability, as mentioned in this Q&A page:

    NOTE: If you are running applications that make use of the Notes C API Toolkit, then you must recompile those application with the new 64-bit Mac API Toolkit, which is expected to be available approximately 30 days after Notes 9.0.1 64-bit ships. This technote will be updated when the C API Toolkit is available.

    Since the applications that we maintain on OS X for customers (such as MindPlan or individual Notes Client add ons) contain native code, they need to be recompiled for 64 Bit, otherwise they will no longer work after the OS X update.

    We are asking IBM dev for a beta version of the C API toolkit to speed up this application update process, but have not received a positive response yet.

    BTW: It looks like there are no plans to move the Windows Notes Client to 64 bit. However, for Notes 9.0.2 it is planned to ship it with IBM's JVM version 1.8. IBM will announce their release plan for 9.0.2 in January at IBM Connect.

    Looks like there is Java 6 support in El Capitan and the old 32 bit Notes Client is still working. See the comments for details.

    New C API method NIFFindByKeyExtended2 in Domino 9.0 improves view lookups

    Karsten Lehmann  March 6 2015 14:48:54
    Once again I am digging into the Notes/Domino C API to implement fast and powerful view lookups. What caused it this time was a customer requirement for "Notes Client style keyboard navigation" in web views, meaning that you type a character, press enter and the cursor position should be moved to the relevant area of the view (e.g. where the content in the first sorted view column is greater or equal letter "L").
    Using standard Java APIs for this purpose (ViewNavigator.getNextSibling(), until we find a greater column value) was much to slow, since the view had about 40,000 entries in the top level.

    We did a lot of experiments in this area in the past (1, 2) writing custom DLLs for Windows/.so libraries for Linux, but this time my plan was to use Java Native Access (JNA) from an Eclipse plugin to build the code more quickly.

    I will try to publish some tool libraries in this area in the near future (as always I am very busy...). But in this post, I just want to document a method that is available in the C API since 9.0 and has not been documented in the C API tookit since then.

    The method is called NIFFindByKeyExtended2 (the C API release notes say NIFFindByKeyExtented2) and is only mentioned a few times on the web, e.g. in Scott Souder's C API toolkit announcement post.

    Here is the method signature:

    STATUS far PASCAL NIFFindByKeyExtended2 (HCOLLECTION hCollection,
                    void *KeyBuffer, DWORD FindFlags,
                    DWORD ReturnFlags,
                    COLLECTIONPOSITION *retIndexPos,
                    DWORD *retNumMatches,
                    WORD *retSignalFlags,
                    DHANDLE *rethBuffer,
                    DWORD *retSequence)

    I asked IBM dev about the method and got the information that it combines NIFFindByKey and NIFReadEntries in one call. In earlier Domino releases, you had to use NIFFindByKey to get the view entry position for a search key and then use NIFReadEntries to read the view data. Unfortunately the view could have changed in the meantime so that the postion could point to a different location.

    This is not the case for NIFFindByKeyExtended2, which is executed atomically with a read lock on the view. For remote calls, the returned data can have up to 64 KB of content. If more data is required, subsequent calls to NIFReadEntries have to be made. For local calls, the main use case for XPages apps, the buffer has no limit.

    Here is the complete method documentation:

    /*        NIFFindByKeyExtended2 - Lookup index entry by "key"
    *        Given a "key" buffer in the standard format of a summary buffer,
    *        locate the entry which matches the given key(s).  Supply as many
    *        "key" summary items as required to correspond to the way the index
    *        collates, in order to uniquely find an entry.
    *        If multiple index entries match the specified key (especially if
    *        not enough key items were specified), then the index position of
    *        the FIRST matching entry is returned ("first" is defined by the
    *        entry which collates before all others in the collated index).
    *        Note that the more explicitly an entry can be specified (by
    *        specifying as many keys as possible), then the faster the lookup
    *        can be performed, since the "key" lookup is very fast, but a
    *        sequential search is performed to locate the "first" entry when
    *        multiple entries match.
    *        This routine can only be used when dealing with notes that do not
    *        have multiple permutations, and cannot be used to locate response
    *        notes.
    * Inputs:
    *        hCollection = Handle of per-user collection context
    *        KeyBuffer = Address of "key" summary buffer
    *        FindFlags = Find flags word (FIND_xxx)
    *        ReturnMask = Mask specifying what information is to be returned on each entry
    *                                        (READ_MASK_xxx).  Information is always returned in the
    *                                        order of the bits which are 1, from bit 0 to bit 15.
    *        retIndexPos = Place to receive index position of (first) matching entry
    *        retNumMatches = Place to receive # entries which match (optional)
    *        retSignalFlags = Place to receive extra sharing warning flags (optional)
    * Outputs:
    *        (Routine) = Error status (ERR_NOT_FOUND if none found at all)
    *        *retIndexPos = Index position of (first) matching index entry.
    *        *retNumMatches = # matching entries
    *        *rethBuffer = Handle of return buffer (may be NULLHANDLE)
    *        *retBufferLength = Length of return buffer
    *        *retSequence = Index Modified Sequence number

    Based on searches on the internet, there also seems to be NIFFindByKeyExtended3, but I don't have information about parameters and purpose for this method yet.

    Tools we use to build web apps

    Karsten Lehmann  September 21 2014 21:50:48
    In a recent comment in this blog, Andrew Magerman asked what frameworks I use to build web applications and whether we have looked into Angular. Since the answer got too long for a simple comment and might be interesting for others, I created this blog article.

    Server side
    I am using my own regexp based templating system, which simply fills some placeholders in static HTML and JS files and sends them to the browser, e.g. to compute URLs, to insert translated phrases and include content of other template files. I don't need much flexibility for this template system, because all dynamic stuff is created in the browser anyway.

    Data is provided via custom REST services implemented in Java that offer CRUD operations. In many cases, the server side application code uses framework classes from OSGi plugins that build a common layer shared between multiple web applications.

    Frontend stuff
    For the frontend, I use Bootstrap to build responsive user interfaces that work on phones, tables and desktop browsers. I use jQuery, lots of helper projects like bootstrap datepicker and timepicker, select2 for flexible comboboxes, velocity.js for animations, Asynquence to work with callbacks and other libraries that I tweeted about in the past.

    To wire them together I use require.js, which gives me a clean dependency resolution.

    React based UI rendering
    For more and more UI components, I use React for the rendering and their flux application architecture.
    I especially like their approach to reduce DOM changes by comparing old and new in a virtual DOM tree in memory when data changes.

    Another advantage of React.JS is that the initial UI code can be precomputed on the server side to improve SEO ranking (see this article).

    Normally, this is done in code running in a Node.JS server.

    For Java based server environments like IBM Domino, we have code to do this using the JavaScript engine of the JVM and as an alternative (with better performance thanks to Node's V8 JavaScript engine) by leveraging an external Node.JS process on the same or a different machine.

    We haven't used Angular in real-life projects yet. Looking at the documentation, it feels as if they over-standardized web application development a bit, making it more difficult than necessary to get started.

    What concerns me is that their templating system does not seem to optimize DOM operations as good as React does. In the browser, it's all about responsiveness and performance.

    What I don't use
    Personally I prefer not to use JSF components or similar concepts for the web UI. I don't like to depend on a server state and don't like to have too much communication between frontend and backend.

    Instead I like to have most of the UI code in the browser so that the app is responsive even with bad network coverage. In addition, I can optimize DOM rendering and have more ways to play with animations and transitions.

    Communication with the server side is done through REST APIs that can also be reused to test functionality, automate tasks or for automatic data imports/updates.

    You may have noticed that not much of my way to develop web applications requires a Domino server.
    Having Domino on the server is a great thing, as it includes many services in one consistent platform, like the document database, fulltext search, directory services, replication and a close integration of application code and the mail server.

    But there's more than one way to skin a cat. We have prototypes in the lab that don't have any Domino dependencies.

    Since we like document databases combined with replication, we have been playing with the CouchDB eco system for some time:
    the Apache CouchDB project that is currently merged with the Cloudant database and the rcouch project as well as its mobile version Couchbase Lite and PouchDB in the browser.

    Combined with an OSGi based server platform, that looks like a powerful and extensible app dev environment.