Thursday, 2 January 2014

ANT Contrib & Custom Tasks

Contrib tasks

Lets see how we can create a contrib tasks in ANT first and then we proceed to custom tasks. To create contrib tasks in ANT first we have to create ant-contrib plug in and drop it in target platform's directory. This topic meant for advanced Eclipse Plugin Developers.

Download the ant-contrib jar to some location in local machine.
Create a new plugin project using eclipse.
Create a lib folder parallel to META-INF file and, place the ant-contrib jar over there.

Goto Eclipse plugin editor, and add lib/ant-contrib.jar  to the bundle classpath.

Once you are done here, add org eclipse ant core as dependent plugin by going to dependents tab.This will help in identifying extensions of ant core defined in ant core plugin.

We will be using ExtraClassPathEntries extension and AntTask extension.

Curretnly ant-contrib  defines the following tasks:

for   foreach  with parallel execution benefit

For each task that you want to use, define a mapping of task against classname defined in the ant-contrib jar for that task.

After defining all the need tasks that you want to use in your build system, add the lib/ant-contrib.jar in to the extra class path entries section of the manifest file.

Here is a sample and partial manifest file after above change.

<extension point="org.eclipse.ant.core.antTasks">
      <antTask 
           library="lib/ant-contrib.jar" 
           name="foreach" 
           class="net.sf.antcontrib.logic.ForEach"> 
      </antTask> 
     <antTask 
          library="lib/ant-contrib.jar" 
          name="for" 
          class="net.sf.antcontrib.logic.For">
     </antTask>
</extension>
<extension point="org.eclipse.ant.core.extraClasspathEntries"> 
     <extraClasspathEntry 
               library="lib/ant-contrib.jar"> 
      </extraClasspathEntry> 
</extension>

If everything is configured properly, you should be able to pick the defined ant tasks in the ant contrib jar from the Eclipse's plugin editor extension tab.

Once all of the tasks are added in the extension section of the manifest, the very important step is to remove the lib/ant-contrib.jar from the runtime bundle classpath. This is to make sure, we do not include ant-contrib.jar into the class path of the manifest classloader.  

Note that all the task defined in ant-contrib.jar need to be loaded by Ant class loader defined in org eclipse ant core plugin.   Otherwise  you will see all kinds weird error messages from the ant builder in eclipse plugins. 

At this point we are ready to export this project as ant contrib plugin. Goto File menu, select export and export the project as deployable plugin.  Select any destination directory. Once exported you will have plugin with ant-contrib jar inside.


How to use this plugin:
Drop this jar into the plugin's folder of your target platform's build system. Modify build.xml to define ant contrib xmlns as follows..

build.xml sample -

<project default="some.default.target" xmlns:ac="antlib:net.sf.antcontrib">
...
..
</project>

Note that   above defined as prefix namespace for antcontrib. 
Now use ac prefix to call the relevant ant contrib tasks anywhere in the build.xml 

Sample is like the following:
   <target name="iterate">
      <ac:for param="file">
         <fileset dir="."/>
         <sequential>
            <echo message="- @{file}"/>
         </sequential>
      </antcontrib:for>
   </target>

At this point, we should be able to run the build successfully calling tasks defined in ant contrib.


CUSTOM TASKS


Steps to create custom ANT  tasks.

1. Create a new Java Project in eclipse. Right click on Project->Properties->Java Build Path->Add external Jar. Browse to Ant.jar file in ANT_HOME/lib folder.

2.Make a new class say Hello which has to extend class org.apache.tools.ant.Task

import org.apache.tools.ant.BuildException;  
import org.apache.tools.ant.Project;  
import org.apache.tools.ant.Task;  
  
public class Hello extends Task 
{  
 private String retproperty = null;  
 private String msg;  
  
 public String getRetProperty() {  
  return retproperty;  
 }  
  
 public void setRetProperty(String property) {  
  this.retproperty = property;  
 }  
  
 public void setMsg(String msg) {  
  this.msg = msg;  
 }  
  
 public void execute() throws Exception {  
  System.out.println(msg);  
  Project project = getProject();  
  project.setProperty(retproperty,  
    "Value Returned By Custom task");  
 }  
}   

3. Once you have the java code ready in eclipse click on File=>Export=>Choose Jar and export to any suitable location on your system 

4. Now it’s time to write Ant script which will call this custom task pass a value and also read the value returned by the task.So write a similar Ant script. Here classpath should be location where jar in Step 3 was exported. 

<project name="CustomTask" default="build" basedir=".">  
  <taskdef name="Hello" classpath="../../CustomTask.jar" classname="HelloWorld">  
  <target name="build">  
   <helloworld retproperty="val" msg=" Custom Ant Task">  
   <echo message="${val}">  
  </echo></helloworld></target>  
</taskdef></project> 

5.Now we can run the Ant script through command prompt or eclipse as per convenience. 

<span style="font-family: Arial;">
<hello retproperty="val" msg="Custom Ant Task">
</hello>
</span>

This executes method of the HelloWorld class is invoked and msg variable is initialised with value passed. Similarly

project.setProperty(retproperty,"Value Returned By Custom task");  
The above line sets the value into property value  which is again defined in ret property. So that in Ant script variable val will hold the value returned or set inside the class so we can use it for further processing.

Wednesday, 1 January 2014

SVN Branching,Merging commands


           As most of used SVN on windows we would know mergeing, Branching etc on windows with the help of graphical user interface. But sometimes we also need to work on UNIX/LINUX environment and in that case if we want to use SVN we would need to know the commands to create branch, merge branch, check in, check out etc. In this post let me show some of commands used for creating branch, merging branch into trunk, updating branch.



1. Merge a Branch into Trunk


a. Check out the trunk:


svn co svn+ssh://server/path/to/trunk


b. Check out a copy of the branch you are going to merge:


svn co svn+ssh://server/path/to/branch/myBranch


c. Change your current working directory to “myBranch” .Find the revision “myBranch” began at:


svn log --stop-on-copy


This should display back to you the changes that have been made back to the point the branch was cut. Remember that number (should be rXXXX, where XXXX is the revision number).


d. Change your current working directory to trunk # Perform an SVN update:


svn up


This will update your copy of trunk to the most recent version, and tell you the revision you are at. Make note of that number as well (should say “At revision YYYY” where YYYY is the second number you need to remember).


e. Now we can perform an SVN merge:


svn merge -rXXXX:YYYY svn+ssh://server/path/to/branch/myBranch


This will put all updates into your current working directory for trunk.

f. Resolve any conflicts that arose during the merge and Check in the results:


svn ci -m "MERGE myProject myBranch [XXXX]:[YYYY] into trunk"


That is it. You have now merged “myBranch” with trunk.


2. Branch Creation


a. Get the head revision


svn info svn://server.com/svn/repository/trunk | grep Revision


b. Create a branch

svn cp svn://server.com/svn/repository/trunk \ svn://server.com/svn/repository/branches/your_branch \ -m "Branching from trunk to your_branch at HEAD_REVISION"


c. Swtich to new branch


svn switch --relocate \ svn://server.com/svn/repository/trunk \ svn://server.com/svn/repository/branches/your_branch

d. Update you current directory


svn info | grep URL svn up



e. commit your new changes


3. Updating the branch


a. Update your current branch

b. Search the subversion logs to check what revision number last merged.

svn log --limit 500 | grep -B 3 your_branch

c.Get the head revision

svn info svn://server.com/svn/repository/trunk | grep Revision

d. Merge the difference of the last merged revision on trunk and the head revision on trunk into the your branch working copy

svn merge -r LAST_MERGED_REVISION:HEAD_REVISION \ svn://server.com/svn/repository/trunk .
Replace LAST_MERGED_REVISION with the revision number you noted in step 2, and HEAD_REVISION with the revision number you noted in step 3.


Now look for errors in the output. Could all files be found? Did things get deleted that shouldn’t have been? Maybe you did it wrong. If you need to revert, run svn revert -R *.


e. Check for conflicts.


svn status | egrep '^C|^.C'


Resolve any conflicts. Make sure the application starts and the tests pass.


f. Commit merge changes.


svn ci -m "Merged changes from trunk to your_branch"



Datasource setup on Websphere

In my previous post about "Data sources and Advantages" I have explained about Datasources and It's advantages over Driver manger in JAVA/J2EE based applications. In this post I will show how to setup DataSources on Websphere application server, which can be used in applications using JNDI name.

Following are the steps to create Datasources on Websphere :

1.Start the WebSphere Application Server and login to administrative console.
2. Click Security -> Global security. Under Authentication, expand Java Authentication and Authorization Service and click J2C authentication data.
















3. Click New and enter the Alias, User ID and Password,click Ok.(This will be the user name and password of DB).













4. On the administrative console, expand Resources. Expand JDBC then click JDBC Providers.In the Scope section, choose the appropriate scope depending on the usability of Datasource.














5.Click New to create a new JDBC driver. Select, the Database type, Provider type, Implementation type and Name. The Name automatically fills based on the implementation type chosen.
















6.Click Next and configure the database class path. Click Next.
















7.On the Summary page, click Finish.Click Save to save your selections to Master configurations. The JDBC providers page then appears.













8.On the administrative console, click Data sourcesClick New to create a new data source. Enter the Data source name and the JNDI name, and choose the authentication alias from the drop-down list in Component-managed authentication alias. This JNDI name will be used in the applications.














9. Click Next and select the JDBC provider which was created earlier and click Next.














10. Enter the Database name and and server name where DB is located.Deselect the checkbox, Use this data source in container managed persistence (CMP). Click Next.













11. Select Component-managed authentication alias and Container-managed authentication alias.


















12.On the Summary page, click Finish.














13.The Data sources page displays, Click Save. Click Test Connection. The message should indicate that the connection is successful. Ignore any warnings.