Monday, January 23, 2012

Hibernate: Mapping Many-to-Many Associations

Overview:
This article will look at different ways of how you can map many-to-many associations in Hibernate.

Approach1: Mapping as many-to-one associations without an association entity.
Approach2: Mapping as many-to-one associations with an association entity as many-to-one.
Approach3: Mapping as many-to-one associations using composite-elements.

Approach1:
Mapping as many-to-one associations without an association entity. This approach is one of the most common ways of mapping a many-to-many association, there will be NO separate entity class to model the association between a Player and a Club.
Association Diagram
__________
|    Club         |
-----------------
       |*
       |
____|*____
|    Player     |
----------------
Class Diagram
___________
|Player             |
-------------------
|id:long            |
|name:String    |
|clubs:Set         |
-------------------
__________________
|Club                             |
------------------------------
|id:long                          |
|name:String                  |
|contractedPlayers:Set   |
------------------------------
Following is the database structure,
CREATE TABLE CLUB (
  club_id INTEGER NOT NULL,
  name VARCHAR(50),
  PRIMARY KEY (id)
);
CREATE TABLE PLAYER (
  player_id INTEGER NOT NULL,
  name VARCHAR(50),
  PRIMARY KEY (id)
);
CREATE TABLE CONTRACT (
  club_id,
  player_id,
  PRIMARY KEY (club_id, player_id),
  FOREIGN KEY (club_id) REFERENCES CLUB(club_id),
  FOREIGN KEY (player_id) REFERENCES PLAYER(player_id),
);  
Following is the hibernate mapping involved,
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="org.fazlan.beans.Club">
     <id name="id" column="club_id">
        <generator class="increment" />
     </id>
     <property name="name" />
     <set name="contractedPlayers" table="contract" inverse="true">
        <key column="club_id" />
        <many-to-many class="Player" column="player_id"/>
     </set>
  </class>
  <class name="org.fazlan.beans.Player">
     <id name="id" column="player_id">
        <generator class="increment" />
     </id>
     <property name="name" />
     <set name="clubs" table="contract">
        <key column="player_id" />
        <many-to-many class="Club" column="club_id" />
     </set>
  </class>
</hibernate-mapping>
However, with this approach, we cannot model data specific to the association with the contract(e.i: start-date and end-date of the contract). The next approach will look at how we can model such many-to-many associations.

Approach2:
Mapping as many-to-one associations with an association entity. With this way, we can easily model additional data related to the association. This is achieved by having an entity class to model the association as many-to-one.

Association Diagram
_______________
|    Club       |
-----------------
|
______|*_______
|    Contract   |
-----------------
|*
______|________
|    Player     |
-----------------

Class Diagram
_______________
|Player         |
-----------------
|id:long        |
|name:String    |
-----------------
_______________
|Club           |
-----------------
|id:long        |
|name:String    |
-----------------
______________________________
|Contract                      |
--------------------------------
|contract_id:long              |
|club:Club                     |
|player:Player                 |
|startDate:Date                |
|endDate:Date                  |
--------------------------------
Here, the association between a Player and a Club will be represented using an association entity, namely Contract. Following is the database structure,
CREATE TABLE CLUB (
  club_id INTEGER NOT NULL,
  name VARCHAR(50),
  PRIMARY KEY (id)
);
CREATE TABLE PLAYER (
  player_id INTEGER NOT NULL,
  name VARCHAR(50),
  PRIMARY KEY (id)
);
CREATE TABLE CONTRACT (
  contract_id INTEGER NOT NULL,
  club_id,
  player_id,
  start_date Date,
  end_date Date,
  PRIMARY KEY (contract_id),
  FOREIGN KEY (club_id) REFERENCES CLUB(club_id),
  FOREIGN KEY (player_id) REFERENCES PLAYER(player_id),
); 
Following is the Hibernate mapping involved,
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="org.fazlan.beans.Club">
     <id name="id" column="club_id">
        <generator class="increment" />
     </id>
     <property name="name" />
  </class>
  <class name="org.fazlan.beans.Player">
     <id name="id" column="club_id">
        <generator class="increment" />
     </id>
    <property name="name" />
  </class>
  <class name="org.fazlan.beans.Contract">
     <id name="id" column="contract_id">
        <generator class="increment" />
     </id>
     <property name="startDate" column="start_date"/>
     <property name="endDate" column="end_date"/>
     <many-to-one name="club" column="club_id" not-null="true" />
     <many-to-one name="player" column="player_id" not-null="true" />
  </class>
</hibernate-mapping>
Alternatively, you can model the many-to-many relationship using an composite-element. The next section looks at this.

Approach3:
Mapping as many-to-one associations using composite-elements.
Association Diagram
_______________
|    Club       |
-----------------
    |
______|*_______
|    Contract   |
-----------------
    |*
______|________
|    Player     |
-----------------

Class Diagram
_______________
|Player         |
-----------------
|id:long        |
|name:String    |
-----------------
_______________
|Club           |
-----------------
|id:long        |
|name:String    |
|contracts:List |
-----------------
______________________________
|Contract                      |
--------------------------------
|id:long              |
|player:Player                 |
|startDate:Date                |
|endDate:Date                  |
--------------------------------
Following is the database structure,
CREATE TABLE CLUB (
  club_id INTEGER NOT NULL,
  name VARCHAR(50),
  PRIMARY KEY (id)
);
CREATE TABLE PLAYER (
  player_id INTEGER NOT NULL,
  name VARCHAR(50),
  PRIMARY KEY (id)
);
CREATE TABLE CONTRACT (
  contract_id INTEGER NOT NULL,
  club_id,
  player_id,
  start_date Date,
  end_date Date,
  PRIMARY KEY (contract_id),
  FOREIGN KEY (club_id) REFERENCES CLUB(club_id),
  FOREIGN KEY (player_id) REFERENCES PLAYER(player_id),
);
Following is the Hibernate mapping involved,
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="org.fazlan.beans.Club">
     <id name="id" column="club_id">
        <generator class="increment" />
     </id>
     <property name="name" />
     <list name="contracts" table="contract">
        <key column="club_id" />
        <index-column column="contract_id" />        
        <composite-element class="org.fazlan.beans.Contract">
             <property name="startDate" column="start_date"/>
             <property name="endDate" column="end_date"/>
             <many-to-one name="player" column="player_id">
        </composite-element>
     </list>
  </class>
  <class name="org.fazlan.beans.Player">
     <id name="id" column="player_id">
        <generator class="increment" />
     </id>
     <property name="name" />
  </class>
</hibernate-mapping>
Summary:
This article looked at how you can map many-to-many associations in different ways depending on the data you need to capture.

Thursday, January 19, 2012

Hibernate: Mapping Parent/Child Relationship

Overview:
This post will look at how you map bi-directional one-to-many association. It's one of the most common association types that exists, and the semantics in mapping the association with cascade the parent/child relationship.

Relationship:

1 0..m
| Parent | ----------------- | Child |

Database tables:

CREATE TABLE Parent(
parent_id INTEGER NOT NULL,
PRIMARY KEY (parent_id)
);
CREATE TABLE Child(
child_id INTEGER NOT NULL,
parent_id INTEGER NOT NULL,
PRIMARY KEY (child_id),
FOREIGN KEY (parent_id) REFERENCES Parent
);

POJOs:

package org.fazlan;

public class Parent {
private long id;
private Set children = new HashSet();
// getters and setters
}

package org.fazlan;

public class Child {
private long id;
private Parent parent;
// getters and setters
}

Hibernate Mapping:
Lets look at the basic mapping the parent and child entities,


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.fazlan">
<class name="Parent" table="parent">
. . .
<set name="children" inverse="true">
  <key column="parent_id" />
  <one-to-many class"Child" />
</set>
</class>

<class name="Child" table="child">
. . .
<many-to-one name="parent" column="parent_id" not-null="true"/>
</class>
</hibernate-mapping>
Now that the Child entity is managing the state of the link(parent_id), and we declare the Child entity is the one that manages the relationship. We use the 'inverse' attribute to do this.

The following code is used to add a Parent,
Parent p1 = new Parent();  session.save(p1);  session.flush();
SQL generated by Hibernate,
Hibernate: select max(parent_id) from hibernatedb.Parent
Hibernate: insert into hibernatedb.Parent (parent_id) values (?)
The following code is used to add a Child,
Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
c.setParent(p);
p.getChildren().add(c);
session.save(c);
session.flush();
Alternatively, you can add the following method to parent.

public void addChild(Child c) {
c.setParent(this);
getChildren().add(c);
}
Updated code will look like this,
Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
p.addChild(c);
session.save(c);
session.flush();
NOTE:
  • When inverse="false" (default), Hibernate will generate TWO SQL statements: INSERT to create the child. UPDATE to create the link between parent and child.
<set name="children" inverse="false" >
<key column="parent_id" />
<one-to-many class"Child" />
</set>
SQL generated by Hibernate,
Hibernate: insert into hibernatedb.Child (parent_id, child_id) values (?, ?)
Hibernate: update hibernatedb.Child set parent_id=? where child_id=?
  • When inverse="true", Hibernate generates ONLY ONE SQL statement: INSERT the child and the parent's id.
<set name="children" inverse="true" >
<key column="parent_id" />
<one-to-many class"Child" />
</set>
SQL generated by Hibernate,
Hibernate: insert into hibernatedb.Child (parent_id, child_id) values (?, ?)
Using Cascade associations:
You can get rid of the explicit call to the save() by using cascase attribute to the collection mapping.
<set name="children" inverse="true" cascase="all">
<key column="parent_id" />
<one-to-many class"Child" />
</set>
Simplified code,
Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
p.addChild(c);
session.flush();
This will insert the new child to the database. Also, the following code will now delete the parent and all it's children.
Parent p = (Parent) session.load(Parent.class, pid);
session.delete(p);
session.flush();
However, the following will not remove c from the database. In this case, it will only remove the link to p and cause a NOT NULL constraint violation.
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c); // remove link
c.setParent(null); // NOT NULL constraint violation
session.flush(); 
to achieve this, you need to explicitly call the delete() on the Child.
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c);
session.delete(c);
session.flush();
But, a Child cannot exist without its parent. So if we remove a Child from the collection, we do want it to be deleted. To do this, we must use cascade="all-delete-orphan".
<set name="children" inverse="true" cascade="all-delete-orphan">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
Updated code, Now, removing the child from the collection would also will result in removing the child from the database
Parent p1 = (Parent) session.get(Parent.class,1l);
Child c1 = p1.getChildren().iterator().next();
p1.getChildren().remove(c1);
session.flush();
Summary:
This post looked at how you can map Parent/Child relationship efficiently in Hibernate, and also briefly looked at the 'inverse' and 'cascade' features.

Sunday, January 8, 2012

Creating Java and Web Project with Maven3

Overview
This post shows how to create a Java and Web application project with Maven3.

Creating a Java project

mvn archetype:generate -DarchetypeArtifactId=maven-archetyp-quickstart -DgroupId=org.fazlan -DartifactId=org.fazlan.sample.java.project -Dversion=1.0.0-SNAPSHOT -DinteractiveMode=false

Creating a Web application project

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=org.fazlan -DartifactId=org.fazlan.sample.webapp.project -Dversion=1.0.0-SNAPSHOT -DinteractiveMode=false

Developing a Web Service Client using Axis2

Overview:
This article looks at how to create a service stub using Axis2 from a WSDL also know as a Web Service contract(refer here).

Pre-requisite:
Apache Axis2 1.6.1
Apache Tomcat
Apache Maven3

Sample code used can be found here.
Steps:
1. Create a project using the following,
mvn archetype:generate -DgroupId=org.fazlan -DartifactId=org.fazlan.employee.service.stub -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0-SNAPSHOT -DinteractiveMode=false

2. Now, access the WSDL file (http://localhost:8080/axis2/services/EmployeeService?wsdl) and save as org.fazlan.employee.service.stub/src/main/resources/EmployeeService.wsdl.

3. Update the pom.xml to include the axis2 dependencies and plug-ins to generate the artifacts from the WSDL file as follows,

1: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2: xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3: <modelVersion>4.0.0</modelVersion>
4: <groupId>org.fazlan</groupId>
5: <artifactId>org.fazlan.employee.service.stub</artifactId>
6: <packaging>jar</packaging>
7: <version>1.0-SNAPSHOT</version>
8: <name>org.fazlan.employee.service.stub</name>
9: <url>http://maven.apache.org</url>
10: <dependencies>
11: <dependency>
12: <groupId>org.apache.axis2</groupId>
13: <artifactId>axis2</artifactId>
14: <version>${axis2.version}</version>
15: </dependency>
16: <dependency>
17: <groupId>wsdl4j</groupId>
18: <artifactId>wsdl4j</artifactId>
19: <version>${wsdl4j.version}</version>
20: </dependency>
21: <dependency>
22: <groupId>org.apache.ws.commons.axiom</groupId>
23: <artifactId>axiom-api</artifactId>
24: <version>${axiom.api.version}</version>
25: </dependency>
26: <dependency>
27: <groupId>commons-logging</groupId>
28: <artifactId>commons-logging</artifactId>
29: <version>${commons-logging.version}</version>
30: </dependency>
31: <dependency>
32: <groupId>org.apache.neethi</groupId>
33: <artifactId>neethi</artifactId>
34: <version>${neethi.version}</version>
35: </dependency>
36: <dependency>
37: <groupId>org.apache.ws.commons.schema</groupId>
38: <artifactId>XmlSchema</artifactId>
39: <version>${XmlSchema.version}</version>
40: </dependency>
41: <dependency>
42: <groupId>org.apache.ws.commons.axiom</groupId>
43: <artifactId>axiom-impl</artifactId>
44: <version>${axiom-impl.version}</version>
45: </dependency>
46: <dependency>
47: <groupId>org.apache.axis2</groupId>
48: <artifactId>axis2-transport-local</artifactId>
49: <version>${axis2.version}</version>
50: </dependency>
51: <dependency>
52: <groupId>org.apache.axis2</groupId>
53: <artifactId>axis2-transport-http</artifactId>
54: <version>${axis2.version}</version>
55: </dependency>
56: </dependencies>
57: <build>
58: <plugins>
59: <plugin>
60: <groupId>org.apache.maven.plugins</groupId>
61: <artifactId>maven-antrun-plugin</artifactId>
62: <version>1.1</version>
63: <executions>
64: <execution>
65: <id>source-code-generation</id>
66: <phase>process-resources</phase>
67: <goals>
68: <goal>run</goal>
69: </goals>
70: <configuration>
71: <tasks>
72: <java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true">
73: <arg line="-uri src/main/resources/EmployeeService.wsdl -u -uw -o target/generated-code
74: -p org.fazlan.employee.service.stub
75: -ns2p http://service.employee.fazlan.org=org.fazlan.employee.service.stub,http://beans.service.employee.fazlan.org/xsd=org.fazlan.employee.service.stub.beans.xsd,http://exceptions.service.employee.fazlan.org/xsd=org.fazlan.employee.service.stub.exceptions.xsd"/>
76: <classpath refid="maven.dependency.classpath"/>
77: <classpath refid="maven.compile.classpath"/>
78: <classpath refid="maven.runtime.classpath"/>
79: </java>
80: </tasks>
81: </configuration>
82: </execution>
83: </executions>
84: </plugin>
85: <plugin>
86: <groupId>org.codehaus.mojo</groupId>
87: <artifactId>build-helper-maven-plugin</artifactId>
88: <executions>
89: <execution>
90: <id>add-source</id>
91: <phase>generate-sources</phase>
92: <goals>
93: <goal>add-source</goal>
94: </goals>
95: <configuration>
96: <sources>
97: <source>
98: target/generated-code/src
99: </source>
100: </sources>
101: </configuration>
102: </execution>
103: </executions>
104: </plugin>
105: </plugins>
106: </build>
107: <properties>
108: <axis2.version>1.6.1</axis2.version>
109: <wsdl4j.version>1.6.2</wsdl4j.version>
110: <commons-logging.version>1.1.1</commons-logging.version>
111: <neethi.version>2.0.4</neethi.version>
112: <axiom.api.version>1.2.12</axiom.api.version>
113: <axiom-impl.version>1.2.12</axiom-impl.version>
114: <XmlSchema.version>1.4.7</XmlSchema.version>
115: </properties>
116: </project>

4. Build the project to generate the artifacts required,

mvn clean install

The generated artifacts will be packaged in the org.fazlan.employee.service.stub-1.0-SNAPSHOT.jar. You then add this jar as a dependency to the client project that needs to access the Employee Web Service.

5. Write a simple Java client (You may need to include all the axis2 dependencies to run this client).

1: import org.apache.axis2.AxisFault;
2: import org.fazlan.employee.service.stub.beans.xsd.Employee;
3: public class Main {
4: public static void main(String... args) throws Exception {
5: EmployeeServiceStub service = new EmployeeServiceStub();
6: Employee e = new Employee();
7: e.setId(1);
8: e.setFirstName("Fazlan");
9: e.setLastName("Sabar");
10: int id = service.addEmployee(e);
11: System.out.println(id);
12: Employee[] employees = service.getAllEmployees();
13: for(Employee em : employees) {
14: System.out.println(em.getId());
15: System.out.println(em.getFirstName());
16: System.out.println(em.getLastName());
17: System.out.println("---------------");
18: }
19: }
20: }

6. Sample output.

0
Fazlan
Sabar
---------------
1
Fazlan
Sabar
---------------
Summary:
This articles looked at how to generate artifacts using Axis2 with Maven3 to interact with the Web Service contract (WSDL).

Saturday, January 7, 2012

Develop Code-First Web Services using Axis2


Overview:
This article is simple, but provides a good foundation of creating a Web Service from an existing Java code using Apache Axi2 and Maven3.

Pre-requisites:
Apache Axis2 1.6.x
Apache Tomcat
Apache Maven3

Sample code used for this can be found here.
Steps:
1. Create a Maven project,

mvn archetype:generate -DgroupId=org.fazlan -DartifactId=org.fazlan.employee.service -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0-SNAPSHOT -DinteractiveMode=false

Now, the project structure should be like the following,

org.fazlan.employee.service
`-- src
     |-- main
     |    `-- java
     |         `-- org
     |             `-- fazlan
     |                 `-- employee
     |                     `-- service
     |     
     `-- test 
          `-- java
               `-- org
                   `-- fazlan

2. Update the pom.xml to add the 'axis2-aar-maven-plugin' plugin.
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  <modelVersion>4.0.0</modelVersion>  
  <groupId>org.fazlan</groupId>  
  <artifactId>org.fazlan.employee.service</artifactId>  
  <packaging>aar</packaging>  
  <version>1.0-SNAPSHOT</version>  
  <name>org.fazlan.employee.service</name>  
  <url>http://maven.apache.org</url>  
  <build>  
     <plugins>  
       <plugin>  
         <groupId>org.apache.axis2</groupId>  
         <artifactId>axis2-aar-maven-plugin</artifactId>  
         <version>1.6.1</version>  
         <!--<version>${orbit.version.axis2}</version>-->  
         <extensions>true</extensions>  
         <configuration>  
           <aarName>org.fazlan.employee.service</aarName>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
 </project>  


3. I have a service class to manage employee details, and the classes looks like this,
 POJO to model employee,  
 //org.fazlan.employee.service.beans.Employee.java  
 public class Employee {  
   private int id;  
   private String firstName;  
   private String lastName;  
   // getter and setter methods  
 }  
 POJO to model the employee exception,  
 //org.fazlan.employee.service.exceptions.EmployeeException.java  
 public class EmployeeException extends java.lang.Exception {  
 }  
 The service class with the logic to manage employees,  
 //org.fazlan.employee.service.EmployeeService.java  
 public class EmployeeService {  
   private static final Map employeeMap = new HashMap();  
   private static int index = 0;  
   public int addEmployee(Employee employee) throws EmployeeException {  
    employee.setId(++index);  
    employeeMap.put(index, employee);  
    return index;  
   }  
   public Employee getEmployee(int employeeId) throws EmployeeException {  
    return employeeMap.get(employeeId);  
   }  
   public Employee[] getAllEmployees() throws EmployeeException{  
    return employeeMap.values().toArray(new Employee[employeeMap.size()]);  
   }  
 }  


4. Create the service descriptor src/main/resources/META-INF/services.xml as follows,
 <service name="EmployeeService" scope="application">  
 <messageReceivers>  
    <!--messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"  
         class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/-->  
    <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"  
         class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>  
  </messageReceivers>  
   <parameter name="ServiceClass">  
     org.fazlan.employee.service.EmployeeService  
   </parameter>  
 </service>  

5. Now the project structure should look like the following,
org.fazlan.employee.service
`-- src
|-- main
|   |-- java
|   |    `-- org
|   |         `-- fazlan
|   |              `-- employee
|   |                   `-- service
|   |                       |-- beans
|   |                       |-- exceptions
|   |                       `-- util
|   `-- resources
|       `-- META-INF
`-- test
     `-- java
         `-- org
             `-- fazlan

6. Build the project and pack the aar file.

mvn clean install

7. Deploy the axis2.war from the Axis2 distribution to Tomcat. After deploying you can verify by accessing http://localhost:8080/axis2/

8. Now, deploy the org.fazlan.employee.service.aar via the Axis2 administrator's console. (default username/password is admin/axis2).

9. After successfully deploying the service, you can access the WSDL via http://localhost:8080/axis2/services/EmployeeService?wsdl


Summary:

This article looked at how you can create a Web Service using Axis2 in a nutshell.

Friday, March 25, 2011

SSH and SCP

This looks at how to SSH and SCP on default and non-standard ports

SSH
running on default port is 22.
 ssh <user>@<host>  (e.i ssh foouser@barserver)

running on non-standard port.
 ssh -p  <port> <user>@<host>  (e.i ssh -p 2000 foouser@barserver)

SCP
running on default port is 22.
 scp <file> <user>@<host>:<host-path-to-copy>  (e.i scp foo.txt foouser@barserver:/home/foouser/directory1)

running on non-standard port.
 scp -P <port> <file> <user>@<host>:<host-path-to-copy>  (e.i scp -P 2000 foo.txt foouser@barserver:/home/foouser/directory1)

Building WSO2 Carbon from WSO2 SVN trunk

Environment
Ubuntu 10.04

Applies To
WSO2 Carbon source trunk as of 22nd March, 2011.

Prerequisite
Install the following softwares,
JDK version 1.6.x
Mavan2 version 2.1.x
Subversion
- sudo apt-get update
- sudo apt-get install subversion

Environment Setup
Open up a terminal and type,
$ gedit ~/.bashrac &

Add the following lines at the end of ~/.bashrc file, which can be located under your home directory($HOME)
JAVA_HOME=
e.g: JAVA_HOME=/home/fazlan/sw-installables/jdk-1.6.22

M2_HOME=
e.g: M2_HOME=/home/fazlan/sw-installables/apache-maven-2.1.0

PATH=$PATH:$JAVA_HOME/bin:$M2_HOME/bin

Save and close the file.

Verify the version of them,

$ java --version
$ mvn --version

Checkout WSO2 Carbon
Create a directory to checkout the source code.
$ mkdir wso2-svn

Checkout the carbon source code from wso2 trunk to the directory just created.
$ cd wso2-svn
$ svn checkout http://svn.wso2.org/repos/wso2/trunk/carbon

Build WSO2 Carbon
Once the checking out of the source code is completed, you can build the code

$ mvn install -Dmaven.test.skip=true
Note: maven.test.skip=true - this will stip the test cases

WSO2 carbon needs to be build in the following order,

buidling dependencies required by carbon,
$ cd carbon/dependencies
$ cd carbon/orbit
$ cd carbon/service-stub
$ cd carbon/core
$ cd carbon/components
$ cd carbon/feature

building products,
$ cd carbon/products
where you can build a specific product by providing -Dproduct= property.
values can be = appserver, bam, bps, brs, cep, ds, esb, greg, gs, is, mb, ms
e.g mvn install -Dmaven.test.skip=true -Dproduct=greg

Possible Build-time Problems and Solutions
You might encounter certain problems while building the code,

problem: exceeding the number of open file descriptor
solution: increase the number of open file descriptor count
$ su
enter root password:
root $ gedit /etc/security/limits.conf &
Enter the following lines at the end of the file

* soft nofile 65536
* hard nofile 65536

Save and close file.
Summary
This post is aimed to help you building the WSO2 Carbon platform from the WSO2 SVN trunk and this post will be updated accordingly in the future to reflect the build statergy of wso2 carbon.