|
GettingStartedPart5
Getting started, part five - building and deploying
Building and DeployingOne thing that you may have noticed in this getting started series is that, apart from a few scripts in part one, we haven't had to leave the safety and comfort of Eclipse to perform any of our development tasks. This is great, becausing leaving the IDE slows you down, but there comes a time when you want to make your application available to real some real users. For this, you will need to deploy your application outside of your IDE. Which of course means, you will need to build and deploy your application. Impala comes with some built-in support for build automation. Controversially to some perhaps, the build support is based on ANT. ANT is not the sexiest of tools, but it works, it's easy to use, and if you careful about the way you set up your build scripts, you can even write build scripts which are maintainable and well factored. Build setupIf you're happy to live without Impala's build support, you can simply add the Impala jars into your project's jar repository and forget about any of the other files that come with the Impala distribution. In order to use the Impala build system, you will need to download the Impala distribution. The current snapshot can be found at here. As we recall from part one, you will need to download and unzip this distribution, and set your IMPALA_HOME environment variable to point to the unzipped contents folder. Getting library dependenciesGetting third party dependenciesA typically problematic aspect of new project setup is obtaining third party libraries. Impala has a simple but effective approach this problem, which takes advantage of the existence of Maven repositories. Obtaining third party dependencies is a three step process:
main from commons-logging:commons-logging:1.1 main from log4j:log4j:1.2.13 main from org.springframework:spring:2.5.5 main from cglib:cglib-nodep:2.1_3 test from junit:junit:3.8.1 test from org.easymock:easymock:2.2 test from org.easymock:easymockclassextension:2.2 The dependencies.txt in the web project contains the following entries: web from org.springframework:spring-webmvc:2.5.5 web from servletapi:servletapi:2.4 source = "false" web from jspapi:jsp-api:2.0 source = "false" jetty from org.mortbay.jetty:jetty:6.1.1 jetty from org.mortbay.jetty:jetty-util:6.1.1 jetty from tomcat:jasper-runtime:5.5.15 source = "false" jetty from tomcat:jasper-compiler:5.5.15 source = "false" jetty from tomcat:jasper-compiler-jdt:5.5.15 source = "false" jetty from xerces:xercesImpl:2.8.1 jetty from commons-el:commons-el:1.0 Consider the entry main from commons-logging:commons-logging:1.1 This is shorthand for saying that I want the Maven repository jar file with organisation id commons-logging, artifact id commons-logging and version number 1.1 to be downloaded and placed into the workspace's repository folder main. Note that our workspace repository in found in the project repository, with main a folder relative to this location. The ability to specify the download location in this way makes it easy to apply rules to include or exclude certain jars from ending up in built artifacts, such as war files. For example, the EasyMock dependencies are clearly present for testing, so there would be no point bundling these into a war file. Similarly, the Jetty dependencies are clearly not required in a war file. The whole point of a war file is that it can be simply dropped into a web container, so it wouldn't make much sense including Jetty server jars in such an artifact. Getting Impala dependenciesIf you've gone to the trouble of downloading the Impala distribution and setting up your IMPALA_HOME environment variable, it wouldn't be very helpful having to go onto the internet to download Impala jars. The quick start application features a simple command to retrieve Impala jars, and place them in the main directory of your workspace's repository: ant fetch Main project build fileLet's take a look at the main project build file which you get with the generated quickstart application: <?xml version="1.0"?>
<project name="Build build" basedir=".">
<property environment="env"/>
<property name = "workspace.root" location = ".."/>
<property name = "impala.home" location = "${env.IMPALA_HOME}"/>
<echo>Project using workspace.root: ${workspace.root}</echo>
<echo>Project using impala home: ${impala.home}</echo>
<property file = "build.properties"/>
<property file = "web.properties"/>
<import file = "${impala.home}/project-build.xml"/>
<import file = "${impala.home}/shared-build.xml"/>
<import file = "${impala.home}/shared-web-build.xml"/>
<import file = "${impala.home}/shared-tomcat-build.xml"/>
<import file = "${impala.home}/download-build.xml"/>
<import file = "${impala.home}/repository-build.xml"/>
<import file = "${impala.home}/execution-build.xml"/>
<target name = "get" depends = "shared:get" description="Gets project dependencies as in dependencies.txt"/>
<target name = "fetch" depends = "repository:fetch-impala" description="Fetches Impala libraries"/>
<target name = "clean" depends = "shared:clean" description="Cleans all projects"/>
<target name = "dist" depends = "shared:all-no-test" description="Builds jars for projects, and copies to repository's dist directory"/>
<target name = "test" depends = "shared:test" description="Runs tests"/>
<target name = "jetty" depends = "execution:jetty" description="Runs Jetty in ANT"/>
<target name = "war" depends = "shared-web:war" description="Do war file build"/>
<target name = "tomcat" depends = "shared-tomcat:copy" description="Deploy war to Tomcat"/>
</project>As you can see, there is not much to it. Most of the entries are to define environment properties and to import helper build scripts from the Impala home directory. There are also a few convenience targets towards the end of the script. In addition, there are two property files which locally define properties used for the build. Lets look at build.properties first: base.repository.urls=file://${user.home}/.m2/repository,http://ibiblio.org/pub/packages/maven2/
project.name=main
repository.dir=${workspace.root}/repository
project.list=main,module1,web
web.project.list=web
project.version=1.0
#uncomment to run in debug mode
#run.jvm.args=-Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=y
#test.jvm.args=-Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=y
test.jvm.args=These properties are useful, because they control aspects of the build. For example:
The second locally defined properties file is web.properties, shown below: webapp.project.name=web
context.path=/${webapp.project.name}
context.dir=../${webapp.project.name}/context
webapp.port=8080
tomcat.home=${env.TOMCAT_HOME}/webappsA recommended approach is to set the TOMCAT_HOME environment variable to your Tomcat installation directory. On Unix based systems you can do so using the command: export TOMCAT_HOME=/mypathtoTomcat/ Building a war, and deploying to TomcatThe main build file defines a bunch of convenience methods. To build a war file using the generated quick start application: ant clean dist war If the Tomcat home directory is correctly specified, we can deploy directly to Tomcat using the following command: ant tomcat Place a command prompt at the Tomcat bin directory, and start Tomcat. cd ${TOMCAT_HOME}/bin
./catalina.sh runThis will start Tomcat. Once again, point the browser to http://localhost:8080/web/message.htm and we'll end seeing the same result as in part three War project structureWe can end the discussion with a brief look at the structure of the exploded war file in the Tomcat webapps/web application directory. Apart from the test.jsp, all the deployed files are contained in WEB-INF. WEB-INF/classes:
impala-embedded.properties
impala.properties
log4j.properties
moduledefinitions.xml
WEB-INF/lib:
cglib-nodep-2.1_3.jar
easymockclassextension-2.2.jar
impala-interactive-1.0-SNAPSHOT.jar
junit-3.8.1.jar
servletapi-2.4.jar
startjetty.jar
commons-logging-1.1.jar
impala-build-1.0-SNAPSHOT.jar
impala-web-1.0-SNAPSHOT.jar
launcher.jar
spring-2.5.5.jar
easymock-2.2.jar
impala-core-1.0-SNAPSHOT.jar
jsp-api-2.0.jar
log4j-1.2.13.jar
spring-webmvc-2.5.5.jar
WEB-INF/modules:
main-1.0.jar
module1-1.0.jar
web-1.0.jar WEB-INF/classes contains the files from the web project's webconfig directory. Note that these files are all found in the web application class path. WEB-INF/lib contains all the third party jars, including the Impala jar files. Finally, the modules are contained in jar files in WEB-INF modules. The reason for this location is that the module jars need to be loaded using a different class loader from the third party jars, and therefore should not be on the web application's class path. Jetty DeploymentThe advantage of using a Jetty deployment is that you can easily "ship" the Jetty container with your application as a single zip file. This makes it possible to literally unzip and run in the target environment, without requiring a web container (e.g. Tomcat) to be separately installed. To build to Jetty, follow these instructions: From the main project: ant clean dist From the web project: ant jetty:zip This results in a zip file to be copied to the location ../deploy/webprojecname-jetty.zip. You can then unzip this file. CD to the folder containing startjetty.sh and startjetty.bat. Run the relevant script. For example. runjetty 8080 web starts the Jetty web container on port 8080. You can then browse to the running application on: http://localhost:8080/web/message.htm There are some useful configuration options which can be applied, for example, to set system properties and to tweak Impala startup options, but this this basic configuration will get you going without pain. |
Sign in to add a comment
Hi, thanks for this very interesting tool. The tomcat deploy is helpful but it is also compelling to me to deploy a component which only rely on the jetty example. I see there is a jetty-build ant file - is that part of the recipe? What is the magic to make Jetty the deployed servlet container target?
Yes, it is possible to deploy to Jetty, using the jetty-build.xml. I don't have any precanned instructions available at this point, but essentially the Jetty deployment has the following features: 1) the jetty jars are included as part of the distribution, so you don't need to install it, 2) the basic war structure is deployed, but the war archive is not created - instead, an expanded war structure is used. I will make a note to updated this page or create another with Jetty instructions.
Updated Jetty build following previous comments.