Intro to Maven Shell

23 03 2010

Introduction
Sonatype has released a nifty utility called Maven Shell that allows developers to execute maven goals/phases in a pre-loaded shell environment, significantly reducing the build time. It does this by loading up a JVM, Maven, and any loaded plugin once and leverages that existing load for each subsequent build. I downloaded the .10 binary and played around with it with a very simple multi-module project. Here is a quick primer on some of the things you can expect from Maven Shell.

Efficiency
I used a simple multi-module JEE project shell that’s mostly void of code and unit tests to test out efficiency. Because some of the overhead associated with a build is loading numerous plugins, I wanted to run this build at least one time before I started comparing it to a build outside of Maven Shell. My first build ran as such, taking 7.420 seconds:

[INFO] ----------------------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] parent Multi Project .............................................. SUCCESS [1.088s]
[INFO] Util Project ...................................................... SUCCESS [3.292s]
[INFO] beans JEE5 EJB .................................................... SUCCESS [0.830s]
[INFO] web JEE5 Webapp ................................................... SUCCESS [0.807s]
[INFO] app JEE5 Assembly ................................................. SUCCESS [1.123s]
[INFO] 
[INFO] ----------------------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ----------------------------------------------------------------------------------------
[INFO] Total time: 7.420s
[INFO] Finished at: Tue Mar 23 13:46:19 EDT 2010
[INFO] Final Memory: 16M/79M
[INFO] ----------------------------------------------------------------------------------------

The subsequent build took 3.519 seconds:

INFO] ----------------------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] parent Multi Project .............................................. SUCCESS [0.264s]
[INFO] Util Project ...................................................... SUCCESS [1.569s]
[INFO] beans JEE5 EJB .................................................... SUCCESS [0.404s]
[INFO] web JEE5 Webapp ................................................... SUCCESS [0.509s]
[INFO] app JEE5 Assembly ................................................. SUCCESS [0.673s]
[INFO] 
[INFO] ----------------------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ----------------------------------------------------------------------------------------
[INFO] Total time: 3.519s
[INFO] Finished at: Tue Mar 23 13:58:24 EDT 2010
[INFO] Final Memory: 25M/79M
[INFO] ----------------------------------------------------------------------------------------

Great, but how does this compare to running maven via the command line outside of Maven Shell? Running outside of Maven Shell, the build took 7.085 seconds:

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] parent Multi Project .............................. SUCCESS [1.024s]
[INFO] Util Project ...................................... SUCCESS [3.787s]
[INFO] beans JEE5 EJB .................................... SUCCESS [0.341s]
[INFO] web JEE5 Webapp ................................... SUCCESS [1.029s]
[INFO] app JEE5 Assembly ................................. SUCCESS [0.691s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.085s
[INFO] Finished at: Tue Mar 23 13:59:43 EDT 2010
[INFO] Final Memory: 13M/79M
[INFO] ------------------------------------------------------------------------

That’s about a decrease of ~4 seconds execution time for this very simple build, with hardly any plugins loaded. I’d imagine multi-module builds with numerous plugins executed in Maven Shell would see an exponential decrease in time to finish.

Note: After completion of this blog, I downloaded the source for Maven Shell 0.11 SNAPSHOT and built that using the .10 binary, to test these efficiency increases on an actual project with real source and real plugin inclusions. I had even better results. The initial mvnsh clean install took ~23 seconds, each subsequent clean install took ~13 seconds and the standard command line build took about ~20 seconds. That’s a savings of about ~7 seconds on every build!

Navigation
Maven Shell provides a bash-esque shell for navigation and binary execution, at least on my Mac; I imagine it would be the same on Linux distros (Windows?). You navigate as you would in a regular shell, using the cd command. The command prompt will look something similar to this :

mvnsh(/logging/logger):~/Projects/fyb_maven_workspace/multi-example> 

The mvnsh prefix helps identify to the user they are in the Maven Shell environment. The value in the parenthesis identifies which command group the user is currently in. Currently we are in the /logging/logger command group. We’ll cover command groups in a subsequent section. After the command group and colon, the current location in our file system is identified. In our example, we are in the ~/Projects/fyb_maven_workspace/multi-example directory.

Executing A Command
Executing a command is as easy as it is in the bash shell, simple type the name of the command and any parameters and press return. Changing a directory:

mvnsh(/):~/Projects/fyb_maven_workspace/multi-example> cd ..
mvnsh(/):~/Projects/fyb_maven_workspace> 

Help
Typing help or ? and pressing return will provide the help menu. The help menu will identify all the commands available to the user. To receive help on a specific command, type help command. For example, to receive help on rm, type help rm and the user will be provided with a man page on the rm command.

Something very important to know is that help is command group aware. If the current command group is /pref, not only will you see all the default commands available, you will be presented with the commands available to the pref command group.

Here is the root(/) help listing:

mvnsh(/):~/Projects/fyb_maven_workspace/multi-example> help
Available pages:
  .                 Alias to: source
  ?                 Alias to: help
  alias             Define an alias or list defined aliases.
  archetype         Command group: archetype
  cd                Changes the current directory.
  dir               Alias to: ls
  echo              Print arguments to standard output.
  encrypt-password  Encrypt passwords.
  exit              Exit the current shell.
  help              Display help pages.
  history           Display history.
  hostname          Displays the name of the current host.
  info              Display information about the shell and environment.
  install-jna       Alias to: source /Developer/Applications/mvnsh-0.10/scripts/install-jna.msh
  logging           Command group: logging
  ls                List the contents of a file or directory.
  mkdir             Create a directory.
  mvn               Execute Maven.
  nexus             Command group: nexus
  pref              Command group: pref
  pwd               Displays the current directory.
  recall            Recall an item from history.
  rm                Remove a file.
  rmdir             Remove a directory.
  set               Set a variable or property.
  shell-env         Shell environment variables overview.
  shell-files       Shell configuration files overview.
  shell-navigation  Shell navigation overview.
  shell-syntax      Shell syntax overview.
  source            Execute commands from a source into the current shell.
  unalias           Undefine an alias.
  unset             Unset a variable or property.
  wget              Fetch a file from a URL.

And the help listing from within the /pref command group:

mvnsh(/pref):~/Projects/fyb_maven_workspace/multi-example> help
Available pages:
  .                 Alias to: source
  ?                 Alias to: help
  alias             Define an alias or list defined aliases.
  archetype         Command group: archetype
  cd                Changes the current directory.
  dir               Alias to: ls
  echo              Print arguments to standard output.
  encrypt-password  Encrypt passwords.
  exit              Exit the current shell.
  export            Export preferences.
  get               Get a preference.
  help              Display help pages.
  history           Display history.
  hostname          Displays the name of the current host.
  import            Import preferences.
  info              Display information about the shell and environment.
  install-jna       Alias to: source /Developer/Applications/mvnsh-0.10/scripts/install-jna.msh
  list              List preferences.
  logging           Command group: logging
  ls                List the contents of a file or directory.
  mkdir             Create a directory.
  mvn               Execute Maven.
  nexus             Command group: nexus
  pref              Command group: pref
  pwd               Displays the current directory.
  recall            Recall an item from history.
  remove            Remove preferences.
  rm                Remove a file.
  rmdir             Remove a directory.
  set               Set a preference.
  shell-env         Shell environment variables overview.
  shell-files       Shell configuration files overview.
  shell-navigation  Shell navigation overview.
  shell-syntax      Shell syntax overview.
  source            Execute commands from a source into the current shell.
  unalias           Undefine an alias.
  unset             Unset a preference.
  wget              Fetch a file from a URL.

Notice the addition of the list, set, get, unset, remove, import, and export commands.

Command Groups
Command groups are a logical way of grouping like commands together, in a hierarchical fashion. It allows for easy execution of specific commands within a command group. For example, the /logging/logger command group has the following commands:

mvnsh(/logging):~/Projects/fyb_maven_workspace/multi-example> help logger
Help pages in group logger:
  set     Set the level of a logger.
  list    List loggers.
  levels  List valid logger levels.

If we are in the /logging/logger command group, we can execute the levels command to print out the list of logging levels available to the Maven reactor during a build:

mvnsh(/logging/logger):~/Projects/fyb_maven_workspace/multi-example> levels
TRACE
DEBUG
INFO
WARN
ERROR
OFF

You can execute a command no matter where you are in the command group hierarchy if you specify it’s full path, ie printing logger levels from within the /pref command group.:

mvnsh(/pref):~/Projects/fyb_maven_workspace/multi-example> /logging/logger/levels
TRACE
DEBUG
INFO
WARN
ERROR
OFF

Features
There is a laundry list of features on the Maven Shell wiki site, look for a subsequent blog on these features in detail.

Conclusion
If you’re a developer using Maven and do a lot of your interaction with Maven from the command line, I highly recommend taking a look at Maven Shell. It’ll shave precious time from builds allowing you to accomplish more in your day all the while providing a nice interface for interacting with Maven. Keep in mind, it won’t speed up unit tests, plugin execution, etc, but will remove the overhead associated with loading these items every launch.

References
Sonatype
Maven Shell
Maven Shell Wiki
James Lorenzen’s Blog

About these ads

Actions

Information

29 responses

24 03 2010
Chris Wash

Cool! So it looks like this is only for Maven 3, if you want to use something similar in Maven 2 you need to use the maven-cli-plugin? Have you tried that?

Gotta love command line tools. Some other cool command line tools I like with JBoss:
http://community.jboss.org/wiki/Twiddle
http://community.jboss.org/wiki/BSHDeployer

24 03 2010
ericmiles

Removing content of comment as it was incorrect information.

Note: Matthew McCullough responded below that Maven Shell does indeed use Maven 3 binaries (jars). However, from what I’ve read, it seems as though the Maven 3 developers have put significant effort into making Maven 3 backwards compatible. Your Maven 2 based projects should still work (and the ones I’ve tested with certainly do still build appropriately).

26 03 2010
Matthew McCullough

Guys,

Maven Shell is indeed a Maven-3-only tool. It uses the Maven 3 binaries (JARs) at its very heart. Such a tool was not fully possible with Maven 2.

It is true that I’m looking to refocus future efforts of myself and other folks who contributed to maven-cli-plugin (for Maven 2) onto Maven Shell (for Maven 3). Maven Shell is a much more promising platform for the next few years and offers far more extensibility then we could achieve with maven-cli-plugin.

-Matthew McCullough

26 03 2010
ericmiles

I went back and re-read where I thought Jason van Zyl stated it would run on Maven 2 and the point was it supports Maven 2 based projects through the Maven 3 binaries’ backwards compatibility feature. On the feature list in the source in github, it states it includes a Maven 3 binary. However, Maven Shell can be built with Maven 2. What comes first, the chicken or the egg? :-D

Thanks for the confirmation Matthew.

26 03 2010
ericmiles

Chris,

You might have even seen it during your stint there, but we used BSH deployer at a certain state client of ours for JBoss Portal topology deployment.

25 03 2010
Baptiste Wicht

Really interesting, thanks :)

I wanted to try maven-cli-plugin, but now, i will try Maven Shell, hoping i will increase a few my build time.

26 03 2010
uberVU - social comments

Social comments and analytics for this post…

This post was mentioned on Twitter by jvanzyl: Really nice intro to the Maven Shell: http://bit.ly/8WZiWn

26 03 2010
alexx

Eric

Think you could step back for those who are still stuck in the Cruise world and write on the significant differences between the Cruise and the Maven worlds?

This all sounds fantastic to me, but how can I pitch this in the face of inertia? i.e. “what we have now works well enough” (It doesn’t) I’m considering it because the company is at a tipping point and is heading into a great time for change…

Thanks :D

Alexx

14 04 2010
Macon

Alexx,

Cruisecontrol and Maven are really two separate (but potentially complimentary) tools. Cruisecontrol offers scheduling an execution of “processes” (whether those processes represent traditional commandline scripts, ant builds, or other things). Maven is a dependency management and build system. Using “convention over configuration” you can very easily define project dependencies, build process and build artifact management.

So the two tools can work together. You can use Cruisecontrol to schedule and execute Maven builds (although, in my opinion Cruisecontrol offers significantly better support for Ant than Maven). If you’re looking for alternatives to Cruisecontrol I would HIGHLY recommend Hudson ( http://hudson-ci.org/ ) which takes literally minutes to download an learn, and is extremely easy to setup. It supports all the things that Cruisecontrol does and much more.

26 03 2010
Sonatype Blog » Introduction to Maven Shell

[...] the full article here.  And to get started, download the latest release of Maven Shell 0.10. [...]

26 03 2010
Maven Shell Features « Tight Lines and Tight Deadlines

[...] Shell Features 26 03 2010 In my previous blog, I gave a brief Introduction to Maven Shell and what to expect from the environment. I really like what Maven Shell has to offer so I wanted to [...]

26 03 2010
Carsten Schlipf

Sounds gret… have to try it.

But why do I need to download it? After all this is maven. Why not a simple

mvn shell:start

or something like that?

26 03 2010
ericmiles

Good question, probably better for one of the developers to respond. Hopefully they’ve seen this post and will provide some feedback.

26 03 2010
Jason Dillon

The short answer is… maybe one day ;-)

26 03 2010
James Lorenzen

I’ve confirmed mvnsh works with maven 2 projects.

26 03 2010
ericmiles

As I have James. I’ve linked your blog from the bottom of mine as yours is what provided the impetus to dive in and take a look at Maven Shell. Thanks.

27 03 2010
Bernd Adamowicz

Sounds like the mvnsh could also increase the speed of builds using a CI system like Hudson. Does anyone have already experiences with this?

Bernd

27 03 2010
karussell

Really nice! speed improvements of ~40%! and it works for my multi-mvn2-project too.

Two questions: how to report bugs? I cannot do this via the provided jira (can only view issues)!?

1. mvnsh prints incorrect encoding to bash console e.g. if using german umlaute
2. delete button is mapped to backspace button. so pressing ‘del’ will result in char removed at the left of the cursor

27 03 2010
Jason Dillon

Bug reports should go to JIRA:

https://issues.sonatype.org/browse/MVNSH

You will need to sign up for an account first before you can submit new issues.

27 03 2010
marco.godin

is there a way to execute system shell command like ps ?
regards
Marc

27 03 2010
Jason Dillon

There are a bunch of commands which were not included into the mvnsh distribution, exec, cat, grep and script are some that exist already (which users have asked for) but were not included. We’ll be adding those into the next release by popular demand.

28 03 2010
marco.godin

Great !
i love it !

27 03 2010
marco.godin

also a killer feature will be to add custom user command via a groovy/jython… script :)

12 10 2010
daniel

Hi,

I keep getting out of memory errors when building within maven shell. It seems to ignore MAVEN_OPTS.
Does anyone have any idea how to increase the memory available for maven inside maven shell?

Thanks,
Daniel

26 11 2010
Peter Liljenberg

The mvnsh script starts java with the following line:
exec “$JAVACMD” $JAVA_OPTS -jar “$BOOTJAR” $SHELL_OPTS $COMMAND $QUOTED_ARGS

So, setting JAVA_OPTS with memory options should do the trick, for example:
export JAVA_OPTS=”-Xmx1024m -XX:MaxPermSize=512m”

23 12 2011
sagaofsilence

I tried parallel build with Maven shell using mvn -T 4 clean package
(Parallel build: https://cwiki.apache.org/MAVEN/parallel-builds-in-maven-3.html)

But I got error
org.sonatype.gshell.util.cli2.ProcessingException: “-T” is not a valid option

Can we perform parallel build using Maven shell?

29 07 2013
main page

Hey there! I could have sworn I’ve been to this site before but after reading through some of the post I realized it’s new to me.
Anyhow, I’m definitely delighted I found it and I’ll be book-marking and checking back
frequently!

31 07 2013
Jude

It’s going to be ending of mine day, but before ending I am reading this great paragraph to increase my experience.

31 07 2013

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: