Thursday, 17 September 2015

isNumeric in Java.

Once in while in java we might have to check If a passed string to method is a valid numerical value. Below are some utility methods to accomplish this:

    Using java.text.NumberFormat.


    public static boolean isNumeric(final String str) {
        try {
            Double.parseDouble(str);
        } catch (final NumberFormatException | NullPointerException e) {
            return false;
        }

        return true;
    }

    JUnit Test Case:


        Assert.assertEquals(false, yourClass.isNumeric(null));
        Assert.assertEquals(false, yourClass.isNumeric(""));
        Assert.assertEquals(true, yourClass.isNumeric("2.74"));
        Assert.assertEquals(true, yourClass.isNumeric("2.745435E3"));
        Assert.assertEquals(true, yourClass.isNumeric("0"));
        Assert.assertEquals(true, yourClass.isNumeric("0.0f"));
        Assert.assertEquals(false, yourClass.isNumeric("NaN"));       


    Using Double.parseDouble.


     public static boolean isNumeric(final String string) {
        try {
            NumberFormat.getInstance().parse(string);
        } catch (ParseException | NullPointerException e) {
            return false;
        }

        return true;
    }

    JUnit Test Case:


        Assert.assertEquals(false, yourClass.isNumeric(null));
        Assert.assertEquals(false, yourClass.isNumeric(""));
        Assert.assertEquals(true, yourClass.isNumeric("2.74"));
        Assert.assertEquals(true, yourClass.isNumeric("2.745435E3"));
        Assert.assertEquals(true, yourClass.isNumeric("0"));
        Assert.assertEquals(true, yourClass.isNumeric("0.0f"));
        Assert.assertEquals(true, yourClass.isNumeric("NaN"));


As you guys might have noticed that I have an assert statement for both the methods which checks the method against string "NaN". The thing which makes this more interesting is that the method which uses NumberFormat returns false for this string while the method which uses Double.parseDouble(string) returns true.

You might say that the method which uses NumberFormat is correct because "NaN" is technically just a mere string value. Below is the description of how java treats "NaN" while doing floating-point operations :

"NaN" stands for "not a number". "Nan" is produced if a  floating point operation has some input parameters that cause the operation to produce some undefined result. For example, 0.0 divided
by 0.0 is arithmetically undefined. Taking the square root of a negative number is also undefined.


That's all for now folks stay tuned for new posts !!!!!!!!

 
 
 



Saturday, 5 September 2015

Jetty - Enabling request logs

Whenever you start jetty using jetty.sh shell script located inside jetty's bin folder, the jetty will start with the below logs enabled defined inside /opt/jetty/start.ini file (defined using xml files) by default:

etc/jetty.xml
etc/jetty-annotations.xml
etc/jetty-deploy.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml

Below is the snapshot of the /opt/jetty/start.ini file to show complete set of configuration files:

#===========================================================
# Configuration files.
# For a full list of available configuration files do
#   java -jar start.jar --help
#-----------------------------------------------------------
#etc/jetty-jmx.xml
etc/jetty.xml
etc/jetty-annotations.xml
# etc/jetty-ssl.xml
# etc/jetty-requestlog.xml
etc/jetty-deploy.xml
#etc/jetty-overlay.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml
#===========================================================

As highlighted in the above configuration the request log xml file is commented by default. We just have to uncomment the same and restart jetty to enable request logs and you should be able to see the request logs generated in the below directory:

/opt/jetty/logs

$ ls -lt
total 48
-rw-rw-r-- 1 jetty jetty  165 Aug 21 13:54 2015_08_21.request.log

Thursday, 4 June 2015

AspectJ Weaving - Finally Working !!!!!



After almost banging my head on the desk I finally get this working and thought of sharing the same in order to have a smooth run for anyone looking at it for the first time.

Before explaining the sample project I would like to set the plot that why I wanted to use AspectJ at the first place. I wanted to log a method's execution time in java. Though I would have done it a simple way by recording the difference between start time and end time of the method I chose AspectJ for not polluting the method body with the execution time logic.

In this tutorial I am not going to explain what is AspectJ? As I wanted to focus more on a working example. I have created a sample MAVEN project consists of the following java files:

SampleTarget.java:
This class contains a method fact for which we have to record the execution time.

 package com.piyush.aspect.tutorial;

/**
 * Class on which advice will be applied
 */
public class SampleTarget {
    public static void main(String[] args) {
        // Calling fact method on which 'around' advice will be applied
        new SampleTarget().fact(5);
    }

    public void fact(int num) {
        int c, fact = 1;
        if ( num < 0 )
           System.out.println("Number should be non-negative.");
        else
        {
           for ( c = 1 ; c <= num ; c++ )
              fact = fact * c;
           System.out.println("Factorial of "+num+" is = "+fact);
        }
    }
} 


SampleAspect.java: This class contains the advice implementation which has to be applied to the SampleTarget fact method.

package com.piyush.aspect.tutorial;

import org.aspectj.lang.ProceedingJoinPoint;
/**
 * A sample class annotated with @Aspect and implementing around advice
 */
@Aspect
public class SampleAspect {
    @Around("execution (* com.piyush.aspect.tutorial.SampleTarget.fact*(..))")
    public void advice(ProceedingJoinPoint joinPoint) throws Throwable {
        final long startTime = System.nanoTime();

        joinPoint.proceed();
        System.out.println("Elapsed time: ="+ (System.nanoTime() - startTime));
    }
}


Above things were not that difficult and can be found easily over the various blogs or tutorials. The key thing which has to be setup right is the pom.xml. Following is the pom.xml file which can be used without any modifications:

<?xml version="1.0" encoding="UTF-8"?>
<project
    <modelVersion>4.0.0</modelVersion>
    <groupId>SampleProject</groupId>
    <artifactId>SampleProject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <targetJdk>1.7</targetJdk>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.12</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.12</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.5</version>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>1.6.12</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <complianceLevel>1.6</complianceLevel>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.piyush.aspect.tutorial.SampleTarget</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Above pom.xml contains 3 dependencies aspectjrt, aspectjweaver and aspectjtools. It also contains aspectj maven plugin and maven execution plugin to execute SampleTarget.java having main method.

Now we have to run this project and see if the advice is applied to the fact method or not. Following command can be used to run the project from command line (make sure you are in the root directory of the project):

Command : mvn clean install OR mvn install

Following output should be displayed after running the project:

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - SampleProject:SampleProject:jar:0.0.1-SNAPSHOT
[INFO]    task-segment: [clean, install]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
[INFO] Deleting /home/piyusht/workspace/rtb/MyAspect/target
[INFO] [resources:resources {execution: default-resources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 3 source files to /home/piyusht/workspace/rtb/MyAspect/target/classes
[WARNING] POM for 'org.apache.maven.wagon:wagon-provider-api:pom:1.0-beta-6:runtime' is invalid.
Its dependencies (if any) will NOT be available to the current build.
[INFO] [aspectj:compile {execution: default}]
[INFO] [resources:testResources {execution: default-testResources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/piyusht/workspace/rtb/MyAspect/src/test/resources
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] No sources to compile
[WARNING] POM for 'org.apache.maven:maven-toolchain:pom:2.0.9:runtime' is invalid.
Its dependencies (if any) will NOT be available to the current build.
[INFO] [surefire:test {execution: default-test}]
[INFO] No tests to run.
[INFO] Surefire report directory: /home/piyusht/workspace/rtb/MyAspect/target/surefire-reports
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Results :
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar: /home/piyusht/workspace/rtb/MyAspect/target/SampleProject-0.0.1-SNAPSHOT.jar
[INFO] Preparing exec:java
[WARNING] Removing: java from forked lifecycle, to prevent recursive invocation.
[INFO] No goals needed for project - skipping
[INFO] [exec:java {execution: default}]
Factorial of 5 is = 120
Elapsed time: =119435
[INFO] [install:install {execution: default-install}]
[INFO] Installing /home/piyusht/workspace/rtb/MyAspect/target/SampleProject-0.0.1-SNAPSHOT.jar to /home/piyusht/.m2/repository/SampleProject/SampleProject/0.0.1-SNAPSHOT/SampleProject-0.0.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Wed Jun 03 18:09:31 IST 2015
[INFO] Final Memory: 31M/244M
[INFO] ------------------------------------------------------------------------

das Ende !!!! Nope it is not garbage, its THE END in german. Although it has nothing to do with this post, mentioned just to put THE END in a different way :-)

Hope it helps. Please share your feedback and questions If any.

Sunday, 9 November 2014

Strengthen your test suite - Mutation Testing

Hey Guys, I found this interesting thing sometime back and was wondering how can somebody be not using this.

So we must be encountered the following situations while Unit Testing our code:
  • Hey there are some more scenarios against which we have to test the method !!!
  • Hey I did not take this scenario into account while unit testing and this results in a production issue.
  • Hey I had 100% code coverage, how can a bug will come?
Myth here is : 100% Code Coverage does not mean 100% Test Scenarios are covered.

The answer to all the above or to avoid such conditions is to use Mutation Testing. A cool testing technique to validate and enhance your test suite.
There are several Mutation Testing frameworks present right now however the most simple and active framework named PIT is a good choice.

Following are some other framework for Mutation Testing:
  • Jester Source-based mutation testing tool for Java
  • Judy Mutation testing tool for Java
  • Jumble Bytecode-based mutation testing tool for Java

Links to go through:

Tuesday, 4 November 2014

Hadoop Single Node Setup & Map-Reduce

This time I would like to share something big and here I come with the "BigData". Though I won't talk much on BigData, I will explain the Single node setup for hadoop and a map reduce java program running on it.

Following are the pre-requisites of running a Single node hadoop:
  • Java 6 or higher.
  • Apache Hadoop 2.5.1 (Download Link)
  • SSH Server.
  • Password less SSH login for localhost.
  • Make/Edit ~/.bashrc file.
First 2 steps are pretty simple and can be accomplished with ease. At this point I assume that you have downloaded/installed java and hadoop.

Note: Hadoop installation is merely a copy and paste task, so once after downloading the tar file for hadoop, unpack the same and put it to the following directory: /usr/local/hadoop
Command: sudo cp –rf ~/Downloads/hadoop-2.5.1/* /usr/local/hadoop
Add your user as owner to the hadoop directory i.e. /usr/local/hadoop as below:
Command: sudo chown <username> /usr/local/hadoop

SSH Server:
Install the SSH Server using the below command:
Command: sudo apt-get install openssh-server openssh-client

Password less SSH login for localhost:
To get rid of input the password login to localhost, we have to execute the following commands:

        1. Delete the SSH directory:
rm -rf ~/.ssh
2. Generate the SSH key:
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
3. Register the generated key as authorized:
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
4. Login to localhost:
ssh localhost (Should not ask for password)

Make/Edit ~/.bashrc file:

This is one of the important part of this setup, so insert the below entries into the .bashrc file if you have .bashrc file otherwise create .bashrc file by yourself and insert the entries:

JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
PATH=$PATH:$JAVA_HOME/bin
JRE_HOME=/usr/lib/jvm/java-7-openjdk-amd64
PATH=$PATH:$JRE_HOME/bin
HADOOP_INSTALL=/usr/local/hadoop/
PATH=$PATH:$HADOOP_INSTALL/bin
PATH=$PATH:/sbin
export HADOOP_CLASSPATH=$JAVA_HOME/lib/tools.jar
export JAVA_HOME
export JRE_HOME
export PATH

Above entries are to set the important environment variables. Once after you are done with .bashrc file creation/modification close your terminal window and start a new one as changes may not reflect in the same terminal window.

Note: As we can see in the above entries there is an environment variable HADOOP_INSTALL, don’t confuse with it, it is same as the HADOOP_HOME however that is deprecated now so use HADOOP_INSTALL in place of HADOOP_HOME.


Okay !!! Now we are done with the pre-requisites so let’s make some configuration changes necessary for the hadoop single node setup to work:

1. Move to the directory which has all the configuration files in the hadoop installation directory i.e. /usr/local/hadoop/etc/hadoop

2. Set the JAVA_HOME variable inside file hadoop-env.sh:

export JAVA_HOME=${JAVA_HOME}
OR
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64

3. Add following lines in the core-site.xml:
<property>
    <name>fs.default.name</name>
    <value>hdfs://localhost:9000</value>
</property>
<property>
    <name>hadoop.tmp.dir</name>
    <value>/usr/local/hadoop/tmp</value>
</property>
As we can see here the value for hadoop.tmp.dir is /usr/local/hadoop/tmp, we have to create tmp directory before running hadoop scripts.

4. Add following lines in the hdfs-site.xml:
<property>
    <name>dfs.replication</name>
    <value>1</value>
</property>
<property>
    <name>dfs.namenode.name.dir</name>
    <value>/var/hadoop/namenode</value>
</property>
<property>
    <name>dfs.datanode.data.dir</name>
    <value>/var/hadoop/datanode</value>
</property>
Here we are defining the name node and data node directories; these should also be created before we run/start the hadoop. Also we have to add our username as the owner of these directories. Below are the commands for the same:

sudo mkdir /var/hadoop/namenode
sudo mkdir /var/hadoop/datanode
sudo chown <username> /var/hadoop

5. There will be a mapred-site.xml.template file inside /usr/local/hadoop/etc/hadoop so we have to move the file as mapred-site.xml:
sudo mv etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml

Then add below entries in the same:
<property>
    <name>mapred.job.tracker</name>
    <value>localhost:9001</value>
</property>
Now we are done with the configurations files.


HDFS Steps:


Now we’ve to format the name node : (we are at the /usr/local/hadoop/)
hadoop namenode –format

To check if the name node is formatting is successful check for the below message:
/var/hadoop/namenode had been successfully formatted. (In our case)

After this start all the necessary services using below command:

sbin/start-all.sh
<username>@mysystem-desktop /usr/local/hadoop $ sbin/start-all.sh
This script is Deprecated. Instead use start-dfs.sh and start-yarn.sh
Starting namenodes on [localhost]
localhost: starting namenode, logging to /usr/local/hadoop/logs/hadoop-<username>-namenode-xxx-desktop.out
localhost: starting datanode, logging to /usr/local/hadoop/logs/hadoop-<username>-datanode-xxx-desktop.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: starting secondarynamenode, logging to /usr/local/hadoop/logs/hadoop-<username>-secondarynamenode-xxx-desktop.out
starting yarn daemons
starting resourcemanager, logging to /usr/local/hadoop/logs/yarn-<username>-resourcemanager-xxx-desktop.out
localhost: starting nodemanager, logging to /usr/local/hadoop/logs/yarn-<username>-nodemanager-xxx-desktop.out

You can check about the running processes using jps command as below:

<username>@mysystem-desktop /usr/local/hadoop $ jps
3316 SecondaryNameNode
3506 ResourceManager
3160 DataNode
3932 Jps
3607 NodeManager
3060 NameNode

This will tell us about the running services and components. All the components listed above should be running if not there is some issue.

Once all the processes are started you can view the name node setup with the help of below URL: NameNode - http://localhost:50070/. Here you can get all the information about the directories, datanode etc.


Setup for Map-Reduce:

To run the Map-Reduce example we first have to make the input directory where we will store our input files on which map-reduce program will run.

1. Make the HDFS directories required to execute MapReduce jobs:
$ bin/hdfs dfs -mkdir -p /user/<username>/input
2. Copy the input files into the distributed filesystem: (This is not exactly the input file but the configuration files)
$ bin/hdfs dfs -put etc/hadoop input
3. Map Reduce Dictionary example: Map-Reduce Example, we are using the example from the link mentioned before, where the whole procedure is divided in below steps:

1. Go to the below links and download the dictionary files for Italian, French ans Spanish:
2. Merge all the three files into one file with the below:
cat French.txt >> fulldictionary.txt
cat Italian.txt >> fulldictionary.txt
cat Spanish.txt >> fulldictionary.txt
3. Copy this file i.e. fulldictionary.txt to hadoop file system input directory with the below command: (assuming you are in the path: /usr/local/hadoop)
bin/hdfs dfs -copyFromLocal ~/<your_path>/fulldictionary.txt input
4. In this example Map-Reduce Example there is one Dictionary.java file having map-reduce logic in it, which you have to compile, make jar and run the jar using below commands:
Compilation:
javac -classpath $HADOOP_INSTALL/share/hadoop/common/hadoop-common-2.5.1.jar:$HADOOP_INSTALL/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.5.1.jar:$HADOOP_INSTALL/share/hadoop/common/lib/commons-cli-1.2.jar Dictionary.java
JAR Creation:
jar -cvf dc.jar Dict*.class
JAR Execution:
hadoop jar dc.jar Dictionary input output
 Note: Before compiling the Dictionary.java file make the below changes in it:
FileOutputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
Instead of hard-coding the path for Input and Output take it from command line arguments as shown above.
Once you are done with JAR Execution, check the output directory in hdfs for result. Please note that, do not make output directory by yourself, output directory will be created by the map-reduce job itself else you will get an error saying output directory already exists.

Viola !!! The End. Hope this tutorial will be helpful for the beginners.














Wednesday, 29 October 2014

Google Protobuf - Get it working on Linux


Note: This article is posted while keeping in mind that the reader has already gone through the Proto file syntax i.e. what variable are used data types etc, last but not the least what protobuf is? If answer to this question is NO, Please visit: https://developers.google.com/protocol-buffers/

Getting Goggle Protobuf working is quite a heck so to make it easy I thought it would be worth sharing a quick read:

Steps to configure a sample maven java project in eclipse using protobuf in LINUX:
1. Install the protobuf compiler as below:
sudo apt-get install protobuf-compiler

2. Maven dependency that needs to be inserted into the pom.xml
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.6.0</version>
</dependency>

3. First of all we have to create a .proto file and then compile it using the protobuf compiler which results in .java class:
Syntax:  
protoc --java_out=<path where you want your respective java files to be created> <the actual .proto file's path>
Example: 
protoc --java_out=src/com/piyush/demo src/com/piyush/demo/addressbook.proto
protoc --java_out=src/ src/com/piyush/demo/my_object.proto

4. Earlier step can be automated using "maven-antrun-plugin", however get this running is quite a heck so please refer the below thread for this:
Links:
We can use maven-antrun-plugin in following ways:
  • For Single proto file compilation:
<echo>Generate</echo>
<exec executable="protoc">
<arg value="--java_out=src/" />
<arg value="src/com/piyush/demo/addressbook.proto" />
</exec>
  • For Multiple proto files compilation:
        <tasks>
                <echo>Generate</echo>
                    <path id="proto.path">
                        <fileset dir="src/com/piyush/demo/proto">
                            <include name="**/*.proto" />
                            </fileset>
                       </path>
                        <pathconvert pathsep=" " property="proto.files" refid="proto.path" />
                        <exec executable="protoc" failonerror="true">
                            <arg value="--java_out=src/" />
                            <arg value="-I${project.basedir}/src/com/piyush/demo/proto" />
                            <arg line="${proto.files}" />
                        </exec>
        </tasks>


Tips & Tricks:
1. Message name should be in camel case.

2. Beware that the name of the message and java_outer_classname should not be same in the proto file. For Example below proto file won't compile:
option java_package = "com.xyz.zrtb.simulator.protos";
option java_outer_classname = "A";
message a {
   optional string id = 1;
   optional string name = 2;
   repeated string cat = 4;
   optional string domain = 3;
}
Below will compile fine:
option java_package = "com.xyz.zrtb.simulator.protos";
option java_outer_classname = "OuterA";
message A {
   optional string id = 1;
   optional string name = 2;
   repeated string cat = 4;
   optional string domain = 3;
}


3. Importing proto file in one another is quite a heck and so it is good if you get it right at the very first place:
Import relies on the on the parameter '--proto_path' so If you've a package com.abc.pqr.model and defined '--proto_path' as below:
--proto_path=${project.basedir}/src/main/java/com/abc/pqr/model
THEN you can import just by writing xxx.proto However If you've defined '--proto_path' as below:
--proto_path=${project.basedir}/
THEN you can import by writing src/main/java/com/abc/pqr/model/xxx.proto and many such combinations.

4. The maven-antrun-plugin is problematic and can be a blocker, so below is the ready to use pom.xml configuration:
<build>
     <pluginManagement>
         <plugins>
            <!-- force a dependency on JDK 5.0 -->
            <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
               <configuration>
                  <source>1.7</source>
                  <target>1.7</target>
               </configuration>
            </plugin>
            <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build
          itself. -->
            <plugin>
               <groupId>org.eclipse.m2e</groupId>
               <artifactId>lifecycle-mapping</artifactId>
               <version>1.0.0</version>
               <configuration>
                  <lifecycleMappingMetadata>
                     <pluginExecutions>
                        <pluginExecution>
                           <pluginExecutionFilter>
                              <groupId>org.apache.maven.plugins</groupId>
                              <artifactId>maven-antrun-plugin</artifactId>
                              <versionRange>[1.7,)</versionRange>
                              <goals>
                                 <goal>run</goal>
                              </goals>
                           </pluginExecutionFilter>
                           <action>
                              <ignore />
                           </action>
                        </pluginExecution>
                     </pluginExecutions>
                  </lifecycleMappingMetadata>
               </configuration>
            </plugin>
         </plugins>
        <pluginManagement>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
               <execution>
                  <id>generate-sources</id>
                  <phase>generate-sources</phase>
                  <configuration>
                     <target>
                        <echo>Generate</echo>
                        <path id="proto.path">
                           <fileset dir="src/main/java/com/piyush/zrtb/simulator/proto">
                              <include name="**/*.proto" />
                           </fileset>
                        </path>
                        <pathconvert pathsep=" " property="proto.files" refid="proto.path" />
                        <exec executable="protoc" failonerror="true">
                           <arg value="--java_out=src/main/java" />
                           <arg value="-I${project.basedir}/src/main/java/" />
                           <arg line="${proto.files}" />
                        </exec>
                     </target>
                     <sourceRoot>src/main/java</sourceRoot>
                  </configuration>
                  <goals>
                     <goal>run</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
      <extensions />
   </build>

Links to go through:
  • https://code.google.com/p/protoclipse/
  • http://www.siafoo.net/user/stou/blog/2010/01/29/Protocol-Buffers-and-Eclipse
  • http://www.masterzen.fr/2011/12/25/protobuf-maven-m2e-and-eclipse-are-on-a-boat/
  • http://techtraits.com/noproto/
  • http://xmeblog.blogspot.in/2013/12/sending-protobuf-serialized-data-using.html
  • http://sleeplessinslc.blogspot.in/2010/03/restful-representation-with-google.html
  • http://tutorials.jenkov.com/maven/maven-tutorial.html
  • https://developers.google.com/protocol-buffers/docs/proto#generating

Friday, 21 February 2014

To start off with my first words here, I would like to share a quote which I always found significant and worth following in life:

"There is nothing noble about being superior to some other person, true nobility lies in about being superior to your former self".