philly spring ug roo overview
DESCRIPTION
A presentation I gave two weeks ago at the Philadelphia Area Spring User Group on Spring Roo.TRANSCRIPT
SpringSource roo
A SpringSource rapid application development framework
Philadelphia Spring User Group07-08-2009Ken Rimple
Chariot Solutions1Friday, July 10, 2009
What is Roo?Rapid application development platform for Spring and Java
Domain-centric design of database entities
Auto-scaffolding of UI elements
Builds a full stack Spring web application
Target build process managed by Maven
An answer to non-Java and non-Spring convention-over-configuration frameworks
2Friday, July 10, 2009
Up Front... Key Points
Roo is a moving target
Not all features are fully implemented
Early days, but SpringSource appears committed to building this framework for Spring Java developers
3Friday, July 10, 2009
Roo Development Process
Roo has a command-line shell (ala Grails/Rails)
Generates a project with a maven build
Round-trips the code to keep the project and developer tools synchronized
Uses Aspects to wire features (.aj files)
Weaves aspects into associated class files
4Friday, July 10, 2009
The TechnologyAspectJ Inter-Type Declarations
Uses the AspectJ Compiler from Maven/Eclipse
Adds code at compile-time to the classes marked by specific roo annotations
Roo command shell
Generates and maintains a proper build environment
Dynamically generates .aj files and scaffolds web UI
5Friday, July 10, 2009
Installing roo
Download roo from SpringSource
Unpack tar in favorite location
Alias roo to ${roo-home}/bin/roo.sh or put the roo directory in your path
Do NOT set a ROO_HOME
6Friday, July 10, 2009
Creating a roo project
Create a directory
Enter roo, and issue the create-project command (tab completion helps here)
flibbity-floo:roo-demo krimple$ roo ____ ____ ____ / __ \/ __ \/ __ \ / /_/ / / / / / / / / _, _/ /_/ / /_/ / /_/ |_|\____/\____/ 1.0.0.M1 [rev 64]
Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.roo> create project -topLevelPackage com.chariot.demo.roodemoCreated /Users/krimple/svn-projects/...roodemo/pom.xmlCreated SRC_MAIN_JAVACreated SRC_MAIN_RESOURCESCreated SRC_TEST_JAVACreated SRC_TEST_RESOURCESCreated SRC_MAIN_WEBAPPCreated SRC_MAIN_RESOURCES/applicationContext.xmlCreated SRC_MAIN_WEBAPP/WEB-INFCreated SRC_MAIN_WEBAPP/WEB-INF/roodemo-servlet.xmlCreated SRC_MAIN_WEBAPP/WEB-INF/web.xmlCreated SRC_MAIN_WEBAPP/WEB-INF/jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/index.jspCreated SRC_MAIN_WEBAPP/WEB-INF/urlrewrite.xml
7Friday, July 10, 2009
Installing JPA
Use install jpa command
You can pick Open JPA, Hibernate, EclipseLink
You can pick a driver, then set settings in
roo> install jpa -provider HIBERNATE -database MYSQL Created SRC_MAIN_RESOURCES/META-INFCreated SRC_MAIN_RESOURCES/META-INF/persistence.xmlCreated SRC_MAIN_RESOURCES/database.propertiesplease enter your database details in src/main/resources/database.propertiesManaged SRC_MAIN_RESOURCES/applicationContext.xmlManaged ROOT/pom.xml
8Friday, July 10, 2009
Adding a Persistent JPA Entity
Set up a domain class with ‘new persistent class’ command (places in base package by default)
Then add fields using add field (remembers the last jpa class added)
roo> new persistent class jpa -name ~.ConferenceCreated SRC_MAIN_JAVA/com/chariot/roodemoCreated SRC_MAIN_JAVA/com/chariot/roodemo/Conference.javaCreated SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_Plural.ajCreated SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_Entity.ajCreated SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_ToString.ajCreated SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_Configurable.aj
9Friday, July 10, 2009
What Got Created?Roo generates the following files:
Conference.java - the file you edit, containing Roo annotations and your properties
Conference_Roo_Configurable.aj - adds @Configurable to the entity
Conference_Roo_Entity.aj - Adds all JPA persistence methods, an id, and a version
Conference_Roo_JavaBean.aj - Adds getters/setters for all of your private properties
10Friday, July 10, 2009
Setting up JPA fields
You can add fields, relationships, and more. These fields are physically added to the java file, and the support methods are wired automatically.
roo> add field string nameManaged SRC_MAIN_JAVA/com/chariot/roodemo/Conference.javaCreated SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_JavaBean.ajManaged SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_ToString.ajroo> add field string descriptionManaged SRC_MAIN_JAVA/com/chariot/roodemo/Conference.javaManaged SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_JavaBean.ajManaged SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_ToString.ajroo> add field date jpa -type java.util.Date -fieldName created Managed SRC_MAIN_JAVA/com/chariot/roodemo/Conference.javaManaged SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_JavaBean.ajManaged SRC_MAIN_JAVA/com/chariot/roodemo/Conference_Roo_ToString.aj
11Friday, July 10, 2009
Building a Relationshiproo> new persistent class jpa -name ~.domain.Conference
roo> add field string -fieldName conferenceName -notNull -sizeMin 1 -sizeMax 40
roo> add field date jdk -type java.util.Date -notNull -fieldName startDate
roo> add field date jdk -type java.util.Date -notNull -fieldName endDate
roo> new persistent class jpa -name ~.domain.ConferenceSession
roo> add field string -notNull -fieldName title -sizeMax 80
roo> add field reference jpa -fieldName conference -type com.chariot.demo.contrack.domain.Conference
roo> add field set jpa -element ~.domain.ConferenceSession -fieldName session -class com.chariot.demo.contrack.domain.Conference
Conference
ConferenceSession
12Friday, July 10, 2009
Entity ValidationEntities are validated using JSR-303 annotations
@NotNull, @Nullable, @Size, @DecimalMin, @DecimalMax, etc...
Controllers (coming up) generate call to validations using this Bean Validation API call:
javax.validation.Validation. buildDefaultValidatorFactory().getValidator(). validate(conference))
13Friday, July 10, 2009
Bean Validation Framework
JSR-303 is a final draft standard
May be incorporated into JPA 2.0
This is a moving target for persistence...
Note: in Spring Roo
Validation Messages (per the spec) can be customized, and go in src/main/resources/ValidationMessages.properties (and do not get installed in a ResourceBundleMessageSource)...
14Friday, July 10, 2009
Validation ExamplesJSR-303 is a Java EE 6 spec standard...
Spring Roo installs and configures it as part of the classpath and framework
Validation errors appear as errors in the Spring validation framework
@Size(min = 5, max = 30, message = "Please enter a name between {min} and {max} characters.") private String name;
@Size(min = 10, max=2048, message = "{description.required}") private String description;
@Temporal(TemporalType.TIMESTAMP) @Column(insertable=true, updatable=false) @NotNull private Date created;
15Friday, July 10, 2009
Roo and MavenRoo generates and maintains a maven pom.xml
Roo properly adds dependencies (except webflow for now) and configures settings
This is all round-trip; you can keep roo open while developing in SpringSource Tool Suite
Could be a nice way to configure a traditional spring application w/o resorting to Grails or another non-Java framework
16Friday, July 10, 2009
Roo and IDEsRoo generates eclipse natures
ADJT AspectJ nature
Roo core nature (used by STS Roo plugin)
Core Spring nature and SpringBuilder
Configures idea using the maven-idea-plugin
Configures jetty and maven plugins automatically
On each IDE, full sources are downloaded for frameworks like Spring, JPA, etc...
17Friday, July 10, 2009
Configuring loggingNice way to set up logging, adds both a file and console logger (can be modified)
roo> configure logging -level TRACECreated SRC_MAIN_RESOURCES/log4j.propertiesManaged SRC_MAIN_WEBAPP/WEB-INF/web.xml
<context-param><param-name>log4jConfigLocation</param-name><param-value>classpath:log4j.properties</param-value>
</context-param>
#Updated at Tue Jun 09 09:21:45 EDT 2009#Tue Jun 09 09:21:45 EDT 2009log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%nlog4j.rootLogger=TRACE, stdout, Rlog4j.appender.R.File=application.loglog4j.appender.R.MaxFileSize=100KBlog4j.appender.R.layout=org.apache.log4j.PatternLayoutlog4j.appender.R.MaxBackupIndex=1log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%nlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.R=org.apache.log4j.RollingFileAppender
18Friday, July 10, 2009
Generating a ControllerBeginning to sound like (g)rails?
Note: first one generates the includes, header and footer jsps.
roo> new controller automatic -name com.chariot.roodemo.domain.ConferenceControllerCreated SRC_MAIN_JAVA/com/chariot/roodemo/domain/ConferenceController.javaCreated SRC_MAIN_JAVA/com/chariot/roodemo/domain/ConferenceController_Roo_Controller.ajCreated SRC_MAIN_WEBAPP/imagesCreated SRC_MAIN_WEBAPP/images/banner-graphic.pngCreated SRC_MAIN_WEBAPP/images/springsource-logo.pngCreated SRC_MAIN_WEBAPP/images/list.pngCreated SRC_MAIN_WEBAPP/images/show.pngCreated SRC_MAIN_WEBAPP/images/create.pngCreated SRC_MAIN_WEBAPP/images/update.pngCreated SRC_MAIN_WEBAPP/images/delete.pngCreated SRC_MAIN_WEBAPP/stylesCreated SRC_MAIN_WEBAPP/styles/roo.cssCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/header.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/footer.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/includes.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/dataAccessFailure.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/uncaughtException.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/conferenceCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/conference/list.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/conference/show.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/conference/create.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/conference/update.jspCreated SRC_MAIN_WEBAPP/WEB-INF/jsp/menu.jspManaged SRC_MAIN_WEBAPP/WEB-INF/jsp/menu.jsp
19Friday, July 10, 2009
Roo’s aspect-driven scaffold
20Friday, July 10, 2009
What is the scaffold?
An aspect-j aspect
each controller gets its’ own series of Aspects, which can be modified/added to
Separates controller logic from mechanics
21Friday, July 10, 2009
Example Aspect: show
Uses findConference in Conference_Roo_Entity.aj
In ConferenceController_Roo_Controller.aj: @org.springframework.web.bind.annotation.RequestMapping( value = "/conference/{id}", method = org.springframework.web.bind.annotation.RequestMethod.GET) public java.lang.String ConferenceController.show( @org.springframework.web.bind.annotation.PathVariable("id") Long id, org.springframework.ui.ModelMap modelMap) { if (id == null) throw new IllegalArgumentException("An Identifier is required"); modelMap.addAttribute("conference", com.chariot.roodemo.domain.Conference.findConference(id)); return "conference/show"; }
public static com.chariot.roodemo.domain.Conference Conference.findConference(java.lang.Long id) { if (id == null) throw new IllegalArgumentException(
"An identifier is required to retrieve an instance of Conference"); javax.persistence.EntityManager em = new Conference().entityManager; if (em == null) throw new IllegalStateException(
"Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
return em.find(Conference.class, id); }
22Friday, July 10, 2009
Get it working!Run mvn jetty:run or tomcat:run
Hit the webapp url and get a menu of choices
Here’s a typical crud screen, generated for you
23Friday, July 10, 2009
Generated UI Code - ListNote: Does not detect column lengths (ROO-80)
<form:form action="/roodemo/conference" method="POST" modelAttribute="conference"><div id="roo_conference_name"><label for="_name">Name:</label><form:input cssStyle="width:250px" id="_name" maxlength="30" path="name" size="0"/><br/><form:errors cssClass="errors" id="_name" path="name"/><script type="text/javascript">Spring.addDecoration(new Spring.ElementDecoration({elementId : "_name", widgetType : "dijit.form.ValidationTextBox", widgetAttrs : {promptMessage: "Enter Name", invalidMessage: "", required : false}})); </script></div><br/>
<div id="roo_conference_description"><label for="_description">Description:</label><form:input cssStyle="width:250px" id="_description" maxlength="30" path="description" size="0"/><br/><form:errors cssClass="errors" id="_description" path="description"/><script type="text/javascript">Spring.addDecoration(new Spring.ElementDecoration({elementId : "_description", widgetType : "dijit.form.ValidationTextBox", widgetAttrs : {promptMessage: "Enter Description", invalidMessage: "", required : false}})); </script></div><br/><div id="roo_conference_created"><label for="_created">Created:</label><form:input cssStyle="width:250px" id="_created" maxlength="30" path="created" size="0"/><br/><form:errors cssClass="errors" id="_created" path="created"/>
<script type="text/javascript">Spring.addDecoration(new Spring.ElementDecoration({elementId : "_created", widgetType : "dijit.form.ValidationTextBox", widgetAttrs : {promptMessage: "Enter Created", invalidMessage: "", required : false}})); </script><script type="text/javascript">Spring.addDecoration(new Spring.ElementDecoration({elementId : "_created", widgetType : "dijit.form.DateTextBox", widgetAttrs : {datePattern : "MM/dd/yyyy", required : false}})); </script></div><br/><div class="submit" id="roo_conference_submit"><script type="text/javascript">Spring.addDecoration(new Spring.ValidateAllDecoration({elementId:'proceed', event:'onclick'}));</script><input id="proceed" type="submit" value="Save"/></div></form:form>
24Friday, July 10, 2009
How about Security?Just do ‘install security’ and you get Spring Security
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
<http auto-config="true"> <form-login login-processing-url="/static/j_spring_security_check" login-page="/static/login.jsp" authentication-failure-url="/static/login.jsp?login_error=t"/> <logout logout-url="/static/j_spring_security_logout"/> <intercept-url pattern="/admin/**" access="ROLE_ADMIN"/> <intercept-url pattern="/member/**" access="IS_AUTHENTICATED_REMEMBERED" /> <intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/static/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> </http>
<authentication-provider> <!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) --> <password-encoder hash="sha-256"/> <user-service> <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN"/> <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER"/> </user-service> </authentication-provider>
</beans:beans>
25Friday, July 10, 2009
IDE Support
Roo works with SpringSource Tool Suite
AJDT AspectJ editing support is very good
Roo Console available via Right-click if installed
But you have to mvn eclipse:eclipse and refresh a lot (F5 is your friend)
Other IDEs do not support ITDs and/or AspectJ compile-time aspects
26Friday, July 10, 2009
JMS SupportAnother quick installer configures ActiveMQ In Memory
No other installer settings yet, assume this will be enhanced over time...
Installs jmsTemplate that can be injected
roo> install jms -provider ACTIVEMQ_IN_MEMORY Created SRC_MAIN_RESOURCES/applicationContext-jms.xmlManaged SRC_MAIN_RESOURCES/applicationContext-jms.xmlManaged ROOT/pom.xml
27Friday, July 10, 2009
Other features
Email configuration
WebFlow
Scripting from the roo command shell
28Friday, July 10, 2009
Current Status...
These are early days.
Roo team is quite active - fixing bugs as they come up and giving us a reasonable, stable trunk build and a way to run it
Often fixes are released to trunk within a few days
29Friday, July 10, 2009
Resources
Roo JIRA:
http://jira.springframework.org/browse/ROO
Roo Forum
http://forum.springsource.org/forumdisplay.php?f=67
30Friday, July 10, 2009