Thanks for sharing this info Brian. I've been grappling with this very issue myself, and your solution sounds pretty good. I think this is an area that maven needs to address - ie: how to maintain multiple builds that have different maven/plugin version requirements, or how to build a previous version of a project that depended on an older version of maven/plugin. Perhaps the POM needs to explicitly specify its plugin dependencies and maven version?

Cheers,
Charles


Brian Murray wrote:

Apologies in advance for the length of this post, hope you find it useful.

In our J2EE development environment we were really struggling with how to deal with multiple versions of Maven and of the Maven plug-ins. If a project was developed with one version of Maven and one set of plug-ins, how could you work from a known base if you came back to the project 6 months or a year later?

We came up with the following approach which has proven very effective for us. Since we have gained so much from using Maven, I thought I'd take a moment to share what we came up with, hoping that it might help others who work in a environment with a large number of projects.

A disclaimer:
- We're not rocket scientists, so there are probably flaws in what we've done. Be gentle, this process works for us.


Our approach:
- Create a central repository where we store all the different "versions" of Maven. For us, a "version" of Maven is a Maven release (e.g. 1.0-rc1) and the set of plug-ins that go with it. If Maven comes out with a new release we create a new "version". If a non-backward compatible version of a plug-in is released that we choose to adopt then we create a new "version". If a backward compatible update to a plug-in is released then we apply that to the current "version".
- The repository is basically one directory tree per "version" where each version directory contains what you would expect to see in MAVEN_HOME (bin, plugins, etc.). The repository is in a location that is accessible from both Windows and Unix/Linux environment. Users can set a MAVEN_BASE environment variable to point to the repository, but we have defaults in the 'runmaven' scripts (see below).
- In each Maven project there is a 'maven.version' file which contains one line with the name of the Maven "version". This string is the name of the version directory in the repository.
- We have created a sh script and a BAT script called 'runmaven' that takes care of running Maven in our process. It looks at the 'maven.version' file and sets MAVEN_HOME to point to that version directory.
- Within MAVEN_LOCAL we have separate plugin caches for each "version". That way if you're working on projects that require different versions, you don't have to worry about clashes. 'runmaven' takes care of setting 'maven.plugin.unpacked.dir' for you.
- When we update a plugin in an existing "version" we touch a 'plugins.date' file in the version directory. 'runmaven' checks the timestamp of this file against the local plugin cache. If 'plugins.date' is more recent, then we delete the local plugin cache so the plugins will be downloaded from the repository.


I think that about sums it up. For your reading pleasure, here are the scripts. Again, we don't claim to be scripting experts so don't be surprised if its seems a little primitive.

---------------------------------- Start runmaven sh script --------------------
#!/bin/sh
################################################################################


#
# Name: runmaven
#
# Date: 9/30/2003
#
# Version: Original KJM 9/30/2003
# 1.1 (nbd/acr) -
# ** Change to allow MAVEN_BASE to be set as env variable
# instead of always using "/mavenbase".
# ** Changes to allow plugins to be downloaded
# dynamically when the plugins have changed on the server.
# ** Changes to run in XP environment under cygwin.
# ** Changes to use latest maven version if maven.version does
# not exist.
# 1.2 (nbd) - Fixed some bugs that were discovered on the HP systems
# ** Changed the search for the latest maven version to use find
# instead of ls since the "--colors=never" option is not
# supported on the HP systems.
# ** Quoted variables in the test expressions. HP didn't like
# them unless they were quoted.
#
#
# Descr: This script will set up the MAVEN_HOME environment variable
# for each application, and subsequently call the application
# specific version of maven.
#
# Assumptions: CVS Module already pulled down, process run in the root
# directory of the CVS module.
#
################################################################################



################################################################################


# Usage
################################################################################


Usage ()
{
echo ""
echo ""
echo " Usage: runmaven MAVEN_OPTIONS"
echo ""
echo " Assumptions: There is a local working copy of the CVS Module"
echo " This process runs in the root directory of that CVS module."
echo ""
exit 1;
}


################################################################################

# Main
################################################################################



### # Parse the command line parameters ### if [ "x$*" = "x" ]; then Usage fi


### # Validate that the maven base directory is valid ### if [ -z "${MAVEN_BASE}" ]; then MAVEN_BASE="/mavenbase" fi

if [ ! -d "${MAVEN_BASE}" ]; then
  echo "Critical Error!!!"
  echo "The Maven installations indicated by MAVEN_BASE [${MAVEN_BASE}]"
  echo "does not exist."
   exit 12
fi


###
# Validate that the maven.version file exists.
###
MAVEN_VERSION_FILE="maven.version"
if [ ! -f "${MAVEN_VERSION_FILE}" ]; then
# Since they don't have a maven.version file we'll figure what the latest version is
MAVEN_VERSION=`find ${MAVEN_BASE} -name "mis-maven*" -follow -prune | sort | tail -1 | xargs -i basename {}`
echo
echo The file "${MAVEN_VERSION_FILE}" does not exist.
echo The latest maven version is [${MAVEN_VERSION}].
echo
echo "Press [Enter] to continue with version ${MAVEN_VERSION}"
echo " [C] to create a ${MAVEN_VERSION_FILE} file and continue"
echo
echo "Or press any other key to quit"
read answer


# if they didn't choose one of the continue options then we're quitting
if [ "${answer}" != "C" -a "${answer}" != "c" -a "${answer}" != "" ]; then
echo "Quiting..."
exit 15
fi


  # create a maven.version file if that option was selected
  if [ -n "${answer}" ]; then
     echo "Creating file '${MAVEN_VERSION_FILE}'..."
     echo ${MAVEN_VERSION} > ${MAVEN_VERSION_FILE}
  fi
  echo
else
   MAVEN_VERSION=`head -n1 ${MAVEN_VERSION_FILE}`
fi

###
# Validate that the requested version of maven exists.
###
MAVEN_HOME="${MAVEN_BASE}/${MAVEN_VERSION}"
if [ ! -d "${MAVEN_HOME}" ]; then
echo "Critical Error!!!"
echo "The maven version specified [${MAVEN_VERSION}] is not installed under"
echo "the maven base directory [${MAVEN_BASE}]."
exit 11
else
export MAVEN_HOME
fi


echo "MAVEN_HOME = ${MAVEN_HOME}"

###
# OS specific support so that script will run on cygwin and linux
###
cygwin=false;
case "`uname`" in
 CYGWIN*) cygwin=true ;;
esac

###
# Determine where the repo and local plugin dir should be
###
if [ -z "${MAVEN_HOME_LOCAL}" ]; then
if [ "${cygwin}" = "true" ]; then
MAVEN_HOME_LOCAL=`cygpath -m c:/maven-local`
else MAVEN_HOME_LOCAL="${HOME}/.maven"
fi fi
###
# Validate the MAVEN_HOME_LOCAL dir to ensure it is a valid path for this platform
###
VALID_PATH=`pathchk "${MAVEN_HOME_LOCAL}"`
if [ $? != 0 ]; then
echo "Critical error!!!"
echo "MAVEN_HOME_LOCAL directory [${MAVEN_HOME_LOCAL}]contains invalid characters."
exit 1
fi


MAVEN_LOCAL_PLUGINS="${MAVEN_HOME_LOCAL}/.${MAVEN_VERSION}/plugins"

###
# Delete local plugins if server has newer ones
###
if [ -d "${MAVEN_LOCAL_PLUGINS}" ]; then
if [ "${MAVEN_HOME}/plugins.date" -nt "${MAVEN_LOCAL_PLUGINS}/plugins.cache" ]; then
echo "Updating local plugins. Please wait..."
rm -rf ${MAVEN_LOCAL_PLUGINS}
else
echo "Local plugins are up to date."
fi
else
echo "Updating local plugins. Please wait..."
fi


###
# Run the application specific version of maven.
###
$MAVEN_HOME/bin/maven -Dmaven.home.local=${MAVEN_HOME_LOCAL} -Dmaven.plugin.unpacked.dir=${MAVEN_LOCAL_PLUGINS} $*
---------------------------------- End runmaven sh script --------------------


---------------------------------- Start runmaven.bat script --------------------
@REM ---------------------------------------------------------------------------


@REM
@REM Name: runmaven.bat
@REM
@REM Date: 05/12/2004
@REM
@REM Version: Original ndb/acr/bm
@REM
@REM Descr: This script will set up the MAVEN_HOME environment variable
@REM for each application, and subsequently call the application
@REM specific version of maven.
@REM
@REM Assumptions: CVS Module already pulled down, process run in the root
@REM directory of the CVS module.
@REM
@REM ---------------------------------------------------------------------------


@echo off
setlocal

if "%MAVEN_BASE%" == "" set MAVEN_BASE=\\central\maven
if not exist %MAVEN_BASE% (
  echo Critical Error!!!
  echo The Maven installations indicated by MAVEN_BASE [%MAVEN_BASE%]
  echo does not exist.
  goto finish
)

set MAVEN_VERSION_FILE=maven.version

if not exist %MAVEN_VERSION_FILE% (
call :GET_LATEST_MAVEN_VERSION
) else (
rem Figure out which version of maven to use by reading the maven version file
for /F "" %%V in (%MAVEN_VERSION_FILE%) do set MAVEN_VERSION=%%V
)


@REM if they selected quit when prompted we'll quit now
if "%MAVEN_VERSION%" == "quit" (
  echo Quiting...
  goto finish
)

rem Check to see if the version of maven specified exists
set MAVEN_HOME=%MAVEN_BASE%\%MAVEN_VERSION%
if not exist %MAVEN_HOME% (
echo Critical Error!!!
echo The maven version specified [%MAVEN_VERSION%] is not installed under
echo the maven base directory [%MAVEN_BASE%].
goto finish
)


rem Default maven local directory if not already specified
if "%MAVEN_HOME_LOCAL%" == "" set MAVEN_HOME_LOCAL="%SystemDrive%\maven-local"


set MAVEN_LOCAL_PLUGINS=%MAVEN_HOME_LOCAL%\.%MAVEN_VERSION%\plugins

set PLUGIN_DISTR_FILE=%MAVEN_HOME%\plugins.date
set PLUGIN_CACHE_FILE=%MAVEN_LOCAL_PLUGINS%\plugins.cache

if not exist %PLUGIN_DISTR_FILE% (
  echo Critical error!!!
  echo Plugins distribution file [%PLUGIN_DISTR_FILE%]
  echo does not exist.
  goto finish
)

rem If they don't have any plugins for this maven version then proceed.
rem The plugins will be installed when maven runs.
if not exist %PLUGIN_CACHE_FILE% (
  echo.
  echo Updating local plugins. Please wait...
  echo.
  goto callMaven
)

rem Compare the local plugins timestamp with the plugins under MAVEN_HOME.
rem If MAVEN_HOME plugins are newer then delete the local plugins to force a
rem new plugin install.
call :GET_FILE_TIMESTAMP %PLUGIN_DISTR_FILE% W
set PluginDistrParsedStamp=%r_fileTimeStamp%


call :GET_FILE_TIMESTAMP %PLUGIN_CACHE_FILE% C
set  PluginCacheParsedStamp=%r_fileTimeStamp%

if %PluginCacheParsedStamp% LSS %PluginDistrParsedStamp% (
  echo.
  echo Updating local plugins. Please wait...
  echo.
  rmdir /s /q %MAVEN_LOCAL_PLUGINS%
) else (
  echo.
  echo Local plugins are up to date.
  echo.
)

:callMaven
set CMD_LINE_ARGS=%*
echo Using %MAVEN_HOME%...
echo Issuing Command : %MAVEN_HOME%\bin\maven.bat -Dmaven.home.local=%MAVEN_HOME_LOCAL% -Dmaven.plugin.unpacked.dir=%MAVEN_LOCAL_PLUGINS% %CMD_LINE_ARGS%
call %MAVEN_HOME%\bin\maven.bat -Dmaven.home.local=%MAVEN_HOME_LOCAL% -Dmaven.plugin.unpacked.dir=%MAVEN_LOCAL_PLUGINS% %CMD_LINE_ARGS%


:finish
ENDLOCAL
exit /B 1

rem /////////////////////////////////////////////////////////////////////////
rem GET_FILE_TIMESTAMP
rem Given a file name, return the file's timestamp in
rem yyyyMMddaahh:mm format
rem
rem Arguments:
rem %1 - filename to return timestamp for
rem %2 - Which timestamp to return (A|C|W)
rem A = Accessed
rem C = Created
rem W = Modified
rem rem Returns
rem r_fileTimeStamp - timestamp in 'yyyyMMddaahh:mm'
rem
:GET_FILE_TIMESTAMP
setlocal
for /F "tokens=1-3" %%A in ('dir /T%2 %1^|find "%~n1"') do call :PARSE_TIMESTAMP %%A %%B %%C
endlocal & set r_fileTimeStamp=%r_parsedStamp%
goto :eof



rem /////////////////////////////////////////////////////////////////////////
rem PARSE_TIMESTAMP procedure
rem Parse a timestamp of the form 'MM/dd/yyyy hh:mm aa'
rem into the form 'yyyyMMddaahh:mm'
rem
rem Arguments:
rem %1 - timestamp in 'MM/dd/yyyy hh:mm aa' form
rem
rem Returns
rem r_parsedStamp - timestamp in 'yyyyMMddaahh:mm'
rem
:PARSE_TIMESTAMP
setlocal
rem Use the FOR /F command to parse the date part into month day and year
rem then reorder the date fragments and append the time and am/pm indicator
for /F "delims=/ tokens=1-3" %%A in ('echo %1') do set fmt_date=%%C%%A%%B%3%2
endlocal & set r_parsedStamp=%fmt_date%
goto :eof


:GET_LATEST_MAVEN_VERSION
setlocal
for /f %%a in ('dir /o:n/a:d /b %MAVEN_BASE%\mis-maven*') do set maven_version_txt=%%a
echo.
echo The file "%MAVEN_VERSION_FILE%" does not exist.
echo The latest maven version is [%maven_version_txt%].
echo.
echo Press [Enter] to continue with version %maven_version_txt%
echo [C] to create a %MAVEN_VERSION_FILE% file and continue
echo.
echo Or press any other key to quit set /p answer=


  if NOT "%answer%" == "" (
     set answer=%answer:~0,1%
     if /I "%answer%" == "C" (
        echo Creating file %MAVEN_VERSION_FILE% ...
        echo %maven_version_txt% > %MAVEN_VERSION_FILE%
     ) else (
        set maven_version_txt=quit
     )
  )
  echo.

endlocal & set MAVEN_VERSION=%maven_version_txt%
goto :eof
---------------------------------- End runmaven.bat script --------------------


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to