Testing XPages (2): BrowserMob Proxy

When testing XPages or other web applications, you may want to have more control about the requests and responses during the JUnit testing. For example, if you want to test if a specific HTTP header exists in the response, or if it is required to add some HTTP headers to the request. But you cannot doe this out of the box with Selenium. Instead, you have to add a proxy to the Firefox controller, which then gives you a handle to the HTTP data and allows you to control the flow.

An good solution for this is BrowserMob Proxy, which can be used by adding the required dependency to your Maven pom.xml:


[This is version 2.0.0, the latest stable version]

The proxy runs locally on the specified port as soon the JUnit test starts and ends automatically after finishing the tests.  In order to accomplish this, the setUp method has to be modified:

// start the proxy (listens on port 4444)
server = new ProxyServer(4444);

// get the Selenium proxy object
Proxy proxy = server.seleniumProxy();

// configure it as a desired capability
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.PROXY, proxy);

Now, the proxy setting must be added to the Firefox driver:

driver = new FirefoxDriver(capabilities);

In the test class, three global variables must be defined; these are giving you access to the proxy server and latest the request and response during testing:

private ProxyServer server;
private BrowserMobHttpResponse httpResponse;
private BrowserMobHttpRequest httpRequest;

With the help of a ResponseInterceptor, the httpResponse property is always filled with the latest response. To initialize it, an anonymous class in the setUp method has to be created:

// add a response interceptor
ResponseInterceptor interceptor = new ResponseInterceptor() {
    public void process(BrowserMobHttpResponse response, Har har) {
          httpResponse = response;

// add the interceptor to the server

For the RequestInterceptor it is the same procedure:

// add a request interceptor
RequestInterceptor requestInterceptor = new RequestInterceptor() {
    public void process(BrowserMobHttpRequest request, Har har) {
       httpRequest = request;


Now, it is possible to use it in a JUnit test:

public void testDemo() throws Exception {
    // add a request header
    server.addHeader("X-FOO", "BAR");
    // load the page

    HttpResponse httpRawResponse = httpResponse.getRawResponse();
    assertTrue("HTTP/1.1 200 OK".equals(httpRawResponse.getStatusLine()
    assertTrue( "Lotus-Domino".equals( httpResponse.getHeader("Server")) );

The Browsermob-proxy has a lot of additional features: You can modify the allowed speed for up- and downstreams, use basic authentication, upload files, etc.

Veröffentlicht unter Java, Web, XPages | Verschlagwortet mit , , , , , , , | Hinterlasse einen Kommentar

Testing XPages

When testing XPages with Selenium, you can easily pre-generate the JUnit test code with the browser plugin. But when you then change the structure of the XPage (f.e. by moving the components from an XPage to a custom control), all the IDs of the JUnit test will not work anymore.

That’s why it is better to use CSS selectors to access the generated fields:


With the selector „id*=’idOfTheComponent'“ you can access the elements by their component id, idependently of their full generated client id.

Here is an example with a small XPage with a radio group and a listbox:


A simple XPage to test (SimpleDemo.xsp)

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

        <xp:selectItem itemLabel="1" itemValue="1" />
        <xp:selectItem itemLabel="2" itemValue="2" />

    <xp:listBox id="listBoxSimpleDemo" multiple="true">
        <xp:selectItem itemLabel="1" itemValue="1" />
        <xp:selectItem itemLabel="2" itemValue="2" />
        <xp:selectItem itemLabel="3" itemValue="3" />

 The JUnit Test

package ch.hasselba.xpages.test.seleniumdemo;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;

public class SimpleDemo {

	private WebDriver driver;
	private String baseUrl = "";
	private StringBuffer verificationErrors = new StringBuffer();

	public void setUp() throws Exception {
		driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

	public void tearDown() throws Exception {
		String verificationErrorString = verificationErrors.toString();
		if (!"".equals(verificationErrorString)) {

	public void testDemo() throws Exception {
		List elemRadio = driver.findElements(By

		Select select = new Select(driver.findElement(By
		List listSelect = select.getOptions();
		for (WebElement listElem : listSelect) {


	public void reloadPage() {

The Maven pom.xml file

<project xmlns="http://maven.apache.org/POM/4.0.0"



Veröffentlicht unter Allgemein, Java, Web, XPages | Verschlagwortet mit , , , , , , , | 1 Kommentar

Android Development

While I had a lot of work to do in my daily business, I was still able to complete five of six MOOCs about Android development during the last monthes. The courses were very cool, especially the ones about Concurrency and Security.

Topics covered during the MOOCs:

  • Screen configurations and sizes
  • Activity Class, Intents and Permission, Fragments
  • Designing user interfaces
  • Notifying users about important events
  • Handling concurrency
  • Acquiring data over the network
  • Leveraging multimedia and graphics
  • Incorporating touch and gestures
  • Working with sensors
  • Android Layers
  • Java Threading Mechanisms
  • Java Built-in Synchronization Mechanisms
  • Android Concurrency Framework Classes
  • Android Looper
  • Android Handler and HaMeR Framework
  •  The AsyncTask Framework
  • Blackbox and Whitebox Frameworks with AsyncTask
  • Monitor Object Pattern
  • Thread-Specific Storage Pattern
  • Command Processor Pattern
  • Active Object Pattern
  • Proxy Pattern
  • Broker Pattern
  • Half-Sync/Half-Async Pattern
  • Started and Bound Services
  • Activity and Service Communication
  • Service to Activity Communication Using Android Messenger
  • Android IntentService
  • Programming Bound Services with Messengers
  • The Android Interface Definition Language (AIDL)
  • Privilege Escalation Concepts
  • Spring, Configuration Annotations, Dependency Injection and Spring Security
  • OAuth
  • Retrofit Client
  • Android Content Providers and Content Resolvers
  • SQLite
  • and much more…

Thanks to Dr. Adam Porter, Dr. Douglas C. Schmidt and Dr. Jules White. It was very interesting and I learned a lot.

Coursera androidpart1 2015

Coursera androidpart2 2015

Coursera posacommunication 2015

Coursera posaconcurrency 2015

Coursera mobilecloudsecurity 2015

Veröffentlicht unter Android | Verschlagwortet mit , | 1 Kommentar

XPages: A ClientSide State

I have created a ClientSide State for XPages, which allows horizontal scaling of XPages applications with a single click.

After installing the OSGi Plugin on the servers and the DDE, you can activate it with a single click:

2015-09-13 20_41_02-XPage Properties Editor - ClientStateDemo - IBM Domino Designer

Then, the State of the XPages application view is stored on client side (in the field „$$clientstate„), and not on the server anymore. The State is AES-128 encrypted and uses some random bytes for a higher security.

2015-09-13 20_52_11-Quelltext von_ http___localhost_ClientStateDemo.nsf_Test.xsp

You can find the code on GitHub.


Parts of the code are shamelessly stolen from Jesse.

Veröffentlicht unter OSGi, Server, XPages | Verschlagwortet mit , , , | 5 Kommentare

The XPages EL Directory

I am currently working on an overview of available objects and properties for XPages Expression Language. A first incomplete and horrible designed version can be found here.


Veröffentlicht unter Expression Language, XPages | Verschlagwortet mit , , | 2 Kommentare

XPages: SSJS, EL and Bindings

Because of reasons you should already know I avoid the use of SSJS in my XPages applications, but there are still some parts which can be easy realized in SSJS, but with EL only with a lot of effort. One of this things is accessing properties of a component which has only a getter or a setter – this will not work when using a binding.

Let’s look for example at a repeat control which is bound to the variable repeat. It can be easily accessed everywhere in SSJS, EL or Java, and it is much faster than searching the component in the tree. Here it is accessed in a label:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">


But this will lead into an error, because the XspDataIterator component has only a getter method for the rowCount property, not a corresponding setter.

2015-07-01 23_11_16-Runtime Error

When changing the code to a SSJS method call, it works without any problems:


The reason for this behaviour can be found deep down in the underlying JSF classes: The BeanInfoManager ignores all methods without a „valid“ getter/setter methods pair during the inspection of a class, and doesn’t add it to the available properties for the PropertyResover. The rows property for example has a pair of those methods, that’s why this works without any problem:



Veröffentlicht unter Allgemein, JSF, XPages | Verschlagwortet mit , , , | Hinterlasse einen Kommentar

XPages: An optimized JavaScript Resource Renderer

Ferry Kranenburg created a nice hack to solve the AMD loader problem with XPages and Dojo, and because of the missing ability to add a resource to the bottom of an XPage by a property, I have created a new JavaScriptRenderer which allows to control where a CSJS script will be rendered.

The renderer has multiple options:

  • NORMAL – handles the CSJS resource as always
  • ASYNC – loads the script in an asynchronous way (with an own script tag)
  • NOAMD – adds the no amd scripts around the resource
  • NORMAL_BOTTOM – adds the script at the bottom of the <body> tag
  • ASYNC_BOTTOM – async, but at the end of the generated HTML page
  • NOAMD_BOTTOM – at the end, with the surrounding no amd scripts

To use the normal mode, you don’t have to change you resource definition. If you want to use the other modes, you have to change the content type of the resource with one of the entries in the list above. This for example would add a script block to the end of the page, including the non amd script blocks around it:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
        <xp:script clientSide="true" type="NOAMD_BOTTOM">
            <xp:this.contents><![CDATA[alert("Hello World!");]]></xp:this.contents>

2015-06-21 11_04_09

Here is the code for the resource renderer:

package ch.hasselba.xpages;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import com.ibm.xsp.component.UIViewRootEx;
import com.ibm.xsp.renderkit.html_basic.ScriptResourceRenderer;
import com.ibm.xsp.resource.Resource;
import com.ibm.xsp.resource.ScriptResource;
import com.ibm.xsp.util.JSUtil;

public class OptimizedScriptResourceRenderer extends ScriptResourceRenderer {
    private static final String TYPE = "type";
    private static final String SCRIPT = "script";
    private static final String CSJSTYPE = "text/javascript";
    private boolean isBottom = false;
    private static enum Mode {

    public void encodeResourceAtBottom(FacesContext fc,
            UIComponent uiComponent, Resource resource) throws IOException {
        isBottom = true;
        encodeResource(fc, uiComponent, resource);
        isBottom = false;

    public void encodeResource(FacesContext fc, UIComponent uiComponent,
            Resource resource) throws IOException {

        ScriptResource scriptResource = (ScriptResource) resource;
        ResponseWriter rw = fc.getResponseWriter();
        String type = scriptResource.getType();
        String charset = scriptResource.getCharset();
        String src = scriptResource.getSrc();

        Mode mode = Mode.NORMAL;
            mode = Mode.valueOf( type );
        }catch(Exception e){};

        if (mode == Mode.NORMAL || mode == Mode.NORMAL_BOTTOM ) {
            normalBottomJSRenderer( fc, uiComponent, scriptResource, (mode == Mode.NORMAL_BOTTOM), type );
        } else {
            if (mode == Mode.ASYNC || mode == Mode.ASYNC_BOTTOM) {
                asyncJSRenderer(fc, uiComponent, scriptResource, (mode == Mode.ASYNC_BOTTOM), rw, type,
                        charset, src );
            }else if (mode == Mode.NOAMD || mode == Mode.NOAMD_BOTTOM ) {
                noAMDJSRenderer(fc, uiComponent, scriptResource, (mode == Mode.NOAMD_BOTTOM) , rw, 
                        type, charset, src);



    private void normalBottomJSRenderer(FacesContext fc,UIComponent uiComponent,
            ScriptResource scriptResource, final boolean addToBottom, final String type ) throws IOException {
        if( addToBottom && !isBottom )
        super.encodeResource(fc, uiComponent, scriptResource);
    private void asyncJSRenderer(FacesContext fc,
            UIComponent uiComponent, ScriptResource scriptResource, 
             final boolean addToBottom, ResponseWriter rw, final String type, final String charset,
            final String src) throws IOException {
        if( addToBottom && !isBottom )
        Map<String, String> attrs = null;
        String key = null;
        String value = null;
        String id = "";

        if (scriptResource.getContents() == null) {
            attrs = scriptResource.getAttributes();
            if (!attrs.isEmpty()) {
                StringBuilder strBuilder = new StringBuilder(124);
                for (Iterator<String> it = attrs.keySet().iterator(); it
                        .hasNext();) {
                    key = it.next();
                    value = attrs.get(key);
                id = strBuilder.toString();

            // check if already added
            UIViewRootEx view = (UIViewRootEx) fc.getViewRoot();

            String resId = "resource_" + ScriptResource.class.getName() + src
                    + '|' + type + '|' + charset + id;
            if (view.hasEncodeProperty(resId)) {
            view.putEncodeProperty(resId, Boolean.TRUE);

        if (!scriptResource.isClientSide()) {

        rw.startElement(SCRIPT, uiComponent);
        rw.write("var s = document.createElement('" + SCRIPT + "');");
        rw.write("s.src = '" + src + "';");
        rw.write("s.async = true;");

    private void noAMDJSRenderer(FacesContext fc,
             UIComponent uiComponent,ScriptResource scriptResource,
            final boolean addToBottom, ResponseWriter rw, final String type, final String charset,
            final String src ) throws IOException {
        if( addToBottom && !isBottom )

        // write the "disable AMD" script
        rw.startElement(SCRIPT, uiComponent);
        rw.writeAttribute(TYPE, CSJSTYPE, TYPE);
                        "'function'==typeof define&&define.amd&&'dojotoolkit.org'==define.amd.vendor&&(define._amd=define.amd,delete define.amd);",

        // write the normal CSJS
        super.encodeResource(fc, uiComponent, scriptResource);
        // write the "reenable AMD" script
        rw.startElement(SCRIPT, uiComponent);
        rw.writeAttribute(TYPE, CSJSTYPE, TYPE);
                        "'function'==typeof define&&define._amd&&(define.amd=define._amd,delete define._amd);",


The ViewRenderer must also be modified, otherwise it is not possible to add the resources at the bottom of the <body> tag:

package ch.hasselba.xpages;

import java.io.IOException;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

import com.ibm.xsp.component.UIViewRootEx;
import com.ibm.xsp.render.ResourceRenderer;
import com.ibm.xsp.renderkit.html_basic.ViewRootRendererEx2;
import com.ibm.xsp.resource.Resource;
import com.ibm.xsp.resource.ScriptResource;
import com.ibm.xsp.util.FacesUtil;

public class ViewRootRendererEx3 extends ViewRootRendererEx2 {

    protected void encodeHtmlEnd(UIViewRootEx uiRoot, ResponseWriter rw)
            throws IOException {
        FacesContext fc = FacesContext.getCurrentInstance();

        List<Resource> resources = uiRoot.getResources();
        for (Resource r : resources) {
            if (r instanceof ScriptResource) {
                ScriptResource scriptRes = (ScriptResource) r;
                if (scriptRes.isRendered()) {
                    Renderer renderer = FacesUtil.getRenderer(fc, scriptRes.getFamily(), scriptRes.getRendererType());
                    ResourceRenderer resRenderer = (ResourceRenderer) FacesUtil.getRendererAs(renderer, ResourceRenderer.class);
                    if( resRenderer instanceof OptimizedScriptResourceRenderer ){
                        ((OptimizedScriptResourceRenderer) resRenderer).encodeResourceAtBottom(fc, uiRoot, r);



To activate the new renderes, you have to add them to the faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>

Needless to say that this works in Themes too.

Veröffentlicht unter Java, JSF, XPages | Verschlagwortet mit , , , , | 8 Kommentare


Just a reminder for myself: To use a CDN for XPage resources, you can add a leading slash to the xsp.application.context.proxy property.


2015-06-17 10_52_08-view-source


Veröffentlicht unter Performance, Web, XPages | Verschlagwortet mit , , , , | 2 Kommentare

XPages: Running Google’s Chrome V8 Javascript Engine (2)

A while ago I tried to run Google’s V8 Javascript engine on top of XPages, and today I found the reason why my server crashed after the first click: I have tried to load the engine only once (statically), and that killed Domino completly.

Today I moved the code back into the processAction method, and now it works without problems.

package ch.hasselba.xpages.jav8;

import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class JAV8Test implements javax.faces.event.ActionListener {

    public void processAction(ActionEvent actionEvent)
            throws AbortProcessingException {

        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("jav8");

        try {
            engine.eval("var i=1+1;");
            System.out.println("i = " + engine.get("i"));
        } catch (ScriptException ex) {
Veröffentlicht unter ServerSide JavaScript, XPages | Verschlagwortet mit , , , , , | 2 Kommentare

XPages: Empty HTML5 Attibutes & PassThroughTags

A while ago I developed some HTML5 XPages applications, but the development process was a little bit frustrating because of the missing possibility to add empty attributes to a PassThroughTag.  A single empty attribute is not allowed, because this would result in invalid XML, and you cannot use „xp:attributes“ with „UIPassThroughTag“ components.

A simple example like this…

<input type="text" value="John Doe" disabled />

… always ended up in something like this:

<xp:text tagName="input" disableTheme="true">
      <xp:attr name="disabled" minimized="true" value="disabled" />
      <xp:attr name="value" value="John Doe" />

To fit my requirements, I had extended the „UIPassThroughTag“ with a special attribute named „emptyAttrs„. This allowed me to write the example above in the following syntax:

<input type="text" value="John Doe" emptyAttrs="disabled" />

(Multiple empty attributes can be added comma separated.)

Here is the Java class:

package ch.hasselba.xpages;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import com.ibm.xsp.component.UIPassThroughTag;
import com.ibm.xsp.renderkit.html_basic.PassThroughTagRenderer;
import com.ibm.xsp.webapp.XspHttpServletResponse;

public class PassThroughTagRendererEx extends PassThroughTagRenderer {

    private final static String EMPTY_ATTRIBUTE_NAME = "emptyAttrs";
    public void encodeBegin(FacesContext fc, UIComponent uiComponent)
            throws IOException {

        // Component is rendered?
        if (uiComponent.isRendered() == false) {
        // only process instances of UIPassThroughTags
        if ((uiComponent instanceof UIPassThroughTag)) {
            UIPassThroughTag uiPTTag = (UIPassThroughTag) uiComponent;
            ResponseWriter rw = fc.getResponseWriter();
            // grab the printer writer directly from the response
            XspHttpServletResponse response = (XspHttpServletResponse) 

            PrintWriter rwPrinter = response.getWriter();
            // start the element tag
            rw.startElement(uiPTTag.getTag(), uiComponent);
            // process all attributes
            List<UIPassThroughTag.TagAttribute> attrList = uiPTTag
            if (attrList != null) {

                UIPassThroughTag.TagAttribute tagAttribute = null;
                String attrName = null;
                String attrValue = null;

                for (int i = 0; i < attrList.size(); i++) {
                    tagAttribute = attrList.get(i);
                    attrName = tagAttribute.getName();
                    attrValue = tagAttribute.getValue();
                    if (EMPTY_ATTRIBUTE_NAME.equalsIgnoreCase(attrName)) {
                        // process all empty tags
                        String tags[] = attrValue.split(",");
                        for( int j=0; j<tags.length; j++){
                            // write the attribute name only
                            rwPrinter.write( " " );
                            rwPrinter.write( tags[j].trim() );
                            // write the attribute data
                            rw.writeAttribute(attrName, attrValue, null);
        } else {
            // process other instances "as always"
            super.encodeBegin(fc, uiComponent);


To activate the class you have to overwrite the renderer in the „faces-config.xml„:

<?xml version="1.0" encoding="UTF-8"?>
Veröffentlicht unter HTML5, XPages | Verschlagwortet mit , , , | 2 Kommentare