Showing posts with label Apache Maven. Show all posts
Showing posts with label Apache Maven. Show all posts

Monday, July 15, 2013

Creating an OSGi Bundle out of a Third Party Library for Using as WSO2 Product Dependency

WSO2 platform supports a modular based architecture where third party libraries which are used in WSO2 products are exposed into the environment as OSGi bundles. This blog post is about how to OSGify a third party library, to be used as a dependency inside WSO2 MB.

We have recently used 'Disruptor', a high performance inter-thread messaging library  as a dependency in WSO2 Message Broker for improving the performance by using disruptor based message writing operations into Cassandra storage. When doing this it is first needed to create an OSGi bundle out of 'Disruptor' library, so it can be referred in the runtime when Message Broker is running.

As common to all OSGi bundle generations, first you need to have a manifest.mf file which describes the bundle information, version info, which packages needed to be imported/exported etc. However as it is not easy to write this file correctly by hand we use maven-bundle-plugin in order to get this done. This process is common to any third party dependency and you can follow the same process in building an osgi bundle for any of them.

1. First let's create a directory named 'disruptor' inside <WSO2_Carbon_Source>/platform/dependencies/orbit/ directory. As we have used Disruptor 2.10.4 version i created a new package called 2.10.4-wso2v1 inside disruptor directory. (This is the common notation across the platform <LibraryVersion>-wso2v<VersionNumber>when naming the versions of the dependencies.)

2. Add a new maven build file (pom.xml) inside package 2.10.4-wso2v1.

3. Now let's add the required details which needs to generate the OSGi bundle into this file. This pom file can be used as a sample template by replacing the required entries when adding another dependency.

<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">

<parent>
   <groupId>org.wso2.carbon</groupId>
   <artifactId>carbon-dependents</artifactId>
   <version>4.1.0</version>
   <relativePath>../../../pom.xml</relativePath>
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>com.googlecode.disruptor.wso2</groupId>
<artifactId>disruptor</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Orbit - disruptor</name>
<version>2.10.4-wso2v1</version>
<description>This bundle exports packages from disruptor jar files</description>
<url>http://wso2.org</url>

<dependencies>
   <dependency>
      <groupId>com.googlecode.disruptor</groupId>
      <artifactId>disruptor</artifactId>
      <version>2.10.4</version>
      <optional>true</optional>
   </dependency>
</dependencies>

<build>
     <plugins>
            <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                 <version>1.4.0</version>
                 <extensions>true</extensions>
                 <configuration>
                      <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Name>${project.artifactId}</Bundle-Name>
                        <Export-Package>
                                com.lmax.disruptor.*;version=2.10.4,
                         </Export-Package>
                        <Import-Package>
                                !sun.misc,
                                *
                        </Import-Package>
                      </instructions>
                </configuration>
            </plugin>
     </plugins>
</build>

<!--<repositories>
    <repository>
       <snapshots>
          <enabled>true</enabled>
          <updatePolicy>daily</updatePolicy>
          <checksumPolicy>ignore</checksumPolicy>
    </snapshots>
    <id>wso2-maven2-snapshot-repository</id>
    <name>WSO2 Maven2 Snapshot Repository</name>
    <url>http://dist.wso2.org/snapshots/maven2/</url>
    <layout>default</layout>
  </repository>
</repositories>-->

<properties>
     <disruptor.build.version>2.10.4</disruptor.build.version>
     <disruptor.version>${disruptor.build.version}-wso2v1</disruptor.version>
 <disruptor.orbit.version>${disruptor.build.version}.wso2v1</disruptor.orbit.version>
</properties>
</project>


Let's go trough the important entries in the file.

<dependencies>
<dependency>
<groupId>com.googlecode.disruptor</groupId>
<artifactId>disruptor</artifactId>
<version>2.10.4</version>
<optional>true</optional>
</dependency>
</dependencies>


As we are using external library in the OSGi bundle we need to add this as a maven dependency entry for the bundle. You can find maven dependency entries of lot of libraries in here.

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Export-Package>
             com.lmax.disruptor.*;version=2.10.4,
</Export-Package>
<Import-Package>
             !sun.misc,
             *
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>


This is how we use maven-bundle-plugin to generate the disruptor osgi bundle. The Export-Package, Import-Package and DynamicImport-Package tags are used to control the exposure of certain packages to other bundles. With <Export-Package> tag it will find the defined project classes or dependencies, and they will be copied to the osgi bundle. With using <Import-Package> here, we can import the extra classes that have been referred from our osgi bundle. By keeping * as the value here by default it imports all the reference classes that needs for OSGi bundle generation. However when using default value here for 'disruptor bundle' i encountered the following error.

org.osgi.framework.BundleException: The bundle could not be resolved. Reason: Missing Constraint: Import-Package: sun.misc; version="0.0.0"

So I added the entry '!sun.misc' to resolve this issue and it seems as the sun.misc package is already there to be referred by the osgi framework, we need to tell that it is not needed to explicitly import it in this case. This is a 'Disruptor' bundle specific entry and you don't have to add the same configuration in each bundle you create. However if the bundle's classes use sun.misc package, this setting might be useful in resolving similar errors.


4. That's it! Save the pom file and build it with maven ( WSO2 projects use Maven3). You will see that in the <WSO2_Carbon_Source>/platform/dependencies/orbit/disruptor/2.10.4-wso2v1/target folder the newly created osgi bundle 'disruptor-2.10.4-wso2v1.jar' is present.

If you see the manifest.mf file of the new bundle it will be as follows.

Manifest-Version: 1.0
Export-Package: com.lmax.disruptor.collections;version="2.10.4",com.lm
ax.disruptor;uses:="com.lmax.disruptor.util";version="2.10.4",com.lma
x.disruptor.dsl;uses:="com.lmax.disruptor,com.lmax.disruptor.util";ve
rsion="2.10.4",com.lmax.disruptor.util;uses:="com.lmax.disruptor";ver
sion="2.10.4"
Ignore-Package: sun.misc
Built-By: <your_host_name>
Tool: Bnd-0.0.238
Bundle-Name: disruptor
Created-By: Apache Maven Bundle Plugin
Bundle-Version: 2.10.4.wso2v1
Build-Jdk: 1.6.0_30
Bnd-LastModified: 1373904351577
Bundle-ManifestVersion: 2
Bundle-Description: This bundle exports packages from disruptor jar fi
les
Bundle-SymbolicName: disruptor
Import-Package: com.lmax.disruptor;version="2.10.4",com.lmax.disruptor
.collections;version="2.10.4",com.lmax.disruptor.dsl;version="2.10.4"
,com.lmax.disruptor.util;version="2.10.4"



To know more about creating OSGi bundles with maven-bundle-plugin, you can read the following article in WSO2 Library.


[1]. http://wso2.com/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin

Monday, February 25, 2013

Error with starting OpenMRS - "Unable to get a connection to the database"

This blog post will be about a very primary error on starting and running OpenMRS medical record system, in which i did my gsoc project and where i am still contributing whenever i get a time (yes i still love openmrs!). This is more like a note to myself.

I recently started to use a new laptop, therefore i moved all my openmrs repositories, .m2 repository and .OpenMRS directories into the new machine, as my intention was saving the time that will be taken to build everything from scratch again. However when i tried to run OpenMRS in the new machine, after installing and setting up mysql server, it returned the following error.

java.lang.RuntimeException: Error occurred while trying to get the updates needed for the database.
Unable to get a connection to the database.  Please check your openmrs 
runtime properties file and make sure you have the correct 
connection.username and
connection.password set ...
.................................................................................
.................................................................................
Caused by: java.sql.SQLException: Access denied for user 'openmrs_user'@'localhost' (using password: YES)


 Although i have worked with the project over an year now, i was also first confused on why the webapp can not be started. But then i realized the fix.

This is simply because when we start the web app from a previous implementation it still uses some of the configuration from its past installation. 
If you go to "webapp" folder in the 'openmrs_home' repository, there is a file called "openmrs-runtime.properties" where there is previous configuration data (usernames, passwords etc.) still present. Now simply delete this file from /home/USER_NAME/.OpenMRS folder if it is present there. Then delete this file from the 'webapp' folder and start again using 'mvn jetty:run'. No more errors, You are good to go now  :) :)


Monday, October 29, 2012

OpenMRS Html Form Entry Module new features

The HTML Form Entry module gets new features with each and every new version of release to provide more functionalities to he users. The following is a simple note on the new features i was working on HFE module last few months.

1. HTML-348 : Allow checkbox styles for numeric observations

Earlier if a user need to enter numeric observations like numbers,quantities etc. there were only text boxes, drop down lists and radio buttons used in order to do it. With the new addition you can use checkboxes also to record numerical observations as well as to capture multiple numerical observations.

An example code segment in a form would be,

<obs conceptId="5497" answer="502" answerLabel="502" style="checkbox"/>
<obs conceptId="5497" answer="503" answerLabel="503" style="checkbox"/>
<obs conceptId="5497" answer="504" answerLabel="504" style="checkbox"/>

where it would generate this kind of a form as shown below.



2. HTML-92 : Handle checkbox style (multiple select) in single obs element


At past if a user needs to add two or more checkboxes as answers for a question concept it was needed to be defined one by one per each checkbox element as shown below.

<obs conceptId="1069" answerConceptId="664" answerLabel="No Complaints" style="checkbox" />
<obs conceptId="1069" answerConceptId="832" answerLabel="Weight Loss" style="checkbox" />
<obs conceptId="1069" answerConceptId="6029" answerLabel="Night Sweats" style="checkbox" />

However this is a tedious and time wasting job for the form designed therefore this new feature is added in order to provide the ability to define all the checkbox elements in a single tag definition.

The following is the format of how the new <repeat with=""> tag should be added in the html form.

<repeat with="[664,'No Complaints'], [832,'Weight Loss'],[5544,'Weight Gain']">
<obs conceptId="1069" answerConceptId="{0}" answerLabel="{1}" style="checkbox" />
</repeat>

An example form with multiple checkbox elements is as follows.


Tuesday, July 3, 2012

Down the lane with OpenMRS in GSoC 2012 ..............

Time flows lot faster and i can't believe that it has almost come up the time for GSoC mid evaluations too.  I did have a quite busy but amazing time of two months so far with GSoC where it helped me to learn about many new things and technologies. So thought to have a little flashback on the things done so far.

The following are the tasks which i have already finished by the time of mid evaluation for this GSoC with HTML Form Entry module in OpenMRS.
1. Add autocomplete search functionality to encounter provider and encounter location widgets in HTML Form Entry
There are a lot of names as locations and encounter provider persons  in the system where it is displayed in a drop down list of options at the current module, but due to the long list of options it will be time taking to load and submit the location and provider values with the HTML form. 
At present, HFE module provides auto complete functionality with the <obs> tag, (stands for observation entries), where it does follows the JQuery AJAX calls to populate the source for the auto complete. However this feature is tightly coupled for Concept classes and ids, therefore it is not reusable for the Locations and Providers. The intention of my task is providing a generalized auto complete mechanism through out the module, which uses a pre-populated list of options as the source and which can be used with any other field (as DrugOrder etc.) in the future too. 
Encounter location and provider have been implemented by having two dedicated widgets for each such as, LocationWidget (for <encounterLocation>) and PersonStubWidget (for <encounterProvider>) tags. In addtion to that there is another encounter provider is introduced with htmlformentry 1.9 onwards which too uses a dedicated widget named ProviderWidget with <encounterProviderAndRole> tag. The intention of the task is replace the dedicated  widgets for location, provider etc. and implement a common auto complete mechanism over the Html Form Entry module by just using AutoCompleteWidget and the DropDownWidget for the fields. In that case when a user needs to add auto complete functionality into any other field, it can be easily done by using the new, generalized AutoCompleteWidget.
Here are few of the snapshots from new functionality!



 
 
 

 
 
 
 
And also it works with Options which has special characters like ã,é etc. and which have double quotes,single quotes in middle too :) Auto complete functionality is added into <encounterLocation>, <encounterProvider> and <encounterProviderAndRole> usingthe new AutocompleteWidget and LocationWidget and ProviderWidget in the module is replaced with the new AutocompleteWidget or a default DropDownWidget, hence they have been deprecated for future occurrences. 
The following is the link for the demonstration video i did regarding this new functionality at the second GSoC progress presentation at OpenMRS on 21st June 2012. The next post will explain the second task i have completed. I am eagerly waiting to see my changes have been integrated into HFE module soon :)
GSoC 2012 Autocomplete Demo
The presentation slides can be found Here!

Tuesday, March 6, 2012

Configuring proxy settings for Apache Maven

Ever wondered how to build your project with Apache Maven via a proxy server? This is a brief tutorial on how to do so.

Environment : Ubuntu 11.10 Oneiric
                        Apache maven 2.2.1

Apache maven holds all the configuration data in a single file called settings.xml file inside the 'conf' directory in the main directory of maven. The file includes configuration details regarding the proxies therefore we need to edit that section in order to enable the proxy server for a maven build.

This is how to do it.
  • Download the maven binary distribution from Apache Maven downloads page. The newest version is 3.0.4 however the stable version is 2.2.1 for the existing projects which are not upgraded into maven 3.
  • Extract the binary distribution into somewhere in your hard disk. apache-maven-2.2.1 directory will be visible now. Browse to the 'conf' directory inside 'apache-maven-2.2.1' main directory.
  • The 'settings.xml' file is inside the 'conf' directory. Open the file with a text editor and uncomment the section between <proxy> </proxy> tags. Edit the <proxy> entry as follows.
<proxies>
    <!-- proxy
     | Specification for one proxy, to be used in connecting to the network.
     | -->
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>MYHOST.LK</host>
      <port>3200</port>
      <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
    </proxy>
   
  </proxies>
  • Replace the MYHOST.LK address with the host address of your proxy server and replace the port number with relevant proxy port too. Save and close the file, now and you are ready to build via a proxy :)