## Pages

### Protobuf for lazy Java coders.

Sometimes you are just plain lazy and would rather have Maven create the Java files out of .proto. The alternative would have been to download the protoc, fire up the terminal and issue one simple command. Not a big deal at all. But as I said sometimes you are just plain lazy.

So how do you go about it. Follow the steps given below.

Think up a super critical message that you want to send across over the wire.
If you dont know how to write a .proto file, perhaps one of the links below would help.
The one below is the super critical hello world that I want to send across.

#1

Create a vanilla maven project.
Say thanks to open source and add protoc-jar-maven-plugin to the project.

#2

This would create the java files.
However they will complain that the google libraries are not around.
So you will have to add the protobuf libraries.

#3

The proof of the pudding is in eating it.
Let's write a test to serialize and deserialize the super critical message.

#4

### Are you using all indexes of your database?

It is a odd week at work, when I don't learn something new. However, every once you learn something so obvious that you wonder exactly why did you miss this so long. This note is about one of those embarrassing aaha moments.

I have never worked on a project that did not have some database behind it. DB2, Oracle, Sybase etc all the usual suspects. However, I have always had one or two members in the team who were the db nerds. While I wrote queries, stored procs etc etc when things got difficult with db related issues, they stepped up and I was only too happy to hand it over to them. This is all good. I like to play to the strengths of the team. However, this means I did miss a few low hanging fruits on the way. And here I talk about one such.

So, we delivered this nice project and we were doing a soft launch. As usual our DB2 came under fire. Someone asked a innocuous question. Are all our heavy lifting queries using indexes? Given the number of queries that we have it was not a quick investigation. So, the next question was are all the indexes being used? Or some of them are just hanging around eating resources and not doing anything at all. Surely I knew the answer.

Umm, no, I did not. I should have. This is something that I should have known. Not only for this application after someone asked but for all the applications that I have ever worked with. But the fact is I did not. I suspect strongly that many of the readers are in the same boat. And hence this half rant, half "how-to" note.

You have read the rant part already. Now is the "how-to" part.

Which indexes of your DB2 database are not being used?

select
INDSCHEMA,
INDNAME,
TABSCHEMA,
TABNAME,
INDEXTYPE,
LASTUSED
from SYSCAT.INDEXES
where INDSCHEMA = 'yourschema'
order by LASTUSED ;


This should give you a list of all indexes of your database in the order of your last usage. In case they are not used at all the LASTUSED will be '0001-01-01'. There you go. As simple as that.

You will get a much more knowledgeable note on this subject at this link.

That's all for today. If you liked what you read or not liked :) it will help if you leave a comment here.

### Trust and Successful Enterprises.

If there was only one thing that you had time for - apart from your day job - building trust and an environment congenial for trust, is a single most important investment to be made on the job.

The problem with trust is - everyone wants to be able to trust - but none wants to go through any pain to make themselves trustworthy. Integrity, hard work, honesty - let's face it - these are not easy virtues to practice. They are not easy to practice in your personal life, as a single human being. They are all the more difficult to practice, in a team, when your career is on line. We have all gone through these internal dialogues...

1. I just have to get that code across - I know there are a couple of bugs - what is the benefit of calling them out. QA will find them.
2. I want that next position and being seen in the vicinity of success is going to help - so why not talk about the excellent job that one guy of your team did, and without actually explicitly saying it, leave an impression that I had something to do about it - while I did nothing really.
3. Let me tidy up that report - highlight the achievements - and play down on the risks. Risks look bad on the report.

These small "innocent" under hand techniques that we all do (and I am not talking about crimes or breaking law) - because everybody else does - is like karma. You do it to. Someone else sees it and does it too. You do more. More gets done around you. You push the envelope of your moral further. Someone else tops it. This is just a vicious circle.

And who wins? I don't know who does. I guess the "pointy haired boss" or the "wally" s of the day wins. But this is for sure, that anyone who is just working hard, doing an honest day's job, with passion and dedication for the job, he doesn't win - without going for any underhand techniques, he looses. And someone else looses. The job, the actual project, the actual business, that looses out to employee's own battles.

So, tell you what, I don't think it is a battle that each one of us - individually - could fight and win alone. I think the biggest looser in the game - the enterprise, the business, the job, the project - that needs to pitch in.  Since the enterprise is nothing but you and me and us - it is in the best interest of all of us, to try in our own spheres of influence, to make building an environment congenial of trust our priority.

Tim Cook says very clearly "You look for people that are not political. People that are not bureaucrats. People that can privately celebrate the achievement, but not care if their name that is in the one in the lights. There are greater reasons to do things." Well, he is doing his bit :).

### One jar to rule them all.

Trip down the memory lane

Back in 1998, when I was a C/C++ developer, trying my hands on Java, a few things about the language were, to put it mildly - irritating - for me. I remember fretting about these quite a lot
1. Why isn't there a decent editor for this? C/C++ had quite a few. All that I had for Java was the good old notepad.
2. Why do I have to make a class, when all I want is a function? Why wasn't a function an object as well?
3. Why can't I just package everything into one zip/jar and let the end user launch with a double click?
and a few others.

Back then, I found me frequently chiding myself for not being able to let go of my "C/C++ way of thinking" and embracing "Java way" of doing things. Now, writing this article in 2013, about a decade and a half later, surprisingly all of those early irritations are gone. Not because I have embraced "Java" way, but because java has changed.

Idle chit chatting aside, the point of this article is to talk about one of these questions - "Why can't I just package everything into one zip/jar and let the end user launch with a double click?".

Why do we need this - one zip/jar - that is executable?

If you are a developer, coding away happily on your IDE (I despise you all who have coded java on Eclipse, NetBeans from day one and have not had to code on Notepad :) ), assisted by Google (I positively totally hate all of you all who did not have to find stuff on internet before Google :) :) ), there is probably no convincing case.

However, have you faced a situation when
1. You have been pulled into the data centre because the guy there have followed your deployment steps  but your application / website will simply not work?
2. All of a sudden the environment variables are all messed up, when "nobody at all so much as touched" the production boxes, and you are the one who has to "just make it work".
3. You are sitting with your business stakeholder and staring incredulously at a "ClassNotFound exception" and were convinced that Java did not like you at all.
In short, what I am trying to say is, when you are in the "relative" sanity of your dev box / environment, a one executable jar does not really do anything for you. But the moment you step into the twilight zone of unknown servers and situations (sans the IDE and other assortment of tools) you start appreciating just how much a single executable jar could have helped.

Ok, I get it. But, what's the big deal? We can make such a package / zip / jar in a jiffy if we have to. Isn't that so.

In all my naivety, I thought so and found out the answer the hard way. Let me walk you through it. Fire up your editors folks. Let's create a executableJar project. I use jdk1.7.0, STS, Maven 3.0.4. If you are new to Maven or just not hands on, I recommend you read this and this

File: C:\projects\MavenCommands.bat
ECHO OFF
REM =============================
REM Set the env. variables.
REM =============================
SET PATH=%PATH%;C:\ProgramFiles\apache-maven-3.0.4\bin;
SET JAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0
REM =============================
REM Standalone java application.
REM =============================
call mvn archetype:generate ^
-DarchetypeArtifactId=maven-archetype-quickstart ^
-DinteractiveMode=false ^
-DgroupId=foo.bar ^
-DartifactId=executableJar001
pause

After you run this batch file, you will have a fully compilable standard java application. Go ahead compile it and build a jar (mvn -e clean install). You will end up with a executableJar001-1.0-SNAPSHOT.jar at C:\projects\executableJar001\target. Now lets go "java -jar jarFileName". And here you stumble the first time. In geeky vocabulary it tells you that there were no class with a main method and hence it did not know what to execute.

Fortunately this is an easy one. There are standard java process to solve it. And there is a Maven plugin to solve it. I will use the latter.

Updated File: /executableJar001/pom.xml
...

...

org.apache.maven.plugins
maven-jar-plugin
2.4

foo.bar.App

...


You can compile and assemble the application again (mvn -e clean install). It is will create a jar file in target folder. Try running the jar from command line again. This time you will get intended result. So, we are all sorted, right?

Wrong. Very wrong.

Why? Everything seems fine.

Let's dig in a bit deeper and we will find why everything is not as sorted as it looks at the moment. Let's go ahead and add a dependency e.g. let's say we want to add logging and for that we want to use a third party jar i.e. logback. I will let Maven handle dependencies in the development environment.

Updated File : /executableJar001/pom.xml
...

ch.qos.logback
logback-classic
1.0.9

...


Updated File: /executableJar001/src/main/java/foo/bar/App.java
package foo.bar;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class App
{
private final static Logger logger = LoggerFactory
.getLogger(App.class);

public static void main( String[] args )
{
System.out.println( "Hello World!" );
logger.debug("Hello world from logger.");
}
}

Now let's compile and run the jar from command prompt using jar command. Did you see what happened?
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

Basically it is saying that the class (i.e the actual code) of the LoggerFactory (i.e. the 3rd party jar that we had added in development environment) was not found.

Oh, but surely we should be able to tell java to pick up the 3rd party libraries from some folder.

Definitely. It is almost a certainty - if you are asking that question - that for most of your applications you tell the JVM where the 3rd party / dependency libraries are. You tell this by setting classpath. You could possibly be using some application server e.g. Tomcat / Jetty and that could be picking up some dependencies itself. And that is exactly where the problem originates.

As a developer, I provide a x.jar that works. However, for it to work, it depends on a.jar (which in turn might depend upon b.jar and c.jar ... you get the point). When I, as a developer, bundle up my deliverable, a x.jar, there is a dependency - on whoever I am handing this out to - to make sure that the classpath is correctly set in the other environment where x.jar is supposed to work.

It is not that big a deal, mostly. However, it is not trivial either. There are multitude of ways that the dependencies on target environment could get messed up. There might be routine updates. There might be some other application deployed in the same production box, that needed an update on a jar that nobody thought would impact yours. We can discuss and debate the multitude of ways that these kind of mishaps can be stopped, but bottom line is x.jar (the developers responsibility) has dependencies (that the developer do not directly control). And that leads to mishaps.

Of course, if you add into this mix the whole lot of variables that comes in because of different versions, different application servers, etc etc. the existing solution of providing x.jar only, quickly starts looking very fragile.

So, what do we do?

Say thanks to Dr. P. Simon Tuffs. This gentleman explains how he catered to this problem in this link. It is a good read, I recommend it. What I have explained in very laymen terms (and have barely scratched the surface), Simon takes a deep dive into the problem and how he solved it. Long story short, he coded a solution and made it open source.

I am not going to replay the same information again - read his article, it is quite informative - but I will call out the salient point of his solution.
1. It allows folks to create a single jar that contains everything - your code, resources, dependencies, application server (potentially) - everything.
2. It allows the end use to run this entire humongous jar by the simple java -jar jarFileName command.
3. It allows developers to develop the same way they have been developing e.g. if it is a web application, the war file structure, remains same. So there are no changes in the development process.
Fine. So how do we go about doing it?

There are many places where it is detailed out. The One-JAR website. Ant with One-JARMaven with One-JAR

Let's see it in action on our dummy code. Thankfully there is also a Maven plugin for this. Sadly it is not in the Maven Central repository (Why? Folks why? You have put in 98% of work. Why be sluggish about the last 2%?). It comes with nice usage instructions

Updated file: /executableJar001/pom.xml
...

...

...

org.dstovall
onejar-maven-plugin
1.4.4

one-jar


Now all you need to do is run mvn -e clean package. You will get, apart from the normal jar, a fat self sufficient jar as well. Go ahead, do the java -jar jarFileName from command prompt again. It should work.

Hmm.. that sounds good. Why isn't everybody going for this? And this One-JAR seems to be around since 2004. Why are we not seeing more players in this market?

You know what they say about free lunches? There are none. While the concept is quite neat and very practical, it does not mean that every other player have decided to join in. So if your website "needs" to be hosted on one of the biggie paid application servers (I don't know why you want to keep paying for those proprietary software and folks that understand them. Should you not pay for only quality folks and rely on the open source apps that do not lock you in) One-JAR might not be a feasible solution for you. Also, I hear unconfirmed murmurs about how things might get sluggish (during load up  if your app is big. So, before you decide to commit to using this, I recommend you do a POC and make sure that other bits of your techstack are not unhappy with One-JAR.

My personal opinion is, 2004 was perhaps a little too early for this kind of thing. People were still struggling with stuff like standardization of  build and release process, getting clear player in ORM area, closing on a clear player for MVC framework etc. Not that those questions have been answered yet, or will be any-time soon. But I think the flavour of current problems in IT world are around
1. How to make DevOps work.
2. How to make the entire build and release automated.
3. How to leverage the open source libraries to provide solid dependable software while ensuring there are no heavy proprietary software causing lock-in and hence make the solution less agile for future business requirement.
And in my mind, One-JAR plays very nicely in that area. So, I definitely expect to see more of this tool and / or more tools around this concept.

And, to be fair, there are more players in this area.

Thanks to Christian Schlichtherle for pointing this out. There is Maven Assembly Plugin and Maven Shade Plugin which cater to this exact same problem. I have not tried them yet but from the documentation they look quite alright, feature wise.

Dropwizard, although not the same thing, but in essence is very similar. They have extended the whole one jar concept with embedded app server, out of the box support for REST, JSON, Logback, sort of in a nice neat package, that  you could just use straight off the shelf.

So, as I keep saying, these are nice exciting times to be in technology business, particularly if you like tinkering around with software.

### Gradle - A Maven perspective.

As reader's of my blog would know I am a bit of a Maven fanboy. I had started using Maven around 2007-8 and have never looked back. However, as is the case with everything else "change is the only constant". There are other players in this area now, and Gradle looks to be the most promising of the lot. I have decided to give it a shot and I have shared the gist of my findings / learning in this article (of course a single article would only barely scratch the surface, but it is a start none the less). If you work on java based projects, and use Maven, you might find this article an interesting read.

Gradle introduces themselves as the Enterprise Automation Tool. From what I have seen till now, I tend to agree that it does seem to tick all the boxes for a framework that aims to be that. However, that is a bit of a BHAG, salesy talk. It is a good goal to have (as in, trying to be the Enterprise Automation Tool) but personally I think it is an ambition rather than a reality at the moment.

Stripping ambition and sales pitch - from a java technocrat perspective - Gradle (looks like) fast becoming a good tool to handle all build and release related activities for java projects.

Why should I bother now? Maven works perfectly fine for me.

Yes, it does. I work with some pretty big enterprises, and truth be told, even if they get all their java projects on Maven, they would have made a great stride forward. So, for all practical purposes - per my experience - in a regular corporate enterprise - Maven is not only good enough, but a big leap forward, if correctly and extensively used.

Having said that, while enterprises have the luxury (and indeed also the need) to play safe with tools and technologies, it is not a luxury that we technocrats have. When a tool / technology / framework proves it's mettle, the enterprises could go and hire the consultants that know those tools (and sometimes the buzzwords) and those technocrats who have not spent enough effort to keep themselves updated could find themselves scrambling to keep up. The trick is to know which technology to invest time on and which not.

As for Gradle, it has managed to get some really impressive patrons. Spring folks have moved Spring core to Gradle. Hibernate folks documented in detail the reasons for them moving on to Gradle. Grails folks seem to have a strong opinion in favour of Gradle.

I am not going to try and enlist the goodness of Gradle. For one, I don't know enough about the tool yet. Secondly, the links that I have already shared are from some pretty big names, working with pretty successful technology companies, and they have done quite a good job of putting together the benefits of Gradle.

My simple summary would be

1. Gradle allows you to code stuff in Groovy. Hence, you could pretty much code whatever you want your build and release script to do.
2. Gradle - having the chance to learn from it's forerunners like Maven - seem to have fixed a few problems right at the onset. Handling multiple modules, working with multiple source folders etc would be good examples.
3. Not being around as long as Maven means that support is a bit sketchy. The plugin for STS that I used, definitely had some rough edges.
4. Since you could code pretty much anything you wanted, it is just as easy to shoot yourself in the foot. Being so flexible - I think would mean a difficult time for enterprises to have a standardized build and release across projects, using Gradle.

So, there you go. Two points in favor and two points against. Pretty balanced. :) This was enough to get me interested. If you are intrigued as well, pray read on.

Ok. So, how do I start?

I would recommend you start by bookmarking a few links.

Building and Testing with Gradle, the ebook. It is totally worth the registration. I recommend it.
Finally the Gradle User Guide, which you will be able to better comprehend after you have spent some more time with Gradle.

We need to tweak the gradle.bat file a bit. Add a JAVA_HOME at the beginning of the batch file. Gradle needs to have access to java installation of the machine. Leave the rest of the file as is.

SET JAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0_09
...
@if "%DEBUG%" == "" @echo off ...
...


Now, just to test that you have got the right stuff wired together, create a batch file. It is just one line, so you could have just typed it on command prompt. But I tend to put this in batch file as I tend to add more stuff in this later on.

gradle -v


If you run this batch file you will see Gradle announcing it's version. If you are with me till now you have vanilla Gradle working on your machine. Congratulations. However, that is not going to be enough for most of your practical purposes. Let's stack up a bit more on tools.

I don't use Eclipse anymore. STS has done a very good job indeed and I have been using that for a couple of years now. Fortunately, there is a Gradle plugin for STS as well. The installation procedure is well documented and I will not repeat it here.  However the installation procedure fails to convey that it is not really quite as straightforward. I tried it on two different machines and had to go through quite a few hoops before I could get it to work. My advice will be to not try it with your work installation of Eclipse / STS, unless you can afford to have it broken for a couple of hours. Make another instance of STS and work off it. Your perseverance will be paid off by a new Gradle import functionality (and a few others, that we will check later), in STS.

One last thing - before you go further, open up "preferences" in STS and set Gradle to be the C:\ProgramFiles\gradle-1.3 folder. I like to make sure that STS is just running the vanilla Gradle and nothing else. If need be, I can get out of STS and type the same commands on command prompt and be assured of the same result. I like to do things from the editor but despise being locked in.

Once that is done, you need a java based project (using Gradle) to import.

How do I create a Gradle based Java project to import in STS?

This is where fun starts. Just create a folder (I will call it gradle001). Put a build.gradle file in it. This is all that is needed for STS now to import it. There is a bit of theory behind what goes into build.gradle. I will not delve into it right now. Let's just look at the following build.gradle file.

apply plugin: 'java'

def localMavenRepo = 'file://D:/mavenrepo'
repositories {
mavenCentral()
maven { url= localMavenRepo }
}

sourceCompatibility = 1.7
version = '1.0-SNAPSHOT'

dependencies {
testCompile 'junit:junit:4.11'
}


Do you see the interesting part now? Although I have not added a single line of comment in the file, can you guess what most of the instructions mean there? Most of you would, I hope. Just so you know, I have been using Maven and the local repository was saved at D:/mavenrepo. Using Gradle I could just reuse that local repository and also use the maven central repository. The way I see it, Gradle could not have been friendlier with Maven and I love Gradle for making effort to make developer's lives that much easier.

Now, we will fire up the STS (with Gradle) and import "a new Gradle project", where we will import the folder structure that we just created. If everything was alright, you will see the project nicely sitting in your "project explorer" view of STS. My personal experience was a bit sketchy on this. I had to try it a couple of times before I got it to work. But once the import was successful, things were much smoother.

But this project does not having anything. Maven used to give me more complete project with a dummy main class and a test class.

Yes. Maven used to "create" a project for you and you could choose from any of the many templates (archetypes) to create your project structure. Alas, I could not find a similar functionality with Gradle (as I admitted right at the beginning of this article, I am new to this tool and hence if I am missing something please let me know. Leave a comment please).

It is a fact that there is no dummy project created for you. However the strength of the tool i.e Gradle is not that. We have already seen how easy it was to read build.gradle. Now let's write some dummy code and see for ourselves what Gradle can do for us.

package foo.bar;

public class AppMain {
public static void main(String[] args) {
System.out.println(new AppMain().greet());
}
public String greet() {
return "Hello world.";
}
}


package foo.bar;

import static org.junit.Assert.*;

import org.junit.Test;

public class AppMainTest {

@Test
public void test() {
assertEquals(new AppMain().greet(), "Hello world.");
}

}


apply plugin: 'java'

def localMavenRepo = 'file://D:/mavenrepo'
repositories {
mavenCentral()
maven { url= localMavenRepo }
}

sourceCompatibility = 1.7
version = '1.0-SNAPSHOT'

dependencies { testCompile 'junit:junit:4.11' }

task(runSimple, dependsOn: 'build', type: JavaExec) {
main = 'foo.bar.AppMain'
classpath = sourceSets.main.runtimeClasspath
}


That's all. Now if we run the "runSimple" task of the build.gradle, Gradle will do a awful lot of stuff for us. It will do the standard clean, compile, test, produce a test report (Check out the /gradle001/build/reports/tests/index.html in your machine, assuming you have been coding the stuff as well till now. You will be pleasantly surprised) , build and finally run the main class. All that for around 18 lines of build.gradle. I must say I don't think that is a bad deal at all.

Oh, but that is 18 lines of code to build around 25 lines of code. What's the big deal?

You are right. But you are missing the point. Even if it was 25,000 lines of code, these 18 lines of build script would have done just fine. If you are still not convinced, I recommend you to read this article, where a 264 lines build script seems to be doing phenomenally well.

Umm ... fine, but Maven "might" have not been much lengthier either?
You might be right. Although people seem to be providing all sorts of arguments and data against that possibility but I don't think that is the relevant point to discuss.

The fact is pom.xml in Maven is just a configuration file. On a regular day, a regular build and release person does not code anything in Maven. Of course Maven allows you to create all sorts of plugins and they solve "most" of the problem. But, it seems like, that precisely (the "most") is the point of contention. In places where the scenario / requirement falls outside "most" scenarios, Maven is a very difficult thing to work with. And as technology ecosystem is getting increasingly diverse, people are revolting against that shackle.

Personally, I think this is how the story goes. The batch files (xyz.bat) files were wildly powerful but they were a pain (read impossible) to manage. You had to write them differently for different OS. There was no task hierarchy. I don't know anyone who liked to maintain them for any but the most trivial of projects.

Hence came in Ant. It was also wildly powerful and did a good job with task management. You had targets for almost everything and for those that you did not have you could just code in a batch file and call that from Ant. Where it fell short was the standardization. People used it in all possible sorts of ways in their projects and in most projects, the build scripts became a project by themselves. They were difficult to manage, only a couple of people in the team knew exactly how they worked and none wanted to have to modify them.

This is where Maven scored big time. It catered to "most" requirements like charm, in a consistent fashion. There was a set way to do most of the things. So, build scripts were not a black hole anymore. And the average Joe was less likely to shoot himself on the foot with Maven scripts.

With Gradle we are flirting with greater power. The average developer would be expected to code with Gradle and not only configure plugins (as in Maven). So, the average developer will have a easier time getting the job done as he / she feels fit.

And that is precisely when the project would have taken up a risk of creating a build script that could potentially do deep damage, have no knowledge base around it, developers will love coding in it but hate maintaining it, managers will have nightmares about build script failing on the day before demo and will have to live with it.

That does not sound very encouraging. What exactly are you saying then?

From what I have seen of Maven - and people seem to agree with me, whether or not they prefer Gradle - it does a good job for standard / average / most requirements. It does what it does extremely well. And there are boundaries that it does not allow you to breach, where it could be seen both as a shackle as well as a safety feature. If you are creating another J2EE web application / java desktop application with standard tech stack, I would say there is no reason to ditch Maven. If you have not embraced it yet, please do, your life will be much easier.

However, if you are in a product development project and you are pushing the boundaries of what java / j2ee have been perceived to be capable of (and assuming you have not hired only average Joes) I think you might want to have a go at Gradle. It is really capable. It is fun to work with. I think the road ahead for Gradle is really bright and full of possibilities. It is a good thing to invest time on.

That is all for today.

If you have read till now hopefully you have liked this or at least found it engaging. My article is based solely on my tinkering with Gradle and that is not the last word on this topic by any stretch of imagination. If you find anything that is wrong - or right in this article, please leave a comment below. I will be much obliged.

If you want to get in touch, you can look me up at Linkedin or Google+ .

### How to un-install a plugin from Eclipse / STS?

It is easy to do - a few button clicks (generally) - but the button location is damn unintuitive. So, this is what you have got to do

1. Go to "Help" menu item.
2. Click on "About ..." button (why on earth should I click that when I am trying to un-install a plugin. By the way, the menu item just above "About ..." is "Install New Software ...". Would it have been too much pain to have a "Manage plugins" and / or "Un-install plugins" right underneath it?)
3. A form opens up. At the bottom of it there is button "Installation details". Click that. (Again, why on earth would anyone think "Installation details" would have anything to do with un-installing stuff. I would have expected only a static display of stuff that are already installed.)
4. Another multi tabbed form opens up (Anyone keeping count of the number of windows opened already. This is the 3rd window by now, including the parent editor window) which shows all the installed plugins.
5. If you select any of the installed plugins, a button to "uninstall" becomes available.
6. Click that and you should be able to un-install and after a restart everything should be fine.

My interest in software and IT has always been much more than a 9 to 5 job (and I am sure there is a huge population that it holds equally true for). I have always wanted software to be efficient and beautiful apart from doing it's job. However, it took an excellent session on usability (which I joined only with casual curiosity but left with renewed interest in the subject and admiration for David Travis who delivered the course)  to get me to start looking at all software with an "user's" perspective. And I was surprised with what I found and how it changed my coding.

I have been using Eclipse and STS for years now (nearing a decade now) and I absolutely love these software. However when you start looking at them as a "user" and not only as a developer, there are quite a few usability opportunities of improvement that meets the eye.

This article - apart from helping folks looking to un-install plugins in Eclipse - is also intended at folks who design Eclipse - just a humble request to consider this also as a usability improvement.

### REST with Spring 3

In this article we will learn to create a basic REST service (hello world) using Spring 3, Logback, Maven, Tomcat, and Eclipse.

I have already written about Hello World with Spring 3 MVCHandling Forms with Spring 3 MVCJUnit, Logback, Maven with Spring 3Handling Form Validation with Spring 3 MVCIntroducing Spring Integration and Spring Integration with Gateways. This is an extension of the same series of Spring 3. It is not necessary, but it might be helpful for the audience to have a cursory glance at previous articles.

REST is best explained to a layman at How I Explained REST to My Wife. Clear, concise, conversational and informational. That's how articles ought to be. Easier said than done. For the geeky ones, here is the link to the PhD thesis by Roy, where he introduced the term REST. Google on if you want to know about the rest of REST :)

Spring 3 has excellent support, should you chose to go the REST way in your architecture. I highly recommend this article and the official documentation provided by SpringSource. Also there are some excellent material by IBM.

With that context setting done, let's roll up our sleeves and fire up the editor. We will learn as we code. To begin with, we will create a basic web application using Maven archetypes. Maven Tips is worth a quick read at this point, if you are not hands on with Maven.

File: \MavenCommands.bat

ECHO OFF

REM =============================
REM Set the env. variables.
REM =============================
SET PATH=%PATH%;C:\ProgramFiles\apache-maven-3.0.4\bin;
SET JAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0

REM =============================
REM Standalone java web application.
REM =============================
call mvn archetype:generate ^
-DarchetypeArtifactId=maven-archetype-webapp ^
-DinteractiveMode=false ^
-DgroupId=foo.bar.spring3 ^
-DartifactId=rest001

pause


If you run this batch file, it will give you a nice and functional web site, with correct folder structure, ready to be deployed on any of the many servlet containers (Tomcat 7 in my case), without writing a single line of code at all. If that alone does not make you check Maven website, I don't know what will (assuming of course that you don't use Maven already).

At this point I generally import it into Eclipse (I use STS and can honestly recommend it. Although I have to admit I am using 2.9.1 version for the current article and not the latest one, because that was being a bit twitchy. I am hoping this is temporary). If you are using standard Eclipse, consider investing time in getting m2e configured (with STS you get that pre-configured). I don't recall when was the last time I had used the standard build icon of Eclipse. My fingers type Alt+Shift+X, M  by muscle memory now, and I love m2e for making this seamless.

The next thing is to use Maven to get all requisite libraries.

File: \rest001\pom.xml

<!-- Unit test. -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>

<!-- Logging -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.6</version>
</dependency>

<!-- A bridge between commons logging and slf4j.
It is required for Spring classes. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.6.1</version>
<scope>runtime</scope>
</dependency>

<!-- Spring MVC, without standard commons logging -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.1.3.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>


I have put brief remarks on each of those dependencies. Hopefully it will be enough for you guess what they are for. If not, don't worry, we will find out soon.

Our next job is to configure our web application to handover all incoming requests to Spring (FrontController is it?). This is done quite easily.

File: \rest001\src\main\webapp\WEB-INF\web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">

<!-- Register Spring servlet. -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>

<!-- Send all requests to Spring -->
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

</web-app>


A couple of thing to note here.

Note 1: The header and the web-app section of this file is much beefier than the standard web.xml that Maven had created. You need this for JSTL to work. We will use JSTL later in the article.

Note 2: It is tempting to put the URL pattern as * instead of /. It works, but only till you get to the point of view resolution. At that point it refuses to find the view even with correct path. I just spent some humiliating amount of time chasing this issue. Avoid it.

Now, we have already asked the website to route all incoming requests to Spring servlet. We need to now configure the Spring servlet. Again, xml is the answer, although this one is going to be a bit chunky. Don't be afraid of the xml. I will explain that in plain english immediately after.

File: rest001\src\main\webapp\WEB-INF\spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<!-- Enables automatic scan for the class that has Spring annotations -->
<context:component-scan base-package="foo.bar.controllers" />

<!--To enable @RequestMapping process on type level -->
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

<!--To enable @RequestMapping process on method level -->
<bean

<!-- Content negotiation. -->
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
<entry key="html" value="text/html" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
</bean>

</beans>


In plain english, this is what we have done. We have told Spring to look for Controllers in the package foo.bar.controllers. We have also said that the requests to the website, depending upon their format, could be hooked up with methods, wherein we will write code to handle those requests. Finally, we have in a oblique way (under the content negotiation bit) said that the views i.e. the stuff that shows up in browser (or other screens) should be served by jsp pages under WEB-INF/views directory.

Now we are at final piece of configuration. We need to tell logback, which we are going to use for logging (I am a bit of stickler when it comes to logging. You might want to read Log don't SOP, Logging revisited) what all to log and how.

File: \rest001\src\main\resources\logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p | %t | %-20logger{20} | %m %n</pattern>
</encoder>
</appender>

<!-- Turn off 3rd party logging -->
<logger name="org.springframework" level="OFF" />

<root>
<level value="DEBUG" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>


Now we are all set to write a piece of code that will handle a REST style URI and respond to it. If you are hands on (even occasional coder) you will find that it does not take more than 10 - 15 minutes to have this bit up and running.

It is worth reflecting on this fact. Starting from an empty directory, to having all the bells and whistles in place to start writing a REST style webservice, complete with support for continuous integration, support for unit / integration testing, support for code quality software like Sonar, support for industrial strength logging like logback is not a trivial bit. Not too long back - say a decade back - it would take weeks to get this much framework configured, if not months. One can not help but appreciate the kind of efficiency that tools like Spring, JUnit, Logback, Eclipse etc have brought in to IT industry. And it also follows that hands on knowledge of the tools in market is that much crucial. It might be the difference between the success and failure of a project.

Anyway, rant aside, let's write the final pieces. A class.method() to handle the request.

File: \rest001\src\main\java\foo\bar\controllers\HelloWorld.java

@Controller
public class HelloWorld {
private final static Logger logger = LoggerFactory
.getLogger(HelloWorld.class);

@RequestMapping(value="/greet/{name}", method = RequestMethod.GET)
public String greet(@PathVariable String name, ModelMap model){
logger.debug("Greeting {}", name);
return "greet";
}
}


And a view to deliver the result.

File: \rest001\src\main\webapp\WEB-INF\views\greet.jsp

<html>
<title>REST with Spring 3</title>
<body>
Hello, \${name}.
</body>
</html>


All done. Compile this and put it in Tomcat. You should be able to hit http://localhost:<portnumber>/rest001/greet/partha and have the web page greet you back. You will notice that there are no .jsp or .html or .do with the URL. These are the REST style URLs. In later articles we will look at more details, run some tests and look at some alternate ways for achieving REST style URLs.

With this I will close this article, but I will leave you are parting question to ponder upon. Are these the baby steps towards internet of things?

If you want to get in touch, you can look me up at Linkedin or Google+.

### 0 to 10,000

0 to 10,000. No this is not some insane acceleration figure of some super car. It is the number of hits that the blog Tech for Enterprise have received in the first 8 months.

What is so big about that? Nothing really, if you look at the macro picture. In this age when every other month a new app is getting a few million hits / downloads in the first few days, this is hardly a ripple in a ocean. Ripple it might be, but it is my doing. I did it in my terms and am feeling mildly proud of it at the moment.

The shot to fame of this blog are quite a few.
1. At last count, 14 articles of this blog have been published at dzone and these articles have generated a staggering 50,000 (approx) page hits (these do not include the 10,000 of this blog).
2. The folks at Java Code Geeks have also entered a contract to reproduce articles from this blog at their site. They have reproduced 12 articles from this blog and that has also generated around 11,000 hits on their site. (Thanks Ilias @ JavaCodeGeeks for fetching this data for me.)
3. Lastly, and perhaps most importantly, the content of this blog have been referred to at SpringSource a couple of times (link).
4. Needless to say, all this has meant that I have come in contact with similar minded technocrats from all across the world. These online contacts have been a source of many, very interesting conversations that have definitely left me more humble and hopefully more knowledgeable person.
I also want to take this opportunity to acknowledge the contribution of certain two individuals as far as this blog is concerned. One is my manager, who after an intense debate almost a year back, convinced me that there is value in visibility when attained for correct reasons and by right means. Thanks sir. Another is my colleague, friend and neighbor at office, who have put up with my techno geek ramblings for well over a year now, for absolutely no fault of his and have managed to keep a straight face for most of this duration. Thanks mate, for bearing with me.

### Java and Database.

Every once in a while I tend to put on some music, switch off distractions (emails, phones) and redo some basic programming. Things that I know and I have done a handful of times. The intent is to practice, get back to basics and hope to get some new insight. I later read about CodeKata and realized that what I had been doing was not entirely unheard of. For anyone who treats building software as a craft, I can safely recommend this practice.

Enough rambling. In this article I am going to talk about using Java to connect to database. Elementary, you say. Absolutely, I concur. I highly recommend the links Connecting to an Oracle DatabaseClosing Database Connections in Java for a clear, concise read, in case you were looking to get those answers. However, if you are interested in a little more detailed, hands on, journey through the subject, I suggest you read on.

Tools

Oracle. I have worked with a variety of RDBMS and/or NoSql (link) based applications and have no sweeping opinion for / against any of those. However, I tend to choose Oracle (express edition) even for my development environment. Call me old fashioned, but till I don't get to log into a "database server" and run queries to confirm that what I "think" my app did in database, I don't feel confident about my code.

Maven + Eclipse. I would tend to agree with anyone who says Maven is an overkill for simple applications (under 10 classes). But again, it's my gut. I don't feel confident if I don't use tools that I will use in any enterprise grade application in my codekatas (for the lack of a better name). After all, when you practise your skills, if you don't use the proper tool set, the practise session is a bit pointless, isn't it.

Getting warmed up

As I mentioned I use Maven. I have a batch file with the basic Maven commands (read more about it) that I use to create any new java application and then import it in Eclipse. Minus all the noise, this is how the batch file looks like.

File: \MavenCommands.bat
REM =============================
REM Set the env. variables.
REM =============================
SET PATH=%PATH%;C:\ProgramFiles\apache-maven-3.0.4\bin;
SET JAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0

REM =============================
REM Standalone java application.
REM =============================
call mvn archetype:generate ^
-DarchetypeArtifactId=maven-archetype-quickstart ^
-DinteractiveMode=false ^
-DgroupId=foo.bar ^


This creates a complete java application, with a dummy class, a test case etc. The pom file contains most of the details. I tend to add a few standard elements in the pom file before I try anything else. In this case I will add the oracle thin client as well.

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>

<!-- Unit test. -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>

<!-- Logging -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.7</version>
</dependency>

<!-- Oracle database driver. -->
<dependency>
<groupId>ojdbc</groupId>
<artifactId>ojdbc</artifactId>
<version>14</version>
</dependency>

</dependencies>

<build>

<!-- Compile and run with current Java version -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>


If you run this "mvn -e clean install" this should download all dependencies and compile just fine.

The code (finally)

In this case I think a JUnit test case would work just fine. We just need to create an instance of the driver (to connect to Oracle), give it some standard data, attempt a connect and then attempt a disconnect.

public class TestConnection {
private final static Logger logger = LoggerFactory
.getLogger(TestConnection.class);

@Test
public void test() {

Connection connection = null;
try {
String driverName = "oracle.jdbc.driver.OracleDriver";
Class.forName(driverName);

// Create a connection to the database
String serverName = "127.0.0.1";
String portNumber = "1521";
String sid = "XE";
String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber
+ ":" + sid;
assertNotNull(connection);
logger.debug("All well");

} catch (ClassNotFoundException e) {
logger.debug(e.getMessage());
} catch (SQLException e) {
logger.debug(e.getMessage());
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
logger.debug(e.getMessage());
fail("The connection could not be closed.");
}
}
}
}
}


You will note that although it is the most basic (and useless functionality wise) piece of code, it is quite well behaved. It catches the required exceptions, and it attempts to close the connection. What is perhaps not as easily seen is that it is a well behaved code in enterprise applications scenario as well. It uses a standard and robust logging mechanism i.e. Logback. It uses a standard build, release (and more) tool i.e. Maven.

In a nutshell if you could think of a sort of virtual shelf, where your software engineers could walk up to and pick standard code templates, this is one of those. Impractical in it's present form but I hope you get the concept.

For those, who are still with me (congratulations by the way), and are interested in the whole codekata concept that I referred to at the beginning of the article, there is a wee bit more.

Can we bring down the boilerplate code?

I like Java for all it's stability and stuff. But, being a lazy human, I hate writing code that "feels like" could have been handled by the language itself. In this current code, multitude of try-catches are an eyesore. I understand why I need them but that does not necessarily mean I like writing them. Perhaps you have guessed already that I am referring to better resource management  introduced by Project Coin.

In a nutshell, Java 7 promises to handle the closing of resources i.e. Connection in this case, by itself. Let's give that a shot.

We need to tell maven that we want to use jdk 7.

<!-- Compile and run with current Java version -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>


And we need to update our test case to create Connection within a try to let java close it by itself.

public void test() throws SQLException {
String driverName;

try {
driverName = "oracle.jdbc.driver.OracleDriver";
Class.forName(driverName);
} catch (ClassNotFoundException e) {
logger.debug(e.getMessage());
e.printStackTrace();
}
// Create a connection to the database
String serverName = "127.0.0.1";
String portNumber = "1521";
String sid = "XE";
String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber
+ ":" + sid;
assertNotNull(connection);
}
}


If you compare this piece of code with the previous one, we have got rid of at least three try-catch blocks. But this code is useless in a practical scenario, you say. Totally, I agree. As I had mentioned earlier, the intent is to practice writing code - something mundane - but in multiple (hopefully new ways) and learn by practising. The intent is not to produce production ready, reusable components.  The quality of the code, the craftsmanship is important in this context. The benefit will be in terms of more skilful engineers in the organization and the associated benefit to business.

Finally, my litmus test...

this supposedly nice, high quality code, how good is it when we run it 10,000 times in 5 threads. I hate to break the news to you but it is not too good at all. It crashes after 20 - 25 executions. Why? And how to fix that? I have discussed the problem and solution at stackoverflow. I hope you find it interesting.

Re-factor

This article is getting longish and I should wrap up now. Let's re-factor this code to a position where stuff are not in unit tests any more. The code ought to be in some classes where they could be used by client code. How does the updated test code looks to you.


@Test
@PerfTest(invocations = 100, threads = 1)
@Required(max = 1200, average = 1000)
public void testConnectionFactoryAndUtil(){
Connection connection = ConnectionFactory.getConnection();
assertNotNull(connection);
Util.closeConnection(connection);
}


Compare this with the earlier test. That was 24 lines. Assuming you are convinced that this is a better looking test, how do we refactor to make this happen. It's your call really and you could do it multiple ways. Here is my take.

public class ConnectionFactory {
private final static Logger logger = LoggerFactory
.getLogger(ConnectionFactory.class);

public static Connection getConnection() {
return getConnection("oracle.jdbc.driver.OracleDriver", "127.0.0.1",
"1521", "XE", "funngames", "funngames");
}

public static Connection getConnection(String driver, String host,
String port, String sid, String user, String pass) {
Connection connection = null;
try {
Class.forName(driver);
String url = "jdbc:oracle:thin:@" + host + ":" + port + ":" + sid;
connection = DriverManager.getConnection(url, user, pass);
logger.info("Connection opened [{}]", connection.toString());
} catch (ClassNotFoundException e) {
logger.debug(e.getMessage());
e.printStackTrace();
} catch (SQLException e) {
logger.debug(e.getMessage());
e.printStackTrace();
}
return connection;
}
}


public class Util {
private final static Logger logger = LoggerFactory.getLogger(Util.class);

public static void closeConnection(Connection connection){
if (connection != null) {
try {
logger.info("Attempting connection close [{}]", connection.toString());
connection.close();
logger.info("Connection succesfuly closed.");
} catch (SQLException e) {
logger.debug(e.getMessage());
e.printStackTrace();
} catch (InterruptedException e){
logger.debug(e.getMessage());
e.printStackTrace();
}
}
}
}


Needless to say, any of this code is hardly new or ground breaking. You might want to check out this class for a much more comprehensive set of utility functions to close connection and related resources. Feel free to use that utility (it is from Apache) or roll your own.

With this I will close this article. If you want to get in touch, you can look me up at Linkedin or Google+.

### Maven Tips

I am a bit of a Maven fanboy. Actually I am more of a - use anything available to make your task easier, smoother and more efficient - person.  And Maven has fit the bill perfectly for near about 3 - 4 years now.

I had written earlier about Maven here. In a very recent conversation around standardization of toolkit for software project / product lifecycle, I realized that Maven was perhaps one of the lowest common denominators to start from (speaking of Java world). I simultaneously - as I was rattling off the virtues of adopting Maven enterprise wide, to the audience - realized that I had not really written enough about it. And hence this article.

With something as widely used as Maven, I don't see much reason to write, yet again, about how to set up, how to use etc. You will find almost everything very neatly described in the Maven website. I have found loads of very good articles on Maven at this link as well. However, I will share a couple of tips here.

Tip 1
The beauty of Maven (and indeed most of the Java based software) is that the installation is too simple. You just put the jar in a folder of your choice and the software just works. Most of the default configurations are good enough for first use. However, there is one bit that I suggest you change. Change the localRepository - the folder where Maven would download dependencies for your code from internet and store in your harddisk - to something that suits you. I like to put it in a drive that is not my primary drive i.e. not the drive in which I have Windows installed. So, in case the windows dies on me, or something happens, this folder with all the dependencies have a better chance of being retained. As you write code, this dependencies folder tends to grow and should you lose it you will have to spend considerable amount of time and bandwidth to download all the stuff.  So, all that I suggest you do is add the following configuration to the default configuration.

File: \apache-maven-3.0.4\conf\settings.xml
<localRepository>D:/mavenrepo</localRepository>


Tip 2
I dislike polluting (some people will disagree that this is "polluting") my system settings with product specific stuff e.g. JAVA_HOME etc. I have always found it much easier to use a simple batch file instead. I use that with Maven as well. I tend to have this (or some variation of this) batch file, which when run (after taking off the appropriate REMs) will do the basic stuff e.g. creating a java application, creating a web application, running them, executing a specific unit tests etc. These instructions are easily available, but I personally found it useful to have it handy and ready.
ECHO OFF

REM =============================
REM Set the env. variables.
REM =============================
SET PATH=%PATH%;C:\ProgramFiles\SpringSource\apache-maven-3.0.4\bin;
SET JAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0_09

REM =============================
REM Check the versions.
REM =============================
REM mvn --version

REM =============================
REM Get a list of all template projects.
REM =============================
REM mvn archetype:generate

REM =============================
REM Standalone java application.
REM =============================
call mvn archetype:generate ^
-DarchetypeArtifactId=maven-archetype-quickstart ^
-DinteractiveMode=false ^
-DgroupId=foo.bar ^
-DartifactId=corejava

REM =============================
REM Standalone java web application.
REM =============================
REM call mvn archetype:generate ^
REM     -DarchetypeArtifactId=maven-archetype-webapp ^
REM     -DinteractiveMode=false ^
REM     -DgroupId=foo.bar ^
REM     -DartifactId=web001

REM =============================
REM Run the main class.
REM =============================
REM mvn exec:java -Dexec.mainClass="foo.bar.Main"
REM mvn exec:java -Dexec.mainClass="foo.bar.Main" -Dexec.args="arg0 arg1 arg2"

REM =============================
REM Run unit tests.
REM =============================
REM mvn test
REM mvn -Dtest=myUnitTest test

pause