The technologies used are :
- JSF 2.0 - Mojarra 2.0.2
- Spring 3.0.0.RELEASE
- Spring Security 3.0.0.RELEASE
- Hibernate Validator 4.0.2.GA as reference implementation of JSR 303: Bean Validation
- AspectJ 1.6.7
- Groovy and the gmaven-plugin
You can see a live demo at : http://sandcode.appspot.com
The application is build with Maven 2.2.1
For local execution you would need Google App Engine SDK
The archetype was updated on 11 February 2010, so that works for latest Google App Engine - 1.3.1
If you want to play and customize it you would need to have installed and configured Java, Maven and Google App Engine SDK
Choose gae-archetype after running :
mvn archetype:generate -DarchetypeCatalog=http://sandcode.googlecode.com/svn/maven2/
build the application :
mvn install
run it :
dev_appserver target/YOUR_ARTIFACT_ID
type in your browser: http://localhost:8080
enjoy :)
If you want to extend the application you can use the small generation utility coming with it :
mvn -Pcrud -Ddomain=Book -Dfields=title,author,remarks
The generator will create for you :
src/main/java/YOUR_EXAMPLE_PACKAGE_NAME/app/domain/Book.java
src/main/java/YOUR_EXAMPLE_PACKAGE_NAME/app/repository/BookRepository.java
src/main/java/YOUR_EXAMPLE_PACKAGE_NAME/app/web/BookController.java
src/main/webapp/secured/book/list.xhtml
src/main/webapp/secured/book/detail.xhtml
src/main/webapp/secured/book/form.xhtml
It will also extend the menu :
src/main/webapp/resources/app/menu.xhtml
with :
<app:menu-group groupname="GEN ADDED - Book ">
<app:menu-item itemoutcome="/secured/book/list" itemvalue="#{msg['book.view.list']}">
<app:menu-item itemoutcome="/secured/book/form" itemvalue="#{msg['book.view.form']}">
</app:menu-item>
Extend the application default Messages bundle :
src/main/resources/Messages.properties
with:
#labels generated for Book
book.view.detail=GEN Book detail
book.view.form=GEN Book form
book.view.list=GEN Book list
book.title=GEN Title
book.author=GEN Author
book.remarks=GEN Remarks
This was the 2 min intro.. depending on your internet connection you can have a nicely running GAE application for about 2-5 min :)
If you want to deploy it on your account of Google Application Engine you will have to edit by hand :
src/main/webapp/WEB-INF/appengine-web.xml
and then type :
appcfg update target/YOUR_ARTIFACT_ID
And... Some more... :
The application is having the following features :
layerd architecture - domain, service, controller
'request' based crud for JSF
localized - currently supports English and Bulgarian. To add another language you need to :
1. create a translated copy of Message.properties
2. edit faces-config.xml
3. download from http://www.famfamfam.com/lab/icons/flags/ the correct flag ;) and add it to src/main/webapp/resources/img/flag with the right name.
4. create a translated copy of ValidationMessages.properties (needed by Bean Validation)
Basic UI customization - the user can change the preffered language, the position of the menu and the colors of the application.
Using of JSF 2.0 custom components, templating.
Using of "JSR 303: Bean Validation".
Using of "JSR 330: Dependency Injection for Java" annotations with Spring 3 ( javax.annotation.ManagedBean , @Inject, @Named ).
Using of Java Config style for Spring 3 ( @Configuration ).
Using of @Bean annotation with inplace implementation of an interface, directly in the @Configuration bean.
Using of @RolesAllowed (javax.annotation.security.RolesAllowed) with Spring Security 3 for securing your application.
Using of 2 distinct roles ROLE_USER and ROLE_ADMIN, securing of methods called with h:commandLink (or h:commandButton)
'Native' integration between Spring Security and JSF : app/web/LoginBean.java ; src/main/webapp/login.xhtml
Almost NO xml configuration for spring : src/main/webapp/WEB-INF/applicationContext.xml
AspectJ for logging app/aspect/TimeExecutionLoggingAspect.java (well.. by default it is swithced off, but you can take a look in the pom.xml )
AspectJ and the Spring stereotype annotations (Repository, Service, etc..) can help you easy log only what you need : app/aspect/SystemArchitecture.java
AspectJ for static weaving of 3rd party jar files (in our case this is jsf-impl , because of a bug in the local Google App SDK ) : common/aspect/FixWebConfigurationAspect.java
Groovy gmaven-plugin and Groovy Templates for generation of files..
Using of box-shadow and border-radius css properties for IE : src/main/webapp/resources/css/gray.css
Enjoy :)
And I'm definitly waiting for your feedback, questions and proposals ;)
21 comments:
The best application ever!
Thanks :)
I accidentally took a look at the applicationContext.xml at http://sandcode.googlecode.com/svn/tags/BLOG_JAN2010/crud-jpa-spring-gae/src/main/webapp/WEB-INF/applicationContext.xml and the schema is for Spring 2.5???
Много добро много добро :Д
Супер :Д
RE: Toy
you are right , the schema is the one for Spring 2.5 . But, that is one of the great things about Spring - they are backward compatible. Also the configuration of beans with annotations is available exactly since version 2.5. Spring 3.0 adds the support for JSR 330 - "Dependency Injection for Java" , and not only that.. Thanks for the interest in the post :)
Hi Dimitar,
superb post, nice recipe with fresh ingredients!
The use of aspects is fantastic just as Chris Richardson lesson.
Among the others I've appreciate very much this snippet in pom
UTF-8
Regards
Hi Domenico,
thanks a lot for the good words :)
I'm happy that you have enjoyed the post.
Hi,
Thanks for this really good post.
I try to start from scratch without Maven, and i have a problem.
When i try to access a managedbean, i have a null error. I see a log at Jetty startup :
JSF1027: [null] The ELResolvers for JSF were not registered with the JSP
If you have a solution, thanks.
Hi, what is the startup time of the app? I have similar setup with jsf2 and it took about 15s to render first page. Thanks Luba
Hi Luba,
the "cold" startup time for that app is between 18-23 sec according to the log files, which shouldn't worry you at all. If you are having enough users, it will stay "warm" and the response times are round 180ms to 500ms depending on the executed back-end logic. If you want to keep the application "warm" you can implement some "cron" task, but this is not needed if you have enough users.
Hi Richard,
the problem with your app could be anywhere - versions of jar files, web.xml, faces-config.xml . I would recommend you to take some of the existing maven archetypes, or just working sample, and then to modify it to fit your needs.
Hi Makariev,
Thanks for your answer.
I have found my error. I have used a bad @ManagedBean (javax.faces), instead of javax.annotation. So spring cant make this job ;)
Now, application works but, yes there is a but ;)
I have a managed bean whith a list. When the list is called by some XHTML, my logger show me that getter is called 8 times ...
I'm beginner on JSF2, but i think is not a normal lifecycle ?
Thanks
Excellent post!!, i enjoy read it.
Kernelman, Montreal(CA)
Hi Makariev,
when I deploy it, error appears:
No persistence unit with name 'person-pu' found
but when I move the configuration to application-context.xml and append this line "" on pulEntityManagerFactory, it works fine.
any idea how POJO configuration cannot find the persistence.xml?
the line appended is persistenceXmlLocation in application-context, it works fine, but on POJO it doesn't work as if it cannot find the path of persistence.
Hi Kahlil,
no idea what might be wrong with your deployment. The live demo application on the top of the post is exactly what I've described here.. and it works :) If the problem is on your local system, that could be something with the local environment : jdk version, gae version..
Bravo, Makariev!
I especially adore how you do this:
"AspectJ for static weaving of 3rd party jar files (in our case this is jsf-impl , because of a bug in the local Google App SDK ) : common/aspect/FixWebConfigurationAspect.java"
This is a very good use of AspectJ, and I'm glad you used it!
No more monkey-patching sources... (although that AOP is exactly monkeypatching, but what I mean is no need to change the original JAR)
Keep up the good work! Waiting for more of your quality posts.
P.S.: can you add in PrimeFaces 2.0 please??
You should disable snapshots for the repository definitions.
Hi Hendy,
Thanks for the good words :),
I've added your proposal for disabling snapshots - definitely important for faster build :)
This is by far the most useful post concerning Spring and App Engine I have found to date. And everything using the most recent version.. A true dream come true. Thank you SO much for giving back to the community!
Excellent demo!
Post a Comment