Showing newest posts with label howto. Show older posts
Showing newest posts with label howto. Show older posts

Tuesday, September 15, 2009

Build numbers & release dates with Maven


Having the build date & build number is a common requirement in any build system. Often, documents such as release notes & readme files need to contain this information. If your project uses Maven 2.x, here is how you do it.



1. Add the plugin repository

<pluginRepositories>
<pluginRepository>
<id>tlc</id>
<name>TLC Repository</name>
<url>http://commons.ucalgary.ca/pub/m2</url>
</pluginRepository>
</pluginRepositories>

2. Add the plugin to the product distributions POM

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>maven-buildnumber-plugin</artifactId>
<version>0.9.4</version>
<configuration>
<format>{0,date,dd MMM yyyy}</format>
<items>
<item>timestamp</item>
</items>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>

3. Where ever you use the release date, use the ${buildNumber} property

4. That is it!

Friday, August 14, 2009

How to patch WSO2 Carbon


WSO2 Carbon allows patching of the server. We provide patches to customers, and these patches deal with issues that crop up on production servers. Patching a Carbon server can be done at two levels.




  1. The sever bootstrap runtime patching is done by placing the patches in the CARBON_HOME/lib/patches directory. Here we are patching regular jar files. You will need to do this only if you are running Carbon in stanadlone mode. If you are running Carbon on top of another app server such as WebLogic, Websphere AS (WAS), Tomcat or JBoss AS, you need not patch the bootstrap libraries since the bootstrapping is the responsibility of the respective JavaEE application server.


  2. Patching the server features are done by placing the patches in CARBON_HOME/webapps/ROOT/WEB-INF/patches. This can be done when Carbon in running in standalone mode as well as when it is running on top of a JavaEE application server. In this case we are actually 'patching' the Carbon OSGi bundles.



After patching the server, you need to restart it as follows:



./wso2server.sh -cleanCache; in the case of standalone mode execution. In the case of running within a JavaEE server, you need to delete the CARBON_HOME/repository/components/plugins directory, and restart the app server.

Sunday, October 19, 2008

How to extend WSO2 Registry

A great article by Chathura Ekanayake, lead developer of the WSO2 Registry on extending the WSO2 Registry.

How to create patches for OSGi bundles

The standard practice that was followed with respect to providing patches (which contain bug fixes) for WSO2 Java products was to create a JAR file containing the fixes, which contains only the classes that have been changed, and placing this patch file, say foo-patch.jar, in the $PRODUCT_HOME/lib/patches directory. When the classpath is constructed, the $PRODUCT_HOME/lib/patches directory is placed in front of the $PRODUCT_HOME/lib/ directory, hence the patched classes take precedence. However, this mechanism does not work on the newer generation of Java products, which are based on OSGi. Hence we had to figure out how to patch OSGi bundles. The obvious answer one can think of is, 'Ship a new version of the bundle'. However, this is not sometimes feasible due to several reasons.

1. The patch may be large (it is the entire bundle that is shipped), even if only a single class changed.
2. Some other bundles may depend on a fixed version of the packages exported by the bundle that is being patched. Hence, we will have to ship new versions of the affected bundles as well, which can lead to a chain reaction. In the worst case, all the bundles may have to be shipped due to a change to a single class in a core bundle!
3. If the dependent bundles import packages in a range of versions, such as [1.0,2.0), the importer will be wired to the bundle which exports the package with the highest version. In this case, shipping a new version of the bundle may work, provided that backwards compatibility is satisfied. However, this may not be always possible.

We can provide a simple solution to this problem using 2 OSGi constructs; require-bundle & fragments. Figure 1 shows that the required bundles take precedence over the bundle's classpath. Hence we can use required bundles to override classes in the bundle.


Figure 1: Class loading flowchart. Source: OSGi R4 spec

However, at the time of shipping a bundle, we cannot know what patch bundles will be required. Hence we cannot put a Require-Bundle manifest header pointing to the patch, in the original bundle. This is where fragments come into play. The entries in the fragments' manifest are merged into that of the fragment host. Hence, we can create a fragment which will require the patch bundle. In effect we have managed to dynamically add a Require-Bundle header to the original host bundle. However, we should ensure that the original bundle is the primary exporter of the patched packages. This can be done by specifying a mandatory attribute. We need to add this to the Export-Package header of the fragment;
e.g. Export-Package:*;partial=true;mandatory:=partial
Once the fragment is attached to the host & the host is refreshed, we will be able to see the functionality in the patch taking effect.

If you ever require to revert the patch, it is just a matter of removing the fragment & patch bundles, and refreshing the main bundle.

I have created a PoC project which demonstrates this concept. You can download the code and try it out. The main bundle is the bundle that needs to be patched. The patch bundle is the required bundle & the fragment bundle attaches to its host, the main bundle. The Knopflerfish desktop tool can be used to test this out.

NOTE: Don't confuse this with bytecode level patching at runtime. That is a different aspect. I've written another post on how that can be done.

How to setup EC2 tools

0. Download EC2 tools

1. Extract ec2-api-tools.zip to some directory. I've installed them at $HOME/.ec2

2. Install a JDK (>= 1.5)

3. export/set the following environment variables; JAVA_HOME, EC2_HOME, EC2_PRIVATE_KEY, EC2_CERT, PATH.
You could simply add these to you /etc/profile, /etc/bash.bashrc or ~/.bashrc files. e.g. Include the following in your /etc/profile, /etc/bash.bashrc or ~/.bashrc files

JAVA_HOME=/usr/local/java

EC2_HOME=/home/azeez/.ec2
EC2_PRIVATE_KEY=/home/azeez/.ec2/pk-xxx.pem
EC2_CERT=/home/azeez/.ec2/cert-xxx.pem

PATH=$JAVA_HOME/bin:$EC2_HOME/bin:$PATH

export JAVA_HOME EC2_HOME PATH EC2_PRIVATE_KEY EC2_CERT

How to create an EC2 AMI

The easiest way to create an EC2 AMI (Amazon Machine Image) is to select one of the publicly available AMIs which suits your requirement. Let's say you selected an Ubuntu image, ami-0757b26e. If you don't have an Amazon Web Services (AWS) account, first create one. Also you will need to download the EC2 command line tools & then set them up. For instructions on how to setup the EC2 tools, read this.

Follw these step to create your AMI:

0. Generate a keypair if you have not already done so
e.g. ec2-add-keypair key1
The output will be something like the following:

KEYPAIR key1
-----BEGIN RSA PRIVATE KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END RSA PRIVATE KEY-----

Copy the string starting from -----BEGIN RSA PRIVATE KEY----- up to -----END RSA PRIVATE KEY----- and save it in your keys directory, say in the /home/azeez/.ec2/keys/id_key1 file. Make sure that only the owner can read & write to that file.
i.e. chmod 600 /home/azeez/.ec2/keys/id_key1

1. Launch an instance of ami-0757b26e, providing a key, say key1, which you generated in step 0
ec2-run-instances ami-0757b26e -k key1
or you could use the ElasticFox GUI to do the same thing
The output will be something similar to
---------------------------------------------------------------------------------------------------
RESERVATION r-d5825cbc 610968236798 default
INSTANCE i-5c7dd335 ami-0757b26e pending key1 0 m1.small 2008-10-20T03:25:27+0000 us-east-1b aki-a71cf9ce ari-a51cf9cc
---------------------------------------------------------------------------------------------------

2. Connect to that instance using SSH,
e.g. ssh -i /home/azeez/.ec2/keys/id_key1 root@ec2-67-202-60-248.compute-1.amazonaws.com

3. Make the necessary changes to that instance. For example, you may install some custom software on that instance.

4. Upload your Amazon Web Services (AWS) private key (PK) & certificate (CERT) files to that instance. You can use scp to do this.
scp -i /home/azeez/.ec2/keys/id_key1 pk-XXX.pem cert-xxx.pem root@ec2-75-101-215-95.compute-1.amazonaws.com:/mnt/

5. On that instance, create an image of the current setup.
ec2-bundle-vol -k /mnt/pk-xxx.pem -c /mnt/cert-xxx.pem -u [user-id] -d /mnt

pk-xxx.pem = the PK file you uploaded in step 4
cert-xxx.pem = the CERT file you uploaded in step 4.
user-id = Your AWS User ID

In this step, you may wish to exclude some directories from the new image. Use the -e option followed by the ABSOLUTE path of the directories to be excluded. By default, some directories, like /mnt/, are excluded during image creation.

6. Create a bucket in Amazon S3. You can use s3fox to do this using a GUI, or use the command line tooling.

7. Upload the newly created image to your S3 bucket which was created in step 6
ec2-upload-bundle -b [your-s3-bucket] -m /mnt/image.manifest.xml -a [aws-access-key-id] -s [aws-secret-access-key-id]
aws-access-key-id = your AWS access key
aws-secret-access-key-id = your AWS secret access key.

8. Register the image. On your local machine, run
ec2-register [your-s3-bucket]/image.manifest.xml
The AMI ID will be displayed if the image was successfully registered. Say this was ami-af34d0c6

9. Test your image. Launch an instance of your new image. On your local machine run, e.g.
ec2-run-instances ami-af34d0c6 -k key1
or you could use the ElasticFox GUI to do the same thing

10. Connect to your new instance using SSH. This is similar to step 2.

That's it. You have just created your own AMI.

If you would like to make your AMI public, do the following:
1. ec2-modify-image-attribute --launch-permission -a all
2. Check the launch permissions of an AMI
ec2-describe-image-attribute -l
ami_id= the ID of the AMI

Saturday, October 18, 2008

How to add a tag cloud to blogger

I followed this article http://phy3blog.googlepages.com/Beta-Blogger-Label-Cloud.html

Just followed everything to the letter, and got the nice looking tag cloud you see on this page

Tuesday, October 14, 2008

Making Openoffice work with dark themes



I recently installed the SlicknesS dark Gnome theme, which has a polished look and feel. However, Openoffice did not work properly with this theme and it seems that due to a bug in Openoffice, it does not work well with dark themes. So the solution was to run Openoffice with a compatible theme while running the rest of the applications with my favorite dark theme. Here is how to do that;

1. Rename /usr/bin/openoffice.org2.4 to /usr/bin/openoffice.org2.4BIN
2. Create a new file called /usr/bin/openoffice.org2.4 and add the following content
#!/bin/sh
env GTK2_RC_FILES=/usr/share/themes/Clearlooks/gtk-2.0/gtkrc openoffice.org2.4BIN "$@"
3. Make /usr/bin/openoffice.org2.4 executable
4. That's it!

The screenshot of my desktop shows gcalctool & terminator running with the default SlicknesS theme, while Openoffice writer is running with the Clearlooks theme.

In step 2, we are setting the theme only for the openoffice.org2.4BIN command. You can do the same for other applications too, if you need to run them with a different theme (not the default theme)
e.g. env GTK2_RC_FILES=/usr/share/gdm/themes/Human/gtk-2.0/gtkrc gedit
will launch gedit with the Human theme