AppFuse, Reduced

In November, I had some time off between clients. To occupy my time, I exercised my body and brain a bit. I spent a couple hours a day exercising and a few hours a day working on AppFuse. AppFuse isn't used to start projects nearly as much as it once was. This makes sense since there's been a ton of innovation on the JVM and there's lots of get-started-quickly frameworks now. Among my favorites are Spring Boot, JHipster, Grails and Play.

You can see that AppFuse's community activity has decreased quite a bit over the years by looking at its mailing list traffic.

AppFuse Mailing List Traffic, December 2014

Even though there's not a lot of users talking on the mailing list, it still seems to get quite a few downloads from Maven Central.

AppFuse Maven Central Stats, November 2014

I think the biggest value that AppFuse provides now is a learning tool for those who work on it. Also, it's a good place to show other developers how they can evolve with open source frameworks (e.g. Spring, Hibernate, JSF, Tapestry, Struts) over several years. Showing how we migrated to Spring MVC Test, for example, might be useful. The upcoming move to Spring Data instead of our Generic DAO solution might be interesting as well.

Regardless of whether AppFuse is used a lot or not, it should be easy to maintain. Over the several weeks, I made some opinionated changes and achieved some pretty good progress on simplifying things and making the project easier to maintain. The previous structure has a lot of duplicate versions, properties and plugin configurations between different projects. I was able to leverage Maven's inheritance model to make a number of improvements:

[Read More]

Posted in Java at Dec 16 2014, 06:03:31 AM MST 2 Comments

AppFuse 3.0 Released!

The AppFuse Team is pleased to announce the release of AppFuse 3.0. This release is AppFuse's first release as a 10-year old and includes a whole slew of improvements.

  • Java 7 and Maven 3 are now minimal requirements
  • Replaced MyFaces and Tomahawk with PrimeFaces for JSF
    • Removed SiteMesh in favor of JSF's built-in layout support
  • Added Wicket support
  • Migrated from jMock to Mockito for tests
  • Integrated wro4j and WebJars
  • Migrated to Bootstrap 3 and defaulted to Bootswatch's Spacelab theme

In addition, this release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are Spring 4, Spring Security 3.2 and Bootstrap 3. For more details on specific changes see the release notes.

What is AppFuse?
AppFuse is a full-stack framework for building web applications on the JVM. It was originally developed to eliminate the ramp-up time when building new web applications. Over the years, it has matured into a very testable and secure system for creating Java-based webapps.

Demos for this release can be viewed at http://demo.appfuse.org. Please see the QuickStart Guide to get started with this release.

If you have questions about AppFuse, please read the FAQ or join the user mailing list. If you find any issues, please report them on the users mailing list. You can also post them to Stack Overflow with the "appfuse" tag.

Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing lists.

We greatly appreciate the help from our sponsors, particularly Atlassian, Contegix, and JetBrains. Atlassian and Contegix are especially awesome: Atlassian has donated licenses to all its products and Contegix has donated an entire server to the AppFuse project.

Posted in Java at Dec 23 2013, 02:31:15 PM MST 1 Comment

Happy 10 Year AppFuse!

10 years ago yesterday, I released the first version of AppFuse. It started with XDoclet generating ActionForms from POJOs and became very popular for Struts developers that wanted to use Hibernate. The project's popularity peaked in 2006, as you can see from the mailing list traffic below.

AppFuse Mailing List Traffic

It's possible the decrease in traffic is because we re-wrote everything to be based on Maven. It's also possible it was because of more attractive full-stack frameworks like Grails and Rails. However, the real reason is likely that I stopped working on it all the time due to getting a divorce becoming an awesome dad.

Below is a timeline of how the project evolved over its first 4 years.

AppFuse History: 2003 - 2007

AppFuse has been a great project for me to work on and it's been a large source of my knowledge about Java, Web Frameworks, Spring, Hibernate - as well as build systems like Ant and Maven. We started with CVS, moved to SVN and now we're on GitHub. We've experienced migrating from Tapestry 4 to Tapestry 5 (thanks Serge Eby!), upgrading to JSF 2 and enjoyed the backwards compatibility of Spring and Struts 2 throughout the years. We've also added REST support, a Web Services archetype and kept up with the latest Spring and Hibernate releases.

AppFuse History: 2007 - 2013

Last year, we added Bootstrap and jQuery as foundational front-end frameworks. For our next release, we're switching to PrimeFaces, adding Wicket and changing from jMock to Mockito. Most of these changes are already in source control, we just need to polish them up a bit and add AMP support. I hope to release 3.0 before the bus is done. ;)

Thanks to all the enthusiastic users of and contributors to AppFuse over the years. It's been a great ride!

Posted in Java at Apr 05 2013, 08:56:45 AM MDT 3 Comments

Integrating GWT into AppFuse

I've been interested in integrating GWT into AppFuse ever since I blogged about it 4 years ago. A few months after that post, I wrote about Enhancing Evite.com with GWT and Grails. After Evite, I had a gig near Boston where I developed with GXT for the remainder of the year. When all was said and done, I ended up spending a year with GWT and really enjoyed my experience. I haven't used it much since.

GWT is scheduled to be integrated into AppFuse in version 4.0. That's quite a ways off. The good news is you might not have to wait that long, thanks to Iván García Sainz-Aja. Iván let us know about his work a couple weeks ago in an email to the appfuse-dev mailing list.

It's still work in progress but it has already most of AppFuse functionality..

If you want to give it a try

https://github.com/ivangsa/appfuse.git

the quickest way to have a go would be

web/gwt> mvn -P gwtDebug -Dgwt.inplace=true gwt:compile jetty:run  

at the moment it still requires this fork of gwt-bootstrap to be compiled first

https://github.com/ivangsa/gwt-bootstrap.git

It needs a lot of testing yet but it's getting quite there

As you can imagine, I was very excited to hear about Iván's work. So I cloned his repo, built gwt-bootstrap locally and checked it out. Functionality wise, it was great! However, when I dug into the source code, I found a whole lotta code.

To see how the GWT flavor compared to the other implementations in AppFuse, I created a cloc report on the various web frameworks in AppFuse. I'm sure these reports could be adjusted to be more accurate, but I believe they give a good general overview. I posted some graphs that displays my findings in visual form.

Lines of Java Number of Files

When I sent this to the mailing list, Ivan responded that it was a lot of code and estimated 12 new files would be needed to CRUD an entity. This sure seems like a lot to me, but he defended this yesterday and noted that his implementation follows many of GWT's latest best practices: MVP pattern, Activities and Places, EventBus, Gin and Guice. He also shared a wiki page with explanations and diagrams of how things work.

The reason I'm writing this post is to get more feedback on this implementation. First of all, does GWT really require this much code? Secondly, are there other GWT implementations that reduce a lot of the boilerplate? SmartGWT, Vaadin* and Errai come to mind.

If you were starting a new GWT project and using AppFuse, how would you want it implemented?

* Vaadin 7 claims it can be used as a drop-in replacement for GWT. I tried replacing the gwt-servlet and gwt-user dependencies with Vaadin's, but it didn't work.

Posted in Java at Mar 07 2013, 06:49:28 PM MST 7 Comments

Switching AppFuse from MyFaces to PrimeFaces

When describing my bias against JSF back in November, I wrote:

... there's a lot of folks praising JSF 2 (and PrimeFaces moreso). That's why I'll be integrating it (or merging your pull request) into the 2.3 release of AppFuse. Since PrimeFaces contains a Bootstrap theme, I hope this is a pleasant experience and my overall opinion of JSF improves.

Shortly after the AppFuse 2.2.1 release in December, Gilberto Andrade contributed a sample project that used Mojarra (the JSF RI) and PrimeFaces instead of MyFaces and its Tomahawk components. Last week, I spent a few hours integrating Gilberto's changes into AppFuse's master branch. You can see all the changes I made (which include a Jetty plugin upgrade and some cleanup) in this Crucible review. Feel free to leave comments on ask questions in the review itself.

The first thing I noticed when integrating PrimeFaces is you have to add a custom repository in order to get its artifacts via Maven.

<repositories>
    <repository>
        <id>prime-repo</id>
        <name>Prime Repo</name>
        <url>http://repository.primefaces.org</url>
    </repository>
</repositories>

This is unfortunate since all of AppFuse's other dependencies can be found in Maven Central. It means that if you're using a JSF archetype, the PrimeFaces repo will be checked for artifacts first, causing an unnecessary slowdown in artifact resolution. I hope the PrimeFaces developers fix this soon.

While integrating these two frameworks, I ran into a number of issues.

An IllegalStateException on startup when using "mvn jetty:run"
The first issue I encountered was that I was unable to run the app in Jetty. It worked fine in Tomcat but I got the following error in Jetty:

2013-01-31 22:28:07.683:WARN:/:unavailable
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:951)
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:316)
at javax.faces.webapp.FacesServlet.init(FacesServlet.java:302)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:492)
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:312)

I found the fix for this on Stack Overflow and added the following listener to my web.xml to solve it.

<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

Conditionally rendering a button disables its click-ability
The next thing I noticed was the Delete button didn't work when editing a user. It was hidden correctly when adding a user, but clicking on it to delete a user simply refreshes the page. Below is the code I used successfully with MyFaces. For some reason, this doesn't work with PrimeFaces.

<c:if test="${not empty userForm.user.id}">
<h:commandButton value="#{text['button.delete']}" action="#{userForm.delete}"
    styleClass="btn" onclick="return confirmMessage(msgDelConfirm)"/>
</c:if>

I also tried the following, but no dice. This is currently an open issue.

<h:commandButton rendered="${not empty userForm.user.id}" value="#{text['button.delete']}" 
    action="#{userForm.delete}" styleClass="btn" onclick="return confirmMessage(msgDelConfirm)"/>

The PrimeFaces Bootstrap theme 404s on some images
After integrating PrimeFaces' Bootstrap theme, the following error shows up in server logs.

[INFO] [talledLocalContainer] Feb 02, 2013 10:40:25 PM com.sun.faces.application.resource.ResourceHandlerImpl logMissingResource
[WARNING] [talledLocalContainer] WARNING: JSF1064: Unable to find or serve resource, images/ui-bg_highlight-hard_70_000000_1x100.png, from library, primefaces-bootstrap.

This seems to have happened before in previous releases and is currently an open issue.

Canoo WebTest doesn't work with fileUpload nor to set checkbox values
We use Canoo WebTest to run integration tests on the UI in AppFuse. For some reason, performing file uploads and setting checkbox values works fine with MyFaces/Tomahawk, but not with Mojarra/PrimeFaces. I'm not sure if this is caused by the JSF core or the component library, but it remains an open issue. For now, I've just commented out the parts of tests that used to do this.

On a related note, getting the real path of a resource from the ServletContext worked fine before the switch, but results in a null value now.

String uploadDir = getServletContext().getRealPath("/resources") + "/" + request.getRemoteUser() + "/";

PrimeFaces resources served up at /javax.faces.resource/* not found
While I didn't have problems with this in AppFuse, I did encounter it in AppFuse Light. I don't know why there was a difference between the two, but it turned out to be caused by the UrlRewriteFilter and my desire for extensionless URLs. The outbound-rule to strip .xhtml from URLs was the culprit. Adding a condition to it solved the problem. Yeah, the condition seems backwards, but it works.

<outbound-rule match-type="regex">
    <condition type="query-string" operator="equal">ln=primefaces</condition>
    <from>^(.*)\.xhtml(\?.*)?$</from>
    <to last="false">$1$2</to>
</outbound-rule>

Summary
The initial switch to Mojarra/PrimeFaces was pretty easy thanks to Gilberto's sample project. However, the small issues encountered after that turned out to be quite frustrating and you can see that several are still not fixed. I guess it just goes to show that not all web frameworks are perfect. Hopefully we'll get these minor issues fixed before the next release. In the meantime, you can checkout the updated demos for AppFuse JSF and AppFuse Light JSF.

Posted in Java at Feb 06 2013, 12:19:34 PM MST Add a Comment

AppFuse Light 2.2.1 Released!

In December, the AppFuse Team released 2.2.1. Right before that release, I decided to wait on enhancing its "light" modules, a.k.a. AppFuse Light. I'm glad I did, because it took some effort to get jQuery and Bootstrap integrated, as well as to make it more secure.

The good news is AppFuse Light 2.2.1 is released and it's sitting out on the Central Repository. This release is a refactoring of all archetypes to be up-to-date with the AppFuse 2.2.1 release. This means Java 7 compatibility, Servlet 3, Bootstrap/jQuery integration, Tapestry 5.3.6 upgrade and security improvements. I integrated Bootstrap and jQuery using WebJars Servlet 3 support since it was simple and straightforward.

You can create projects using AppFuse's light archetypes using a command such as the following:

mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes 
  -DarchetypeArtifactId=appfuse-light-spring-freemarker-archetype -DarchetypeVersion=2.2.1 
  -DgroupId=com.mycompany -DartifactId=myproject 

The list of archetypes is as follows:

  • appfuse-light-jsf-archetype
  • appfuse-light-spring-archetype
  • appfuse-light-spring-freemarker-archetype
  • appfuse-light-spring-security-archetype
  • appfuse-light-stripes-archetype
  • appfuse-light-struts-archetype
  • appfuse-light-tapestry-archetype
  • appfuse-light-wicket-archetype

The QuickStart Guide will help you get setup and demos are available at the following links:

If you have questions about AppFuse, we invite you to ask them on the users mailing list or tweet using #appfuse.

For those enjoying Bootstrap in your apps, I encourage you to check out {wrap}bootstrap and Bootswatch.

Posted in Java at Jan 24 2013, 07:43:20 PM MST Add a Comment

AppFuse 2.2.1 Released!

The AppFuse Team is pleased to announce the release of AppFuse 2.2.1. This release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are Hibernate 4, Struts 2.3.7, Apache CXF 2.7.0 and Spring Security 3.1.3. In addition, we've integrated HTML5, Twitter Bootstrap, jQuery and replaced Compass with Hibernate Search. Last but not least, we've added full support for Java 7 and integrated many security improvements. For more details on specific changes see the release notes.

What is AppFuse?
AppFuse is a full-stack framework for building web applications on the JVM. It was originally developed to eliminate the ramp-up time when building new web applications. Over the years, it has matured into a very testable and secure system for creating Java-based webapps.

Demos for this release can be viewed at http://demo.appfuse.org. Please see the QuickStart Guide to get started with this release.

A number of blog posts were written about features that went into this release while it was being developed:

If you have questions about AppFuse, please read the FAQ or join the mailing list. If you find any issues, please report them on the users mailing list.

Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing lists.

We greatly appreciate the help from our sponsors, particularly Atlassian, Contegix and JetBrains. We highly recommend using the new IntelliJ IDEA 12 for developing web applications.

Posted in Java at Dec 11 2012, 03:21:44 PM MST 5 Comments

Improving AppFuse's PageSpeed with Apache

One of the most important things when developing webapps is to make them fast. With AppFuse, we've tried to incorporate many of the 14 rules for faster-loading websites. We had a gzip filter before it was cool (2003) and replaced it with the one from EhCache. However, users experienced issues with both of these, both with XFire/CXF and WebWork/Struts 2 and JSPs. Because of these issues, we disabled gzipping a few releases ago.

This article is designed to show you how you can make your AppFuse webapp faster, without modifying any code. The good news is this applies to any webapp that you can deploy behind Apache.

Last Friday, I sent an email to the good folks at Contegix to see if they could install mod_pagespeed on the Apache server that sits in front of *.appfuse.org. My goal was to improve the YSlow and PageSpeed scores of the apps hosted on demo.appfuse.org. I discovered they were getting a dismal score of 24 and figured we could do a lot better. mod_pagespeed speeds up your site and reduces page load time by automatically applying web performance best practices. It seemed like an easy solution.

Unfortunately, we were unable to use mod_pagespeed. From the guys at Contegix:

Attempting to install mod_pagespeed as you requested, we find that it requires Apache httpd 2.2 and libstdc++ 4.1.2, both of which are unsupported in RHEL4. To get mod_pagespeed to work on your present operating system basically means re-rolling the core components, which would make them unsupported. I'm afraid mod_pagespeed is simply not an option on your present configuration.

Since I still wanted to improve performance, I opted for another route instead: using mod_deflate (for gzipping) and mod_expires (for expires headers). I also turned on KeepAlive as recommended by PageSpeed Insights.

mod_deflate
mod_deflate was already installed in Apache (version 2.0.52), so all I had to do was configure it. On RHEL4, Apache is installed at /etc/httpd and there's a conf.d directory that contains all the configuration files. I created a file at /etc/httpd/conf.d/deflate.conf and populated it with the following:

#
# mod_deflate configuration
#
<IfModule mod_deflate.c>
    SetOutputFilter DEFLATE
    
    AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript
    
    DeflateCompressionLevel 9
    
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    
    DeflateFilterNote Input instream
    DeflateFilterNote Output outstream
    DeflateFilterNote Ratio ratio
    
    LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    
</IfModule>

At first, I had separate lines for all the different content types (as recommended by this article). The Contegix support crew figured out the solution (everything needed to be on one line) in 14 minutes, updated the config and verified it worked using an http compression testing page.

mod_expires
mod_expires was already installed, so I added a config file at /etc/httpd/conf.d/expires.conf. I used this howto and asked Contegix for help when it didn't work. Their response took quite a bit longer this time (49 minutes), but they once again figured it out:

It appears that FilesMatch does not like to play will JkMount. It does work using content type.

My final config for expires.conf:

<IfModule mod_expires.c>
    ExpiresActive On
    
    <FilesMatch "\.(jpe?g|png|gif|js|css)$">
        ExpiresDefault "access plus 1 week"
    </FilesMatch>
    
    ExpiresByType image/jpeg "access plus 1 week"
    ExpiresByType image/png "access plus 1 week"
    ExpiresByType image/gif "access plus 1 week"
    ExpiresByType text/css "access plus 1 week"
    ExpiresByType application/javascript "access plus 1 week"
    ExpiresByType application/x-javascript "access plus 1 week"
</IfModule>

I used "1 week" because we're changing things quite a bit right now and we haven't integrated resource fingerprinting yet.

KeepAlive
The last thing I did to improve performance was to turn on KeepAlive by editing /etc/httpd/conf/httpd.conf and changing Off to On.

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

Summary
As a result of these changes, our PageSpeed score went from 24 to 96 and YSlow went from a 90 to a 98. When I started this experiment, I was only trying to fix demo.appfuse.org. However, it also improved the speed of all the other *.appfuse.org sites, including Confluence, Bamboo, JIRA and FishEye. Thanks for all the help Contegix! There's a good chance you've given me back a few minutes in each day.

Originally posted on the AppFuse Blog.

Posted in Java at Dec 04 2012, 09:25:05 AM MST 7 Comments

AppFuse News: Liquibase and wro4j Tutorials from J. García

New committer J. García has been doing a lot of work to improve i18n in AppFuse 2.2, as well as our Struts 2 support. In addition, he's written a couple articles that show you how to integrate Liquibase and wro4j in your AppFuse applications. Thanks for the great documentation J!

The 2.2 release is coming along, and we're down to 16 open issues. I've updated the Hibernate, JPA, Services and Web Services tutorials and hope to finish the web tutorials in the next week. You can try the latest code using the QuickStart Guide or check it out on the demo site:

Please see this thread on the mailing list if you have any questions or suggestions.

In related news, Roger Hughes has a good article titled Ten Things You Can Do With Spring Security. Since AppFuse uses Spring Security extensively, hopefully you can use some of Roger's tips to improve the security of your app.

Posted in Java at Nov 30 2012, 02:32:47 PM MST Add a Comment

AppFuse News: GitHub, Hibernate Search and The Future

It's been a while since I've written anything about AppFuse, but since the project has had quite a bit of activity lately, now seems like a good time.

GitHub
First of all, we moved the source code from java.net to GitHub way back in June. Thanks to Serge for helping with this process and making it quick and painless. For some reason, shortly after moving, we started having quite a few build issues with Bamboo. I was able to diagnose the problem as not enough memory on our server. Thankfully, Contegix was able to add another 2GB of RAM to our box and get everything back up-to-snuff.

New Committer: J. Garcia
J. Garcia has been a regular voice on the users and developers mailing list for several months. He's recently started contributing a lot of patches in JIRA and seems genuinely interested in the success of AppFuse. That's why we voted and added him as a committer. To prove this was a smart move, he recently replaced Compass with Hibernate Search and upgraded to Hibernate 4. As part of this work, he removed iBATIS support, which brings me to my next point.

The Future
In mid-August, I sent an email to the community, asking them "Anyone using iBATIS?"

I'm thinking of replacing AppFuse's Data Tier with Spring Data, especially because it has NoSQL and REST support. There's a good intro on InfoQ today:

http://www.infoq.com/articles/spring-data-intro

Does anyone see an issue with this? The lack of iBATIS support could be an issue, but I doubt it since if we wanted to continue supporting it, we should move to MyBATIS.

Everyone agreed this was a good idea and it seemed like a logical time to remove iBATIS support. In addition, I posted a roadmap I jotted down in early May. Since we've missed all the dates so far, I've removed them from the listing below. We hope to get 1-2 releases done by the end of this year, with 2.2 in the next 2-3 weeks.

2.2
Hibernate 4
Hibernate Search
Bootstrap
H5BP

2.3
AMP for all light modules
Wicket
PrimeFaces

2.4
JSR 303 (might require removing or developing client-side support)
Mockito instead of jMock/EasyMock

2.5
AMP one-to-many
Spring Data
MyBatis (if there's interest in adding it back in)

2.6
wro4j for concatenation and minimizing JS and CSS
pjax - https://github.com/defunkt/jquery-pjax

2.7
Scala example
Gradle example
Article about examples

3.0
GWT

Maven Central Statistics
To prove there's still a fair amount of folks using AppFuse, here's some statistic from Sonatype's OSS Repository Hosting Service.

AppFuse Downloads

From this screenshot, you can see that AppFuse artifacts are downloaded around 7,000 times per month. The following graph is even more interesting. Apparently, around 3,000 new projects are created with AppFuse archetypes each month.

AppFuse Archetype Downloads

The AppFuse Name
Finally, I recently discovered that ShoreTel decided to name a new product AppFuse. I guess this signifies two things: 1) it's a good name for a product and 2) someone didn't do their research before naming it. At this point, I'm not too concerned, but it is an interesting development.

Posted in Java at Sep 25 2012, 10:42:14 AM MDT 5 Comments