Saturday, May 2, 2015

How to build WSO2 ESB from source and remote debugging the source code

In this post I'll describe how to build the WSO2 ESB from the source code and how to remote debug the WSO2 ESB code using IntelliJ IDEA. 

Remote debugging is important to understand how the product is working.

This post contains five main parts.

1. Setup the environment.
2. Clone source code base from Git Hub.
3. Building the product from source.
4. Running the product.
5. Remote debugging WSO2 ESB code base using  IntelliJ IDEA.

1. Setup the environment.

Before building and remote debugging we need to have following things in our computer. All these are free. We can easily download and install.

1. JDK

2. Maven - https://maven.apache.org/ 

3. intelliJ IDEA (Community Edition) - https://www.jetbrains.com/idea/download/

Note : we need to set following environment variable :
MAVEN_OPTS="-Xms1024m -Xmx4096m -XX:MaxPermSize=1024m"
This is to avoid the Maven OutOfMemoryError.

For more information please read the documentation :

2. Clone source code base from Git Hub.

We need to clone the source for the WSO2 ESB from Git Hub. It is 100% open source and released under Apache license.

The code is in three repositories as

1. wso2-synapse
https://github.com/wso2/wso2-synapse

2. carbon mediation
https://github.com/wso2/carbon-mediation

3. product esb.
https://github.com/wso2/product-esb

Clone each of these repositories one by one. (If you are planing to send pull requests before cloning fork the repo)
You can copy the clone URL from the right hand side box in Git Hub repository page.


Change the directory where you want to clone the source. Then use “git clone” command to clone the source.
Eg:
wso2-synapse
git clone https://github.com/wso2/wso2-synapse.git

carbon-mediation
git clone https://github.com/wso2/carbon-mediation.git

product-esb
https://github.com/wso2/product-esb.git

After cloning all you would see three repositories named
wso2-synapse
carbon-mediation
product-esb

Open up each repository and you will see a project object model (POM) file inside each of them. This file is used by Maven  to build the source.

3. Building the product from source.

We need to build all three repositories in the following order.

1. wso2-synapse
2. carbon-mediation
3. product-esb

There are three commands that we can use to build the source.

1. mvn clean install -Dmaven.test.skip=true

This command will generate the binary and source distributions, without running any of the unit tests.

2. mvn clean install

This command will generate the binary and source distributions, with running unit tests.
If you run this command most of the time test cases might get failed so I prefer the first command.

3. After building the product once using a above command you can use
mvn clean install -Dmaven.test.skip=true -o

This command will generate binary and source distributions, without running any of the unit tests, in off line mode.

So now navigate to each folder in above order and run  mvn clean install -Dmaven.test.skip=true in a terminal.

After a successful build you should see a BUILD SUCCESS message.
For an example after building wso2-synapse you would see following lines at the bottom of the terminal.


INFO] Apache Synapse .................................... SUCCESS [3.774s]
[INFO] Apache Synapse - Secure vault ..................... SUCCESS [5.571s]
[INFO] Apache Synapse - Commons classes .................. SUCCESS [6.501s]
[INFO] Apache Synapse - Transports ....................... SUCCESS [1.058s]
[INFO] Apache Synapse - Non-blocking HTTP/s Transport .... SUCCESS [9.755s]
[INFO] Apache Synapse - PIPE Transport ................... SUCCESS [2.606s]
[INFO] Apache Synapse - VFS Transport .................... SUCCESS [4.536s]
[INFO] Apache Synapse - Tasks classes .................... SUCCESS [1.478s]
[INFO] Apache Synapse - Core ............................. SUCCESS [36.741s]
[INFO] Apache Synapse - FIX Transport .................... SUCCESS [4.929s]
[INFO] Apache Synapse - Extensions ....................... SUCCESS [4.734s]
[INFO] Apache Synapse - Samples .......................... SUCCESS [4.049s]
[INFO] Apache Synapse - Patches .......................... SUCCESS [3.552s]
[INFO] Apache Synapse - Experimental code ................ SUCCESS [1.628s]
[INFO] Apache Synapse - Web Application .................. SUCCESS [28.018s]
[INFO] Apache Synapse - Handler Module ................... SUCCESS [6.053s]
[INFO] Apache Synapse - XAR Maven Plugin ................. SUCCESS [7.084s]
[INFO] Apache Synapse - Configuration Migrator ........... SUCCESS [1.440s]
[INFO] Apache Synapse - Distribution ..................... SUCCESS [19.387s]
[INFO] Apache Synapse - Package skeleton ZIP ............. SUCCESS [1.238s]
[INFO] Apache Synapse - Package archetype ................ SUCCESS [4.550s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2:44.279s
[INFO] Finished at: Fri May 01 21:27:46 IST 2015
[INFO] Final Memory: 147M/630M
[INFO] ------------------------------------------------------------------------
After building all three code bases to find the product (WSO2 ESB) open product-esb >> modules >> distribution >> target.
In there you should see a zip archive named wso2esb-4.9.0-M8-SNAPSHOT.zip.


This name can change based on  the version. This is the binary distribution of the WSO2 ESB you can  now run the built product.

4. Running the product.

If you want to test run the product just built, extract the zip archive and change directory to ESB_HOME >> bin and run sh wso2server.sh . Shutdown the server using ctrl+c
For more information about running the product please visit: https://docs.wso2.com/display/ESB481/Running+the+Product

5. Remote debugging WSO2 ESB code base using  IntelliJ IDEA.

In this part I will describe how to remote debug the source using intelliJ IDEA. For this demonstration I'll use ESB with sample 0 configuration. However you can remote debug any of the code in the same way based on your requirement.
Here we have to do three things. First open the code base form inteliJ IDEA, edit run configuration and run the ESB sample 0.

  • Open wso2-synapse code from intelliJ IDEA
First open the J IDEA and select File >> Open. Then navigate to the location where you cloned the wso2-synapse  code base and select pom.xml inside the wso2-synapse maven project. Hit OK to open the project.


After opening the project you will be able to see the project structure like this.

  • Edit run configurations
Now we need to edit run configurations of the Run/debug Configurations JIDEA to remote debug. Select Run >> Edit configurations.



Click the + button in the top left corner of the and select Remote. To edit remote debug configuration.


In the configuration give a suitable name and keep all other fields as default.


 Click Apply and OK to save the changes.

  • Running the sample 0.
Now we need to run ESB with sample 0.

First deploy SimpleStockQuoteService sample in the axis2server.

Run axis2server.
Navigate to ESB_HOME >> samples >> axis2Server and in a terminal execute
sh axis2server.sh to run the axis2 server.

Deploy  SimpleStockQuoteService.
Navigate to  ESB_HOME >> samples >> axis2Server >> src >> SimpleStockQuoteService and in a terminal run ant to deploy the service in the server.

You can find more information about running sample 0 from here :

https://docs.wso2.com/display/ESB481/Sample+0%3A+Introduction+to+ESB

Start the ESB with sample 0 configuration with listening to the port 5005.
Navigate to ESB_HOME >> bin and execute sh wso2server.sh -sn 0 -debug 5005

You would see starting the ESB has been paused and the ESB is listening to port 5005. (Check the console)

Listening for transport dt_socket at address: 5005

Now open up intelliJ IDEA. From the Run menu you can select the debug option. In my case it is “Debug  wso2_esb_remote_debug”.

Or else you can simply start remote debug by just clicking the “bug” icon in the menu bar.


Make sure that you have selected the correct configuration.

When the debug session is starting you would see Connected to the target VM, address: 'localhost:5005', transport: 'socket' in intelliJ IDEA console. Then the starting of ESB will continue.


Next we need to place a break point in the source code.
I select SynapseCallbackReceiver class inside the synapse-core >> src >> main >> java >> org.apache.synapse.core.axis2 package.


I will place a break point at the receive method in SynapeCallbackReciver class. I selected this method because when  a new response message is received this method get invoked. So we can easily start debug from here.


To run stockQuote client navigate to ESB_HOME >> samples >> axis2Client and in a terminal run following command to execute the stockQuote client in the smart client mode.

ant stockquote -Daddurl=http://localhost:9000/service/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/

Now you will see that IntelliJ IDEA will get focused as soon as execution has been reached  the breakpoint.

Now from here you can test the execution steps using the options provided by intelliJ IDEA. (F8 F9 etc.)



8 comments:

  1. A very well explained guide to start with WSO2 ESB. Thanks for the post.

    ReplyDelete
  2. Successfully build WSO2ESB 4.9.0.
    If there is a way configure environment(idea/eclipse) to run full debug including starting server from IDE. Because it is really doesn't work good if i did some changes in wso-synapse code and then have to build it to ensure that maven will push newly built jars into local repository and then build again product-esb project to get package ready to run and debug. Cycle to long for simple changes.

    ReplyDelete
    Replies
    1. You can get help from WSO2 development community. Post your question to their dev group.

      Delete
  3. Nice post. Thank you. This is helpful :)

    ReplyDelete
  4. when i start axis2server getting exception
    \product-esb\modules\distribution\target\wso2esb-5.0.0-M3-S
    NAPSHOT\samples\axis2Server>axis2server.bat -http 9000 -https 9002 -name MyServer1


    below are the logs

    [2016-03-29 19:24:07,505] INFO {org.apache.axis2.transport.jms.JMSSender} - JM
    S Transport Sender initialized...
    [2016-03-29 19:24:07,673] INFO {org.apache.axis2.deployment.DeploymentEngine} -
    Deploying Web service: SimpleStockQuoteService.aar - file:/D:/wso2/source/GitH
    ub/PRODUC~1/modules/DISTRI~1/target/WSO2ES~1.0-M/samples/AXIS2S~1/repository/ser
    vices/SimpleStockQuoteService.aar
    [2016-03-29 19:24:07,759] INFO {org.apache.synapse.transport.nhttp.HttpCoreNIOL
    istener} - HTTPS Listener started on 0:0:0:0:0:0:0:0:9002
    [2016-03-29 19:24:07,762] INFO {org.apache.synapse.transport.nhttp.HttpCoreNIOL
    istener} - HTTP Listener started on 0.0.0.0:9000
    [2016-03-29 19:24:07,762] INFO {samples.util.SampleAxis2ServerManager} - [Simp
    leAxisServer] Started
    [2016-03-29 19:24:07,763] WARN {org.apache.synapse.transport.nhttp.HttpCoreNIOL
    istener} - System may be unstable: IOReactor encountered a checked exception :
    Address already in use: bind
    java.net.BindException: Address already in use: bind
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:444)
    at sun.nio.ch.Net.bind(Net.java:436)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:
    214)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:67)
    at org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processSes
    sionRequests(DefaultListeningIOReactor.java:243)
    at org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEve
    nts(DefaultListeningIOReactor.java:146)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute
    (AbstractMultiworkerIOReactor.java:349)
    at org.apache.synapse.transport.nhttp.HttpCoreNIOListener$2.run(HttpCore
    NIOListener.java:298)
    at java.lang.Thread.run(Thread.java:745)



    where can i change the ports to avoid conflicts

    ReplyDelete
    Replies
    1. It seems like you are trying to run on a port which is already occupied according to the error logs.

      Delete