If you develop a website or webapplication it’s always a good idea to reduce the number of HTTP requests by combining the Javascript and CSS into single files. In addition those files should be minimized.

There is a cool Java-tool available which can help you: YUI-Compressor. It can be used from the commandline and is able to minimize Javascript and CSS files. A document about the CSS minification can be found here.

To automate the process of concatination and minification I wrote a little ANT script.

Ant Script for CSS and JS concatination and minification

All settings can be found in the head, pathes can be either relational or absolut. You have to download a current version of YUI-Compressor from here:

Download YUI-Compressor.

<!-- Settings for CSS -->
<property name="css.src-dir" value="path-to-css-source"/>
<property name="css.dest-dir" value="path-to-css-destination"/>
<property name="css.files" value="
    css1.css,
    css2.css
"/>

<!-- Settings for JS -->
<property name="js.src-dir" value="path-to-js-source"/>
<property name="js.dest-dir" value="path-to-js-destination"/>
<property name="js.files" value="
    js1.js,
    js2.js
"/>

<!-- General settings -->
<property name="yuicompressor-jar" value="path-to-yuicompressor.jar"/>

I defined three targets to provide a maximum of flexibility:

  • all: Triggers css and javascript target
  • css: Processes CSS
  • javascript: Processes Javascript

Those targets can be called from commandline:

root@test:~# ant -f minify.xml TARGET

The CSS and Javascript target first concat the given CSS/JS files and then uses YUI-Compressor to minify them. The concated version will be deleted afterwards.

NOTE: YUI-Compressor version minor 2.4.4 have a bug which prevents the usage of Media-Queries in minified CSS!!!

In some cases, it’s neccessary to use a newer GCC compiler (Homepage) than the one provided via a package-manager. OpenSolaris currently provices a GCC 3.4.3 and GCC 4.3. This guide should help you to compile GCC 4 on OpenSolaris, in this case GCC 4.6.1.
The whole software compiled in this guide will be installed in /opt/local. As I don’t run OpenSolaris on a single-core machine, I’ll use the -j switch for make to compile multithreaded.

Basics

Like in most howtos, we need some basic packages from the repository. Those are required to compile GCC and it’s dependencies.

root@test:~# pkg install wget SUNWgcc SUNWgmake SUNWxcu4 system/library/math/header-math
               Packages to install:     7
           Create boot environment:    No
DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                  7/7   2393/2393    37.1/37.1

PHASE                                        ACTIONS
Install Phase                              3215/3215

PHASE                                          ITEMS
Package State Update Phase                       7/7
Image State Update Phase                         2/2

Building dependencies

The next step is to compile some dependencies of GCC. We could use OpenSolaris packages, but those are most likely outdated too.

binutils

The first part of software we will build are the binutils (Homepage). The current release is 2.21.1 and can be downloaded from here.

root@test:~# wget http://ftp.gnu.org/gnu/binutils/binutils-2.21.1.tar.gz
--2011-08-05 20:54:31--  http://ftp.gnu.org/gnu/binutils/binutils-2.21.1.tar.gz
Connecting to ftp.gnu.org|140.186.70.20|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25195472 (24M) [application/x-gzip]
Saving to: `binutils-2.21.1.tar.gz'

100%[==============================================>] 25,195,472   441K/s   in 58s

2011-08-05 20:55:29 (427 KB/s) - `binutils-2.21.1.tar.gz' saved [25195472/25195472]

root@test:~# tar xjf binutils-2.21.1.tar.gz
root@test:~# cd binutils-2.21.1
root@test:~/binutils-2.21.1# ./configure --prefix=/opt/local/gnu --disable-nls
checking build system type... i386-pc-solaris2.11
checking host system type... i386-pc-solaris2.11
...

root@test:~/binutils-2.21.1# gmake -j 4 && gmake install
gmake[1]: Entering directory `/root/binutils-2.21.1'
Configuring in ./intl
...
gmake[1]: Nothing to be done for `install-target'.
gmake[1]: Leaving directory `/root/binutils-2.21.1'

root@test:~/binutils-2.21.1# gmake clean
gmake[1]: Entering directory `/root/binutils-2.21.1'
Doing clean in bfd
...

root@test:~/binutils-2.21.1# cd ..
root@test:~# rm -r binutils-2.21.1*
gmplib

Now we will compile three libraries, which depend on each other. The first one is gmp (Homepage) in version 5.0.2.

root@test:~# wget ftp://ftp.gmplib.org/pub/gmp-5.0.2/gmp-5.0.2.tar.bz2
--2011-08-05 22:13:01--  ftp://ftp.gmplib.org/pub/gmp-5.0.2/gmp-5.0.2.tar.bz2
           => `gmp-5.0.2.tar.bz2'
Resolving ftp.gmplib.org... 130.237.222.241
Connecting to ftp.gmplib.org|130.237.222.241|:21... #connected.
Logging in as anonymous ... Logged in!
==> SYST ... done.    ==> PWD ... done.
==> TYPE I ... done.  ==> CWD (1) /pub/gmp-5.0.2 ... done.
==> SIZE gmp-5.0.2.tar.bz2 ... 2024576
==> PASV ... done.    ==> RETR gmp-5.0.2.tar.bz2 ... done.
Length: 2024576 (1.9M) (unauthoritative)

100%[===============================================>] 2,024,576    195K/s   in 11s

2011-08-05 22:13:13 (187 KB/s) - `gmp-5.0.2.tar.bz2' saved [2024576]

root@test:~# tar xfj gmp-5.0.2.tar.bz2
root@test:~# cd gmp-5.0.2
root@test:~/gmp-5.0.2# ./configure --prefix=/opt/local/gmp/5.0.2 \
    --build=i386-pc-solaris2.11

checking build system type... i386-pc-solaris2.11
checking host system type... i386-pc-solaris2.11
...

root@test:~/gmp-5.0.2# gmake -j 4
gcc -std=gnu99 `test -f 'gen-fac_ui.c' || echo './'`gen-fac_ui.c -o gen-fac_ui
gcc -std=gnu99 `test -f 'gen-fib.c' || echo './'`gen-fib.c -o gen-fib
...

root@test:~/gmp-5.0.2# gmake install
gmake  install-recursive
gmake[1]: Entering directory `/root/gmp-5.0.2'
...

root@test:~/gmp-5.0.2# gmake clean
Making clean in doc
gmake[1]: Entering directory `/root/gmp-5.0.2/doc'
...

root@test:~/gmp-5.0.2# cd ..
root@test:~# rm -r gmp-5.0.2*
root@test:~# ln -s /opt/local/gmp/5.0.2/lib/* /usr/lib/
mpfr

MPFR (Homepage) depends on GMP and is next on our list.

root@test:~# wget http://www.mpfr.org/mpfr-current/mpfr-3.0.1.tar.gz
--2011-08-05 21:09:42--  http://www.mpfr.org/mpfr-current/mpfr-3.0.1.tar.gz
Resolving www.mpfr.org... 152.81.144.6
Connecting to www.mpfr.org|152.81.144.6|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1478243 (1.4M) [application/x-gzip]
Saving to: `mpfr-3.0.1.tar.gz'

100%[================================================>] 1,478,243    412K/s   in 3.7s

2011-08-05 21:09:46 (394 KB/s) - `mpfr-3.0.1.tar.gz' saved [1478243/1478243]

root@test:~# tar xfj mpfr-3.0.1.tar.gz
root@test:~# cd mpfr-3.0.1
root@test:~/mpfr-3.0.1# ./configure --prefix=/opt/local/mpfr/3.0.1 \
    --build=i386-pc-solaris2.11 \
    --with-gmp=/opt/local/gmp/5.0.2

checking for a BSD-compatible install... ./install-sh -c
checking whether build environment is sane... yes
...

root@test:~/mpfr-3.0.1# gmake -j 4 install
gmake  install-recursive
gmake[1]: Entering directory `/root/mpfr-3.0.1'
...

root@test:~/mpfr-3.0.1# gmake clean
Making clean in tests
gmake[1]: Entering directory `/root/mpfr-3.0.1/tests'
..

root@test:~/mpfr-3.0.1# cd ..
root@test:~# rm -r mpfr-3.0.1*
root@test:~# ln -s /opt/local/mpfr/3.0.1/lib/* /usr/lib/
mpc

The final dependeny is mpc (Homepage) which depends on both GMP and MPFR. The current version is 0.9, but this one doesn’t compile on OpenSolaris. We will use 0.8.2 instead.

root@test:~# wget http://www.multiprecision.org/mpc/download/mpc-0.8.2.tar.gz
--2011-08-05 21:32:50--  http://www.multiprecision.org/mpc/download/mpc-0.8.2.tar.gz
Resolving www.multiprecision.org... 213.165.76.208
Connecting to www.multiprecision.org|213.165.76.208|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 548401 (536K) [application/x-tar]
Saving to: `mpc-0.8.2.tar.gz'

100%[=====================================================>] 548,401      265K/s   in 2.0s

2011-08-05 21:32:52 (265 KB/s) - `mpc-0.8.2.tar.gz' saved [548401/548401]

root@test:~# tar xfj mpc-0.8.2.tar.gz
root@test:~# cd mpc-0.8.2
root@test:~/mpc-0.8.2# ./configure --prefix=/opt/local/mpc/0.8.2 --build=i386-pc-solaris2.11 --with-gmp=/opt/local/gmp/5.0.2 --with-mpfr=/opt/local/mpfr/3.0.1
checking for a BSD-compatible install...
...

root@test:~/mpc-0.8.2# gmake -j 4 install
Making install in src
gmake[1]: Entering directory `/root/mpc-0.8.2/src'
...

root@test:~/mpc-0.8.2# gmake clean
Making clean in doc
gmake[1]: Entering directory `/root/mpc-0.8.2/doc'
...

root@test:~/mpc-0.8.2# cd ..
root@test:~# rm -r mpc-0.8.2*
root@test:~# ln -s /opt/local/mpc/0.8.2/lib/* /usr/lib/

GCC

Now we can finally begin to compile GCC. The current release is 4.6.1.

root@test:~# wget ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.6.1/gcc-4.6.1.tar.gz
--2011-08-05 21:36:24--  ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.6.1/gcc-4.6.1.tar.gz
           => `gcc-4.6.1.tar.gz'
Resolving ftp.fu-berlin.de... 130.133.3.130
Connecting to ftp.fu-berlin.de|130.133.3.130|:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done.    ==> PWD ... done.
==> TYPE I ... done.  ==> CWD (1) /unix/languages/gcc/releases/gcc-4.6.1 ... done.
==> SIZE gcc-4.6.1.tar.gz ... 93426552
==> PASV ... done.    ==> RETR gcc-4.6.1.tar.gz ... done.
Length: 93426552 (89M) (unauthoritative)

100%[=================================================>] 93,426,552   348K/s   in 3m 57s

2011-08-05 21:40:21 (385 KB/s) - `gcc-4.6.1.tar.gz' saved [93426552]

root@test:~# tar xjf gcc-4.6.1.tar.gz
root@test:~# mkdir gcc-obj
root@test:~# cd gcc-obj/
root@test:~/gcc-obj# ../gcc-4.6.1/configure \
    --with-gmp=/opt/local/gmp/5.0.2 \
    --with-mpfr=/opt/local/mpfr/3.0.1 \
    --with-mpc=/opt/local/mpc/0.8.2 \
    --with-gnu-as \
    --with-as=/opt/local/gnu/bin/as \
    --enable-shared \
    --disable-nls \
    --enable-languages=c,c++,objc \
    --prefix=/opt/local/gcc/4.6.1

checking build system type... i386-pc-solaris2.11
checking host system type... i386-pc-solaris2.11
...

root@test:~/gcc-obj# gmake -j 4
a lot of stuff, get a coffee...
...

root@test:~/gcc-obj# gmake install

root@test:~/gcc-obj# gmake clean

root@test:~/gcc-obj# cd ..
root@test:~/gcc-obj# rm -r gcc*

Now you have compiled your own GCC and can call it from /opt/local/gcc/4.6.1/bin.

Jenkins provides a nice plugin which lets you chat with it. I decided to install ejabberd on OpenSolaris. This is an easy to use Jabber/XMPP daemon which should be setup quite easy.

Installation

The OpenSolaris Package Repository contains a ejabberd Package which will be used. It includes the integration of ejabberd into is into Solaris’ Service Management Facility (smf) and makes it easy to use.

root@test:~# pkg install web/server/ejabberd
               Packages to install:     1
           Create boot environment:    No
               Services to restart:     1
DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                  1/1     167/167      0.8/0.8

PHASE                                        ACTIONS
Install Phase                                212/212

PHASE                                          ITEMS
Package State Update Phase                       1/1
Image State Update Phase                         2/2

Now we can enable ejabberd and check it’s status.

root@test:~# svcadm enable  svc:/network/xmpp:ejabberd
root@test:~# svcs -x  svc:/network/xmpp:ejabberd
svc:/network/xmpp:ejabberd (ejabberd Jabber/XMPP Server)
 State: online since Mon Aug 01 14:27:32 2011
   See: ejabberdctl(8)
   See: http://www.ejabberd.im
   See: /var/svc/log/network-xmpp:ejabberd.log
Impact: None.

Configuration

The configuration files of ejabberd can be found in /etc/ejabberd/. First we need to add the hostname of our server and modify the user permissions for an admin user we will create later.

In /etc/ejabberd/ejabberd.cfg we need the following entries:

...
%%%   ================
%%%   SERVED HOSTNAMES
{hosts, [&amp;quot;myhost&amp;quot;, &amp;quot;localhost&amp;quot;]}
...
%%%   ====================
%%%   ACCESS CONTROL LISTS
{acl, admin, {user, &amp;quot;myuser&amp;quot;, &amp;quot;localhost&amp;quot;}}.
{acl, admin, {user, &amp;quot;myuser&amp;quot;, &amp;quot;myhost&amp;quot;}}.

Afterwards we need to restart ejabberd and can create the user via commandline.

root@test:~# svcadm restart ejabberd
root@test:~# su daemon -c &amp;quot;ejabberdctl register myuser myhost mypassword&amp;quot;

We can now visit the admin WebGUI of ejabberd on http://myhost:5280/admin and login with the username myuser@myhost and the password.

Adding SSL Support

To enable the SSL Support of ejabberd, we need to create a certificate and add it to the ejabberd.cfg.

root@test:~# cd /etc/ejabberd/
root@test:/etc/ejabberd# openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
Generating a 1024 bit RSA private key
........................................++++++
........++++++
writing new private key to 'cert.pem'
...

Now find the line

{5222, ejabberd_c2s, [

in your ejabberd.cfg and uncomment and modify the entry

{certfile, &amp;quot;/path/to/ssl.pem&amp;quot;}, starttls,

.
The config should now look like this:

{5222, ejabberd_c2s, [
            %%
            %% If TLS is compiled and you installed a SSL
            %% certificate, put the correct path to the
            %% file and uncomment this line:
            %%
            {certfile, &amp;quot;/etc/ejabberd/cert.pem&amp;quot;}, starttls,
            {access, c2s},
            {shaper, c2s_shaper},
            {max_stanza_size, 65536}
          ]},

If we now restart ejabberd, SSL support is available.

root@test:/etc/ejabberd# svcadm restart ejabberd

Connect your XMPP Client to ejabberd

Now we can connect your XMPP Client to your ejabberd Server. The following screenshot contains the information for Pidgin.
ejabberd 270x300 ejabberd on OpenSolaris

After the installation of Ant we can proceed with Maven.

This HowTo descripes the installation of Maven 3 on a OpenSolaris system and the following integration into Jenkins whose installation was descriped in this guide.

Setup

The Maven installation requires Ant and a JDK to build. If you haven’t installed Ant yet, you should visit the appropriate guide first. The JDK can beinstalled via pkg install.
You can find the current version of Maven on any Apache Mirror near you.

root@test:~# cd /tmp
root@test:/tmp# pkg install jdk
root@test:/tmp# PATH=$PATH:/opt/local/bin
root@test:/tmp# wget http://apache.easy-webs.de/maven/source/apache-maven-3.0.3-src.tar.gz
--2011-07-31 21:15:53--  http://apache.easy-webs.de/maven/source/apache-maven-3.0.3-src.tar.gz
Connecting to apache.easy-webs.de|87.106.190.69|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3728950 (3.6M) [application/x-gzip]
Saving to: `apache-maven-3.0.3-src.tar.gz'

100%[===========================================================&gt;] 3,728,950    641K/s   in 6.1s

2011-07-31 21:15:59 (598 KB/s) - `apache-maven-3.0.3-src.tar.gz' saved [3728950/3728950]

root@test:/tmp# tar xvf apache-maven-3.0.3-src.tar.gz
Decompressing 'apache-maven-3.0.3-src.tar.gz' with '/usr/bin/gzcat'...
x apache-maven-3.0.3, 0 bytes, 0 tape blocks
x apache-maven-3.0.3/apache-maven, 0 bytes, 0 tape blocks
x apache-maven-3.0.3/apache-maven/src, 0 bytes, 0 tape blocks
...

root@test:/tmp/apache-maven-3.0.3# export M2_HOME=/opt/maven/
root@test:/tmp/apache-maven-3.0.3# ant
root@test:/tmp/apache-maven-3.0.3# cd ..
root@test:/tmp# rm -r apache-maven-3.0.3

Jenkins Setup

To tell Jenkins which Maven installation should be used, you need to enter the Jenkins-Website and click on Manage Jenkins.

Jenkins02 300x129 Maven on OpenSolaris

Now enter Configure System and set the Maven settings according to this screenshot.
Jenkins03 Maven 300x84 Maven on OpenSolaris

If you’re running a Jenkins Continous Integration System as descriped in this guide, you most likely need Ant and/or Maven to build your applications.

The next two HowTos are about the installation of those tools and the required setup in Jenkins. As Maven requires Ant, we start with that. The guide about the installation of Maven can be found here.

You can find the current version of ant on any Apache Mirror near you.

Setup

First we have to download the current Ant version and put it into /opt/ant/current. Afterwards we can setup Jenkins to use this installation.

root@test:~# cd /opt
root@test:/opt# mkdir ant
root@test:/opt# cd ant/
root@test:/opt/ant# wget http://apache.openmirror.de//ant/binaries/apache-ant-1.8.2-bin.tar.gz
--2011-07-31 21:25:34--  http://apache.openmirror.de//ant/binaries/apache-ant-1.8.2-bin.tar.gz
Connecting to apache.openmirror.de|83.246.74.136|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8324124 (7.9M) [application/x-gzip]
Saving to: `apache-ant-1.8.2-bin.tar.gz'

100%[==========================================================&gt;] 8,324,124    668K/s   in 12s

2011-07-31 21:25:46 (679 KB/s) - `apache-ant-1.8.2-bin.tar.gz' saved [8324124/8324124]

root@test:/opt/ant# tar xvf apache-ant-1.8.2-bin.tar.gz
Decompressing 'apache-ant-1.8.2-bin.tar.gz' with '/usr/bin/gzcat'...
x apache-ant-1.8.2/bin/ant, 9997 bytes, 20 tape blocks
x apache-ant-1.8.2/bin/antRun, 861 bytes, 2 tape blocks
x apache-ant-1.8.2/bin/antRun.pl, 2199 bytes, 5 tape blocks
...

root@test:/opt/ant# ln -s apache-ant-1.8.2 current
root@test:/opt/ant# ln -s /opt/ant/current/bin/ant /opt/local/bin/
root@test:/opt/ant# rm apache-ant-1.8.2-bin.tar.gz

Jenkins Setup

To tell Jenkins which Ant installation should be used, you need to enter the Jenkins-Website and click on Manage Jenkins.

Jenkins02 300x129 Ant on OpenSolaris

Now enter Configure System and set the Ant settings according to this screenshot.
Jenkins03 Ant 300x83 Ant on OpenSolaris