Running FishEye & Crucible as a service in Linux

Atlassian’s tools for supporting software development are great but they aren’t really admin friendly to start with. For example FishEye & Crucible doesn’t ship with scripts to start it at system boot time but with the help of Atlassian’s Wiki, sysadmin tasks and scripts you can run it as a normal service. First we create a dedicated user for crucible and second we add a new service for it. I have done this on CentOS 5.7 x86_64.

Setting up the service account

As the root user, create a separate “FishEye & Crucible” service account at root shell:

# useradd -c "FishEye & Crucible service account" -d /home/crucible -m crucible

To make it easier for this to work also after FishEye & Crucible upgrades we create a symbolic link to the latest version (modify “/opt/fecru” to match your deployment).

# ln -s /opt/fecru/fecru-2.7.15 /opt/fecru/latest

Then, ensure that this user is the filesystem owner of the FishEye & Crucible instance (modify “/opt/fecru” to match your deployment).

# chown -R crucible:crucible /opt/fecru

Running Crucible as a crucible user

Save the following script to /etc/init.d/crucible. Be sure to edit the FISHEYE_HOME value to the location where your FishEye/Crucible instance resides:

#!/bin/bash
# RUN_AS: The user to run fisheye & crucible as. Its recommended that you create a separate user account for security reasons
RUN_AS=crucible
 
# FISHEYE_HOME: The path to the FishEye & Crucible installation. Its recommended to create a symbolic link to the latest version so the process will still work after upgrades.
FISHEYE_HOME="/opt/fecru/latest"
# FISHEYE_INST: The path where the data itself will be stored.
export FISHEYE_INST="/opt/fecru/fecru-data"

fisheyectl() {
        if [ "x$USER" != "x$RUN_AS" ]; then
                # If running without FISHEYE_INST
                # su - "$RUN_AS" -c "$FISHEYE_HOME/bin/fisheyectl.sh $1"
                su - "$RUN_AS" -c "FISHEYE_INST=$FISHEYE_INST $FISHEYE_HOME/bin/fisheyectl.sh $1"
        else
                "$FISHEYE_HOME/bin/fisheyectl.sh $1"
        fi
} 

case "$1" in
        start)
                fisheyectl start
                ;;
        stop)
                fisheyectl stop
                ;;
        restart)
                fisheyectl stop
                sleep 10
                fisheyectl start
                ;;
        *)
                echo "Usage: $0 {start|stop|restart}"
esac
 
exit 0

After saving the script, modify it’s permissions so that it can be executed:

# chmod 755 /etc/init.d/crucible

Running Crucible as a service

Now that we have an init script we can add it as a service and be able to configure the system to run the script on startup (more precisely, ensure that Crucible runs in runlevels 3, 4 and 5):

chkconfig --add crucible
chkconfig crucible on

Verify that the script has been installed correctly:

# chkconfig --list crucible

After this has been done you can manually start or stop the service by using these commands:

service crucible stop
service crucible start

And you’re done.

JSF 1.2 and getting selected value from dropdown

JSF 1.2 has some weird features which you just have to know if you haven’t read the documents. One example is getting a value from h:selectOneMenu dropdown after onchange event. The first what comes to mind is to use binding attribute with RichFaces’ a4j:support for rerendering elements after the event but it doesn’t work like you thought it would. In some cases using the binding attribute works just fine but as the binding attribute should refer to a request scoped bean property, not a session scoped one, you might get “Duplicate id error” when switching pages back and forth.

Fortunately there is valueChangeListener in h:SelectOneMenu which you can trick to do almost the same. It is executed during Validations phase, before the “Update Model Values” phase and is intended to get a handle of both the old and new value so that you can do some business stuff based on the real change. However, you can use it to invoke actions on a dropdown change only by combining it with onchange="submit()" and immediate="true" and the selected value is to be obtained by ValueChangeEvent#getNewValue(). (StackOverflow, BalusC)

For example:

Jspx:
<h:selectOneMenu value="#{fooBean.object.value}" 
	valueChangeListener="#{fooBean.statusChanged}" 
	onchange="submit()" immediate="true">
	<f:selectItem itemLabel="" itemValue=""/>
	<f:selectItems value="#{fooBean.selectValuesList}"/>
</h:selectOneMenu>
 
Java:
public void statusChanged(ValueChangeEvent event) {
	if (event.getNewValue() != null && 
		StringUtils.hasText((String) event.getNewValue())) {
		// ... Do something with the new value
	}
}

The negative side of using onchange="submit()" is that the form is submitted, validated and you don’t get the same dynamic feeling like with a4j:support.

In JSF 2 things are easier as you don’t need the valueChangeListener and you can use the listener attribute of instead.

Exclude JQuery libraries from Eclipse’s JavaScript Validation

Eclipse likes to validate JavaScript when doing Dynamic Web Modules and thus may give you false positive validation errors on 3rd party JavaScript libraries like JQuery. Although you can turn off the validation altogether but better solution is to configure it to exclude files as Alexander shows us at Stackoverflow.

Eclipse Indigo (3.7) has the option to selectively remove some JavaScript sources from validation. The information about JavaScript source inclusion/exclusion is saved into .settings/.jsdtscope file.

  1. Right click your project
  2. Select Properties → JavaScript → Include Path
  3. Select Source tab
  4. Expand JavaScript source folder
  5. Highlight Excluded pattern
  6. Click Edit button
  7. Click Add button next to Exclusion patterns box
  8. You may use wildcard pattern, or click Browse button to add the source by name.
    • Exclude all JQuery files with pattern like: js/jquery-*

The configuration with JQuery files excluded from validation looks like this:

eclipse_exclude-javascript

Eclipse and Maven Console

Eclipse 3.7 Indigo has integrated Maven m2e plugin but is missing some expected functionality which was previously present in Sonatype releases by default. If you want your Maven Console to show something you must also install the optional “m2e – slf4j over logback logging” plugin.

When installing the m2e plugin there is an optional feature “m2e – slf4j over logback logging” which is needed for the Maven Console to work. Without it the plugin produces no output to Eclipse’s Maven Console view so that it is impossible to track plugin’s activity (background maven builds, source and javadoc downloads, etc).

There is a bug filed about it but it is resolved with comment “As a tool, m2e is not in the position to impose any specific slf4j logging backend on the host Eclipse installation.” That seems kinda strange as without the optional component the plugin is missing useful parts.

Just “Install new sofware > Indigo > Collaboration > “m2e – slf4j over logback logging (Optional)” and your Maven Console is back in business.

Using CAcert.org signed certificates for TLS

Setting up Transport Layer Security (TLS), or as previously known as Secure Sockets Layer (SSL), for Apache, Postfix and IMAP like Dovecot is fairly easy. You just need some digital certificates and configuration. If you don’t want to pay for certificates from trusted sources like Thawte or you just don’t need that kind of trust (for development purposes), you can always produce your own certificates. But there is also a middle way: using CAcert.org signed certificates.

Background
Wikipedia tells us that CAcert.org is a community-driven certificate authority that issues free public key certificates. CAcert automatically signs certificates for email addresses controlled by the requester and for domains for which certain addresses (such as “hostmaster@example.com”) are controlled by the requester. Thus it operates as a robot certificate authority. CAcert certificates can be used like any other SSL certificates although they are considered weak because CAcert does not emit any information in the certificates other than the domain name or email address. To create higher-trust certificates, users can participate in a web of trust system whereby users physically meet and verify each other’s identities. They are also not as useful in web browsers as certificates issued by commercial CAs such as VeriSign, because most installed web browsers do not distribute CAcert’s root certificate. Thus, for most web users, a certificate signed by CAcert behaves like a self-signed certificate.

Generating Certificates
The procedure to sign your certificate at CAcert is rather simple. This guide assumes that the certificates are in /etc/ssl/cacert/ and you are as root.

0. Join CAcert.org and fill in your details. After email verification and login, add domain and service will try to verify that you can read mail on one of following accounts: root, hostmaster, postmaster, admin, webmaster or email addresses that can be found on whois data of domain that you provided.

1. Generate a private key that is not file encrypted:

openssl genrsa -out domainname.key 1024
chown root:root domainname.key
chmod 0400 domainname.key

Private keys should belong to “root” and be readable only by root.

You could also create a private key that is encrypted: openssl genrsa -des3 -out domainname.key 1024

2. Create a CSR with the RSA private key (output will be PEM format). Do not enter extra attributes at the prompt and leave the challenge password blank (press enter):

openssl req -new -key domainname.key -out domainname.csr

3. Verify the contents of the CSR or private key:

openssl req -noout -text -in domainname.csr
openssl rsa -noout -text -in domainname.key

4. Send your public key to be signed by and request new server certificate from CAcert.org web site (Class 1 certificate). When you are asked for CSR paste content of domainname.csr. It should look like this:

-----BEGIN CERTIFICATE REQUEST-----
MIIB3TCCAUYCAQAwgZwxCzAJBgNVBAYTAkZJMRAwDgYDVQQIEwdVdXNpbWFhMQ8w
...clip...
MQ==
-----END CERTIFICATE REQUEST-----

You can verify the content of request before sending it

openssl req -in domainname.csr -text -verify -noout

5. Copy the Server Certificate from the CAcert.org webpage and put it in domainname.crt file and add permissions.

chmod a=r domainname.crt

Check at least the contents of Validity and Subject fields:

openssl x509 -in domainname.crt -text -noout

6. Get CAcert.org root certificate

wget -nv https://www.cacert.org/certs/root.crt -O cacert-org.crt
chmod a=r cacert-org.crt

Check the contents:

openssl x509 -in cacert-org.crt -text -noout

After that you’re ready to configure your services like Apache, Postfix and Dovecot to use the new certificate. Read about it later.

For year 2012

The year 2011 has been pretty quiet in this blog as I managed to write just one post. In the backlog I have had for some time a couple of articles almost done and several topics to write about but as it sometimes happens, the time runs out.

For the coming year 2012 I have made a promise to myself to research technology related issues and also write about them to this blog and to my Finnish blog. Now I have just done the former and kept the new information to myself :) Including the articles in the backlog I also have some new topics to write. So subscribe to the RSS feed and stay tuned.

Happy New Year!

WordPress mod_rewrite rules taking over mod_status and mod_info

After moving Rule of Tech to a new server and setting up monitoring I noticed that server-status and server-info Apache modules weren’t working as expected. As usual a little bit of Googling solved this problem.

The problem was that the .htaccess rules in WordPress were taking over non-existing server-info and server-status urls given in Apache’s config and were returning a page not found error. The rewrite rules by WordPress were setup to handle all the permalinks on the site and for any non-existing file send it to index.php. It really wasn’t a WordPress problem and should happen with any application that uses the same type of catch-all rewrite rules to handle all the urls inside the application.

The solution was to specifically add a rewrite rule to not have the server-status and server-info urls processed by adding a rule like: RewriteCond %{REQUEST_URI} !=/server-status. The other way is to stop the rewriting process when the urls are found by adding a rule like: RewriteRule ^(server-info|server-status) - [L].

The WordPress rewrite rules should look like this:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# server info and status
RewriteRule ^(server-info|server-status) - [L]
# RewriteCond %{REQUEST_URI} !=/server-status
# /server info and status
RewriteCond %{REQUEST_FILENAME} -f 
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . index.php [L]
</IfModule>
# END WordPress

Installing Apache Tomcat 6 on CentOS

CentOS is great substitute for Red Hat Enterprise Linux but is missing some useful packages like Apache Tomcat 6. Installing Apache Tomcat 6 on CentOS 5 from gzip-package is fairly easy. The following guide is at least for CentOS 5.4.

Pre-Requirements
First you need to install Sun JDK and you can follow the instructions given in Installing Sun JDK 1.6 on CentOS

After Java is on place it’s time to get ready for Tomcat.

Download Apache Ant and Tomcat

  1. Download apache-ant and apache-tomcat -packages.
  2. Extract those packages to /opt/
    • #[root@srv ~]# cd /opt
      # tar -xzf apache-tomcat-6.0.26.tar.gz
      # tar -xzf apache-ant-1.7.1-bin.tar.gz
      
  3. Create a symbolic link for Ant
    • # ln -s /opt/apache-ant-1.7.1/bin/ant /usr/bin/
      

Create start script

  1. Create a tomcat user so that we don’t need root privileges for Tomcat
    • # useradd -d /opt/apache-tomcat-6.0.26/ tomcat
      
  2. Create start script to /etc/init.d for starting and stopping Tomcat
    • #  vim /etc/init.d/tomcat
      
  3. The script is (via Build a safe cage for Tomcat)
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      
      #!/bin/bash
      #
      # tomcat       Starts Tomcat Java server.
      #
      #
      # chkconfig: 345 88 12
      # description: Tomcat is the server for 
      # Java servlet applications.
      ### BEGIN INIT INFO
      # Provides: $tomcat
      ### END INIT INFO
       
      JAVA_HOME=/usr/java/jdk1.6.0_18
      export JAVA_HOME
      TOMCAT_HOME=/opt/apache-tomcat-6.0.26/bin
      START_TOMCAT=/opt/apache-tomcat-6.0.26/bin/startup.sh
      STOP_TOMCAT=/opt/apache-tomcat-6.0.26/bin/shutdown.sh
       
      # Source function library.
      . /etc/init.d/functions
       
      [ -f $START_TOMCAT ] || exit 0
      [ -f $STOP_TOMCAT ] || exit 0
       
      RETVAL=0
       
      umask 077
       
      start() {
              echo -n $"Starting Tomcat Java server: "
              daemon su -c $START_TOMCAT tomcat
              echo
              return $RETVAL
      }
      stop() {
              echo -n $"Shutting down Tomcat Java server: "
              daemon su -c $STOP_TOMCAT tomcat
              echo
              return $RETVAL
      }
      restart() {
              stop
              start
      }
      case "$1" in
        start)
              start
              ;;
        stop)
              stop
              ;;
        restart|reload)
              restart
              ;;
        *)
              echo $"Usage: $0 {start|stop|restart}"
              exit 1
      esac
       
      exit $?
  4. Give executable rights for that script
    • # chmod 755 /etc/init.d/tomcat
      
  5. Add the script to CentOS services
    • # chkconfig --add tomcat
      
  6. Check the changes
    • # chkconfig --level 234 tomcat on
      # chkconfig --list tomcat
      
      tomcat 0:off 1:off 2:on 3:on 4:on 5:off 6:off
      
  7. You should see that the service uses levels 2, 3 and 4
  8. Test that the script is working and it gives no errors
    • # service tomcat start
      # service tomcat stop
      
  9. Everythings ready

Installing Sun JDK 1.6 on CentOS

CentOS doesn’t have a package for Sun JDK so it has to installed manually. It’s fairly easy but there are some steps to do that. This guide has been tested on CentOS 5.4 x64_86.

Step 1. Initial setup for building RPM
-!- Do this with a non-root user

  1. Create ~/.rpmmacros
    • $ vim ~/.rpmmacros
      %_topdir /home//rpmbuild
      %_tmppath %{_topdir}/tmp
      
  2. Create needed folders:
    • $ mkdir -p ~/rpmbuild/{SOURCES,SRPMS,SPECS,RPMS,tmp,BUILD}
      
  3. Build environment needs to be complete. Some needed packages are:
    • $ sudo yum install -y rpm-build gcc gcc-c++ redhat-rpm-config
      

Step 2. Installing your favorite JDK

  1. Download Sun JDK 1.6 update 14 from Sun Java download or the Sun JDK archive.
    • Choose the correct platform (for me it’s Linux x64) and download jdk-6u18-linux-x64-rpm.bin
  2. Give it executable rights: $ chmod 755 jdk-6u18-linux-x64-rpm.bin
  3. Run the binary to extract it into RPM form: $ ./jdk-6u18-linux-x64-rpm.bin
  4. Install it:
    • $ sudo rpm -Uvh jdk-6u18-linux-amd64.rpm
      
  5. Log out and in again to make the changes in the paths take effect
  6. Check the install
    • $ java -version
      java version "1.6.0_18"
      Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
      Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)
      
  7. Java is now installed on /usr/bin/java

Using RichFaces 3 dataScroller and dataTable -components

RichFaces provides some nice AJAX-components for Java Server Faces but the documentation and examples could be better. RichFaces has great documentation compared to some other frameworks but it could be better with adding a little bit of real world and down to earth examples. So here is one example of using RichFaces dataScroller and dataTable -components with custom CSS-styling, backingBean and JSF-page snippets using Richfaces 3.3.2.SR1 and JSF 1.2_12.

Using RichFaces dataScroller and dataTable components has a big negative property: they work nicely if the amount of data is small but when the row count reaches to thousands they become sluggish or stop working. The rich:dataScroller needs the complete datamodel being loaded into memory and only displays a part of it. Not very efficient if the rowcount exceeds 1000 or so.

Anyways here is some real world example. The icons used in the examples for dataScroller are from Crystal Project Icons.

JSF-page

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<h:form id="myForm">
    <rich:dataScroller styleClass="dataScroller" id="scroller" 
        for="resultTable" maxPages="15" fastStep="3"
        renderIfSinglePage="false" immediate="false" 
        binding="#{backingBean.scroller}" page="#{backingBean.scrollerPage}">
        <f:facet name="first" >
            <h:graphicImage id="firstImage" styleClass="scroller" 
            url="images/crystal/tab_first.png" alt="first"/>
        </f:facet>
        <f:facet name="last">
            <h:graphicImage id="lastImage" styleClass="scroller" 
                url="images/crystal/tab_last.png" alt="last"/>
        </f:facet>
        <f:facet name="previous">
            <h:graphicImage id="prevImage" styleClass="scroller" 
                url="images/crystal/tab_left.png" alt="previous"/>
            </f:facet>
        <f:facet name="next">
            <h:graphicImage id="nextImage" styleClass="scroller" 
                url="images/crystal/tab_right.png" alt="previous"/>
        </f:facet>
        <f:facet name="fastforward">
            <h:graphicImage id="ffImage" styleClass="scroller" 
                url="images/crystal/tab_fastf.png" alt="next"/>
        </f:facet>
        <f:facet name="fastrewind">
            <h:graphicImage id="frImage" styleClass="scroller" 
                url="images/crystal/tab_fastr.png" alt="next"/>
        </f:facet>
        <f:facet name="first_disabled" >
            <h:graphicImage id="firstImage_d" styleClass="scroller" 
                url="images/crystal/tab_first.png" alt="first"/>
        </f:facet>
        <f:facet name="last_disabled">
            <h:graphicImage id="lastImage_d" styleClass="scroller" 
                url="images/crystal/tab_last.png" alt="last"/>
        </f:facet>
        <f:facet name="previous_disabled">
            <h:graphicImage id="prevImage_d" styleClass="scroller" 
                url="images/crystal/tab_left.png" alt="previous"/>
        </f:facet>
        <f:facet name="next_disabled">
            <h:graphicImage id="nextImage_d" styleClass="scroller" 
                url="images/crystal/tab_right.png" alt="next"/>
        </f:facet>
        <f:facet name="fastforward_disabled">
            <h:graphicImage id="ffImage_d" styleClass="scroller" 
                url="images/crystal/tab_fastf.png" alt="next"/>
        </f:facet>
        <f:facet name="fastrewind_disabled">
            <h:graphicImage id="frImage_d" styleClass="scroller" 
                url="images/crystal/tab_fastr.png" alt="previous"/>
        </f:facet>
        <f:facet name="controlsSeparator">
            <h:outputText id="sep" value=" " />
        </f:facet>
</rich:dataScroller>
 
<rich:dataTable styleClass="resultTable" id="resultTable" 
    rows="10" rowClasses=",odd"  columnClasses="col"  
    value="#{backingBean.resultList}" binding="#{backingBean.resultData}" 
    var="h" sortMode="multi">
    <rich:column sortBy="#{h.desc}">
        <f:facet name="header">
            <h:outputText value="description" />
        </f:facet>
        <h:commandLink value="#{h.desc}"
            action="#{backingBean.showRowData}">
            <f:param name="selectedRow" value="#{h.desc" />
        </h:commandLink>
    </rich:column>
    <rich:column sortBy="#{h.value}">
        <f:facet name="header">
            <h:outputText value="value" />
        </f:facet>
        <h:outputText value="#{h.value}" />
    </rich:column>
</rich:dataTable>
</h:form>

Backing Bean

Create some variables for dataScroller and getters and setters for them:

1
2
3
4
5
6
7
8
// RichFaces dataScroller variables
private HtmlDatascroller scroller = new HtmlDatascroller();
private String scrollerPage = "";
 
// Getting the clicked row's data
public String showRowdata() {
  MyDataModel current = (myDataModel) getResultData().getRowData();
}

CSS styling

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* =RichFaces DataScroller
----------------------------------------------- */
.rich-datascr {font-size: 1.1em;border: 0;}
.rich-table-cell {font-size: 1.0em;}
.rich-table-sortable-header {font-size: 1.1em;font-weight: bold;}
td.rich-datascr-button {background-color: #fff;border: 0px solid #ccc;text-decoration: none;}
td.rich-datascr-button-dsbld {background-color: #fff;}
.rich-datascr-ctrls-separator {padding-right: 5px;}
.rich-dtascroller-table {background: #fff;border: 0;}
.scroller {display: block;background-color: #fff;border: 1px solid #ccc;padding: 3px 3px;margin: 0px 5px 5px 5px;text-decoration: none;}
.scroller:hover {background-color: #eee;}
td.rich-datascr-button-dsbld .scroller {background-color: #eee;}
td.rich-datascr-inact {font-size: 1.2em;color: #000;border: 0;}
td.rich-datascr-inact:hover {text-decoration: underline;}
td.rich-datascr-act {font-size: 1.2em;text-decoration: underline;}
td.rich-datascr-act {border: 0;font-weight: bold;}

Selecting All rows with JavaScript

Add to the JSF-page a new column which has the checkbox. We are using JavaScript to loop through the input fields which are after :tu -ending id-field.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<rich:column>
  <f:facet name="header">
    <h:panelGroup layout="block">
      <script type="text/javascript">
        //<![CDATA[
        // RichFaces datatable select all -checkbox
        function checkAllCheckboxesInTable( inputId, state ){
          var commonIdPart = inputId.substr(0, inputId.lastIndexOf(':'));
          var tableId = commonIdPart + ':tu'
          var tableElement = document.getElementById( tableId );
          var inputs = tableElement.getElementsByTagName('input');
          for (var i = 0; i <= inputs.length; i++){
            var input = inputs[i];
            if (input != undefined) {
              if( input.getAttribute('type') == 'checkbox' && state){
                input.setAttribute('checked', state);
              } else{
                input.setAttribute('checked', false);
                input.removeAttribute('checked');
              }
            }
          }
        }
        //]]>
      </script>
      <h:selectBooleanCheckbox id="t0" onclick="checkAllCheckboxesInTable( this.id, this.checked );">
        <a4j:support event="onchange" reRender="resultTable"/>
      </h:selectBooleanCheckbox>
    </h:panelGroup>
  </f:facet>
  <h:selectBooleanCheckbox id="t1" value="#{h.selected}" />
</rich:column>

Selecting All rows in backing bean

You can also check all the checkboxes from the backingBean but it has problems with table ordering and when the lists order changes the selection goes wrong.

Add to the JSF-page a new column:

1
2
3
4
5
6
7
8
<rich:column>
  <f:facet name="header">
    <h:selectBooleanCheckbox id="t0" value="#{backingBean.selectedAll}" onclick="this.blur()">
        <a4j:support event="onchange" actionListener="#{backingBean.selectAll}" reRender="resultTable, t0, t1"/>
      </h:selectBooleanCheckbox>
    </f:facet>
  <h:selectBooleanCheckbox id="t1" value="#{h.selected}" />
</rich:column>

Make a new method to your backingBean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void selectAll(ActionEvent event) {
	logger.info("*** backingBean.selectAll(): " + scrollerPage + " ***");
 
	// get the current scroller page
	int page = Integer.valueOf(scrollerPage).intValue();
	if (page != 0) {
	    page = page - 1;
	}
	int start = page * 10;
	int stop = (page * 10) + 10;
	if (stop > getResultList().size()) {
	    stop = getResultList().size();
	}
	logger.debug("> page: " + page + "; start: " + start + "; stop: " + stop);
 
	// check the boxes on the active page
	for (int i = start; i < stop; i++) {
	    logger.debug("> valitaan: " + i + "; " + selectedAll);
	    getResultList().get(i).setSelected(selectedAll);
	}
}