Jump starting projects with AppFuse
I have been trying for quite some time to get a project started and I always stumbled over some small things. Sometimes it’s a dbUnit test not running through, sometimes it’s the maven jetty plugin which does not want to start at all. All of these problems are related not with the development activity, instead they are due to some problems setting up the environment. So wouldn’t it be nice if there was a tool that preconfigured all of these small things just to work fine?
Well there is: enter the magic world of AppFuse.
AppFuse comes with some skeletons configure for you to simply use and then extend however you want to. In this little tutorial I’m going to show how to setup a Spring-MVC application with Hibernate as a backend.
From the list of available archetypes we select the Spring MVC Basic archetype since this is a small project and I really like Spring:
mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-spring -DremoteRepositories=http://static.appfuse.org/releases
-DarchetypeVersion=2.0.2 -DgroupId=net.snyke -DartifactId=HelloWorld
This will create the basic folder structure for our project.
mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-spring -DremoteRepositories=http://static.appfuse.org/releases -DarchetypeVersion=2.0.2 -DgroupId=net.snyke -DartifactId=HelloWorld [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'archetype'. [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Default Project [INFO] task-segment: [archetype:create] (aggregator-style) [INFO] ------------------------------------------------------------------------ Downloading: http://repo1.maven.org/maven2/net/snyke/wagon-http-shared/1.0-beta-2/wagon-http-shared-1.0-beta-2.pom Downloading: http://repo1.maven.org/maven2/net/snyke/wagon-http-shared/1.0-beta-2/wagon-http-shared-1.0-beta-2.pom [INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'. [INFO] Setting property: velocimacro.messages.on => 'false'. [INFO] Setting property: resource.loader => 'classpath'. [INFO] Setting property: resource.manager.logwhenfound => 'false'. [INFO] [archetype:create] [WARNING] This goal is deprecated. Please use mvn archetype:generate instead [INFO] Defaulting package to group ID: net.snyke [INFO] We are using command line specified remote repositories: http://static.appfuse.org/releases [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating OldArchetype: appfuse-basic-spring:2.0.2 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: net.snyke [INFO] Parameter: packageName, Value: net.snyke [INFO] Parameter: package, Value: net.snyke [INFO] Parameter: artifactId, Value: HelloWorld [INFO] Parameter: basedir, Value: /home/cxd/Desktop [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] ********************* End of debug info from resources from generated POM *********************** [INFO] OldArchetype created in dir: /home/cxd/Desktop/HelloWorld [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 17 seconds [INFO] Finished at: Tue Sep 16 02:16:51 CEST 2008 [INFO] Final Memory: 8M/14M [INFO] ------------------------------------------------------------------------
If we now enter the folder we wont see much in there, but we will be able to already run the basic AppFuse application:
mvn jetty:run-war
will start the application, and after a while we get a message that says that the Jetty Server has been started. After this open a browser and point it to http://localhost:8080 and you’ll see the running application:
Right now the jetty server is running the application from the war-file. While this is pretty nice, we want the application to reload changed resources on the fly, so we don’t have to rebuild all the time. This can be achieved by using war:inplace, like this:
$ mvn war:inplace [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'war'. [INFO] ------------------------------------------------------------------------ [INFO] Building AppFuse Spring MVC Application [INFO] task-segment: [war:inplace] [INFO] ------------------------------------------------------------------------ [INFO] [war:inplace] [INFO] Generating webapp in source directory... /home/cxd/Desktop/HelloWorld/src/main/webapp [INFO] Exploding webapp... [INFO] Assembling webapp HelloWorld in /home/cxd/Desktop/HelloWorld/src/main/webapp [INFO] Overlaying 2 war(s). [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 14 seconds [INFO] Finished at: Tue Sep 16 02:24:00 CEST 2008 [INFO] Final Memory: 8M/15M [INFO] ------------------------------------------------------------------------
So by now we can add new screens and work with the existing DAOs, but we still haven’t full access to the source. To get the full sources we have to execute one more command:
$ mvn appfuse:full-source [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'appfuse'. [INFO] ------------------------------------------------------------------------ [INFO] Building AppFuse Spring MVC Application [INFO] task-segment: [appfuse:full-source] [INFO] ------------------------------------------------------------------------ [INFO] [appfuse:full-source] [INFO] [AppFuse] Installing source from data-common module... [INFO] [AppFuse] Installing source from hibernate module... [INFO] [AppFuse] Installing source from service module... [INFO] [AppFuse] Installing source from web-common module... [INFO] [AppFuse] Installing source from spring module... [INFO] [AppFuse] Source successfully exported, modifying pom.xml... [INFO] [AppFuse] Removing maven-warpath-plugin... [INFO] [AppFuse] Adding dependencies from root module... [INFO] [AppFuse] Adding dependencies from data module... [INFO] [AppFuse] Adding dependencies from data-common module... [INFO] [AppFuse] Adding dependencies from hibernate module... [INFO] [AppFuse] Adding dependencies from service module... [INFO] [AppFuse] Adding dependencies from web module... [INFO] [AppFuse] Adding dependencies from web-common module... [INFO] [AppFuse] Adding dependencies from spring module... [INFO] [AppFuse] Removing maven-warpath-plugin... [INFO] [AppFuse] Updated dependencies in pom.xml... [INFO] [AppFuse] Renaming packages to 'net.snyke'... [info] [AppFuse] Refactored all 'org.appfuse' packages and paths to 'net.snyke'. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1 minute 17 seconds [INFO] Finished at: Tue Sep 16 02:36:40 CEST 2008 [INFO] Final Memory: 6M/23M [INFO] ------------------------------------------------------------------------
Having access to the full sources you now can edit everything, just follow the lead of the AppFuse examples. AppFuse tries to be as generic as possible and implements some great patterns, don’t be afraid to copy some of them.
A last tip before I let you go: using the offline switch (-o) will speed up maven by a factor 2-3 depending on how fast the repositories are
