Matt RaibleMatt Raible is a Web Developer and Java Champion. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

Integrate AppFuse with Crowd in 5 Easy Steps

The good folks at Atlassian have written a nice tutorial on Integrating Crowd with AppFuse and Acegi. Crowd is a web-based single sign-on (SSO) tool that simplifies application provisioning and identity management. We use Crowd for the AppFuse project to maintain a single user store for JIRA, Confluence, and Bamboo. It's worked awesome for us.

Posted in Java at Nov 29 2007, 10:33:32 AM MST 2 Comments

AppFuse Light 1.8.1 Released: includes upgrades to Spring 2.5 and Wicket 1.3

AppFuse Light 1.8.1 is a bug fixes release that includes an upgrade to Spring 2.5 and Wicket 1.3 RC1. See the Release Notes for more information on what's changed since the last release.

What is AppFuse Light? Click here to find out.

AppFuse Light now offers 60 possible combinations for download:

  • Web Frameworks: JSF (MyFaces), Spring MVC (with Ajax, Acegi Security, JSP, FreeMarker or Velocity), Stripes, Struts 1.x, Struts 2.x, Tapestry, WebWork, Wicket
  • Persistence Frameworks: Hibernate, iBATIS, JDO (JPOX), OJB, Spring JDBC

AppFuse Light Screenshot - click on the box at the bottom right of AL to activate StyleSheet Switcher

If you have any questions about this release, please subscribe to the AppFuse user mailing list by sending a blank e-mail to [email protected]. You can also post questions in a forum-like fashion using Nabble: http://appfuse.org/forum/user.

If you're a developer of one of the frameworks that AppFuse Light uses - I'd love a code review to make sure I'm "up to snuff" on how to use your framework. I'm also more than willing to give commit rights if you'd like to improve the implementation of your framework.

Live demos are available at:

What's on tap for AppFuse Light 2.0? Here's what I'm hoping to do:

  1. Drop the seldom-used persistence frameworks: JDBC, JDO and OJB.
  2. Drop Struts 1.x and WebWork as web frameworks (replaced by Struts 2).
  3. Support the same persistence frameworks as AppFuse: Hibernate, iBATIS and JPA.
  4. Re-use appfuse-service, appfuse-hibernate, appfuse-ibatis and appfuse-jpa in AppFuse Light. I'll likely include the core classes (User, Role) since AppFuse Light is more "raw" than AppFuse.
  5. Require Java 5.

Let me know if you disagree with any of these items or would like to see other enhancements.

Posted in Java at Nov 29 2007, 09:28:06 AM MST 3 Comments

AppFuse 2.0.1 Released

The AppFuse Team is pleased to announce the release of AppFuse 2.0.1. This release squashes a number of bugs and includes an upgrade to Spring 2.5. To learn more about Spring 2.5's features, see InfoQ's What's New in Spring 2.5: Part 1 article.

For information on upgrading from 2.0, see the 2.0.1 Release Notes or changelog. AppFuse 2.0.1 is available as a Maven archetype. For information on creating a new project using AppFuse, please see the QuickStart Guide or the demos and videos.

What is AppFuse? Click here to find out.

The 2.0 series of AppFuse has a minimum requirement of the following specification versions:

  • Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)
  • Java 5+

If you've used AppFuse 1.x, but not 2.x, you'll want to read the FAQ. Join the user mailing list if you have any questions.

Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues.

We greatly appreciate the help from our sponsors, particularly Atlassian, Contegix, JetBrains, and Java.net. 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. Thanks guys - you rock!

Please post any issues you have with this release to the mailing list.

Posted in Java at Nov 26 2007, 09:29:43 AM MST 4 Comments

Comparing Java Web Frameworks Presentation on Parleys.com

The good folks from JavaZone have published a video of the Comparing Java Web Frameworks presentation I did in Oslo in September. Enjoy!

Update: In this presentation, I say we've chosen Struts 2 at LinkedIn. Even though it solved most of our problems, I'm also now prototyping with Spring MVC. I wish JSP/JSTL had a way to call methods with arguments like Struts' OGNL supports.

Posted in Java at Nov 23 2007, 10:17:43 AM MST 14 Comments

Go Light with Apache Struts 2 and REST by Don Brown

After attending Dan's talk on REST, I stayed in the same room and listened to Don Brown talk about Struts 2's support for building RESTful applications. Below are my notes from the event.

What is wrong with today's web applications? You're using a modern web framework and you've cleanly separated your presentation and business logic. The biggest problem in modern web applications is Confusing URLs.

A URL should be a resource indicator - not a method invocation. Often, web applications have little or no caching. People use GET to perform data manipulation and POST may or may not change state (especially with JSF). Another big issue with modern web frameworks is there's too many abstraction layers that hide HTTP headers and it's difficult to manipulate them.

Today's applications are "information silos". There's a lot of information in your applications, but it's all buried in HTML, JavaScript and CSS. There's no way to get this information out of your application unless you explicitly expose it.

The answer to many of these problem is REST. It's the Way of the Web. To solve the information silo problem, you can create a single interface that has multiple representation of the same resource. There's one URI for all types of resources - be it XML, JSON or HTML. How does this work w/o modifying the URL? You modify the URL's extension.

Struts 2 has a couple of plugins that make developing RESTful services easier. The first is the Codebehind plugin and the 2nd is the REST plugin. Don is doing a demo with the REST plugin and shows that there's no Struts configuration files needed (no struts.xml and no struts.properties). The only thing that's necessary is to specify an "actionPackages" init-param on the DispatcherFilter in web.xml. This activates the Codebehind plugin that uses conventions to determine the view template's path.

In Don's demo, he's creating an "OrdersController" that implements ModelDriven. After implementing a setId() method (to set the id from the request parameters), a getModel() method (to return the Order object) and implementing a show() method that returns HttpHeaders, Don starts up his server and shows that http://localhost:8080/order/5 returns an HTML page. Changing the URL to end in /5.json returns JSON, /5.xml returns XML.

public HttpHeaders create() {
    service.save(order);
    return new DefaultHttpHeaders("success").setLocationId(order.getId());
}

The Poster Plugin for Firefox is great when you're working with REST services. Don used this plugin to show us that it's possible to post to JSON and get back JSON results. His demo was impressive, especially the fact that there was no XML configuration required for Struts. I also like how the DefaultHttpHeaders class allows you to manipulate headers in a type-safe manner.

To use the REST plugin, you'll want to use Struts 2.1. If you're using Maven, all you need to depend on is struts-rest-plugin. The struts-codebehind-plugin (as well as struts-core) will be pulled in by transitive dependencies.

One disadvantage of REST vs. WS-* is you can't generate client code from a WSDL. You'll have to write your client by hand. However, one advantage of REST is there's already lots of clients - your browser, curl, etc.

The Struts REST Plugin hasn't been officially released, but hopefully will be in Struts 2.1.1. You can checkout the code from SVN using the URL below. The documentation is located here.

http://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/rest

Great talk Don - and excellent work on the REST plugin for Struts. I can't wait to try it out.

Posted in Java at Nov 15 2007, 06:12:58 PM MST 18 Comments

Building scalable, reliable, and secure RESTful services with Dan Diephouse

This afternoon, I attended Dan Diephouse's talk on RESTful services. Below are my notes from his presentation.

Roy Fielding coined the term REST (REpresentative State Transfer) in a thesis. Everything is a resource and are addressable via URIs. Resources are self descriptive and manipulated with verbs via a uniform interface. We don't want keys - we want links! Resources are hypertext. Hypertext is just data with links to other resources. Data model refers to other application states via links. This is possible because of the uniform interface!

REST and HTTP
There's 5 main HTTP methods: GET, POST, PUT, DELETE and HEAD. Get is cacheable and safe (there's no side effects). POST is an unsafe operation and can't be repeated. HEAD is used to retrieve a resources metadata, without getting the method body.

To create a new resource, you use POST. The server will return an HTTP 201 (Created) with a Location header. After that, you'll do a PUT to the location and you'll get back an HTTP 200. Another option is to have the client generate a unique id and PUT to it straight away - instead of doing the POST/PUT - where the POST generates the unique URL.

The biggest problem with REST is firewalls. Many firewalls don't allow PUT or DELETE. Google fixes this by adding a header that specifies a method override.

One of the constraints of REST is all communication is stateless. Session state is kept on the client. The client is responsible for transitioning to new states. States are represented by URIs. The advantage is this improves visibility, reliability and scalability. You don't need to replicate session state on your services in a cluster.

ETag header
Resources may return an ETag header when it is accessed. On subsequent retrieval of the resource, client sends this ETag header back. The client can then use a "If-None-Match" header with the ETag value to communicate with the server. The server will send back a 304 (Not Modified) with no body if nothing has changed. LastModified is a similar header that servers send back. The client will then send a "If-Modified-Since" header and get a similar result.

REST allows scalability through Caching - a.k.a. "cache the hell out of it". There's 3 types of cache:

  • Browser
  • Proxy
  • Gateway

How does caching actually work? A resource is eligible for caching if:

  • The HTTP response headers don't say not to cache it
  • The response is not authenticated or secure
  • No ETag or LastModified header is present
  • The cache representation is fresh

Is your cache fresh? Yes, if the expiry time has not been exceeded and the representation was LastModified a relatively long time ago. If it's stale, the remote server will be asked to grab a new copy of the resource and send it back to you.

HEAD allows you to get metadata about a resource without getting the resource itself. You can use it to test that a resource exists, that a link is valid or to check when a resource was last modified.

There's an "Expect 100 Continue" header you can use to query the server to see if it's capable of receiving a message. The nice thing about this is you get client-server communication before sending the message body. An example was provided where you upload an image from your cell phone. You don't want to start sending the message body if authentication is required. Your phone can check for "100 continue" to determine if it should start uploading the file.

For doing batch operations with REST, you can use HTTP connection pipelining. Unfortunately it's broken by some firewalls. Another option is to POST a whole set of data. GData (an extension to the Atom Publishing Protocol) fixes this by allowing you to post a whole bunch of entries at once. Unfortunately, this approach has received a very cold reception from the community.

The Atom Publishing Protocol is a RESTful protocol for building services. You can use it to create, edit, delete entries in a collection. It's an extensible protocol; examples include paging extensions, GData and OpenSearch.

Why should you use APP for your application? Because it provides ubiquitous elements which have meaning across all contexts. You can leverage existing solutions for security (HTTP Auth, WSEE, Google Login, XML Signatures and Encryption). It also eliminates the need for you to write much of the client/server code. Alternatives to APP include HTTPD, Java (Servlets, Restlets, Spring MVC), Ruby on Rails and many others.

Limitations of REST are HTTP is NOT an RPC or message passing system. It also isn't as secure as other solutions. A lot of times, folks just use SSL and basic authentication - which isn't the most secure system.

Dan posted his presentation on his blog if you'd like to download it.

Posted in Java at Nov 15 2007, 06:04:22 PM MST 3 Comments

Comparing JVM Web Frameworks Presentation

Early this morning, I assembled a Comparing JVM Web Frameworks presentation in preparation for my talk tomorrow at ApacheCon. As mentioned on Monday, this presentation compares Flex, Grails, GWT, Seam, Struts 2 and Wicket. While I think this presentation would be fun to deliver, I don't believe it has as much meat as the original talk I was planning to give. My original talk compares JSF, Spring MVC, Stripes, Struts 2, Tapestry and Wicket. Since I've used all these frameworks, I'm able to compare them more on their technical features. Since I haven't used Flex, GWT or Seam, there was no way for me to 1) try them all before tomorrow and 2) do a thorough analysis of how well they each handle my desired features.

Since the abstract on ApacheCon's website mentions my original presentation, I don't want to yank out the carpet and present the second without asking. So my plan is to ask the audience which one they'd rather hear and continue from there. I've updated both presentations with the latest statistics and uploaded them for your review. For those of you who've used these frameworks, I'd be interested to hear how accurate you think my Pros and Cons section is. If you know of better pros or cons, please let me know and I'll adjust as needed.

While creating the 2nd presentation, I found a couple things that surprised me. The first is how popular Flex is - not only in job listings, but also in skilled developers and mailing list traffic. Below is a graph that shows how there aren't many jobs for most of the frameworks, but there's lots for Flex.

Dice.com Job Count - November 2007

The following graph illustrates while I chose to use Flex instead of OpenLaszlo as the Flash framework. OpenLaszlo has a much smaller community than Flex.

User Mailing List Traffic - November 2007

The second thing that was surprising is Seam doesn't have a logo! How does it ever expect to become a popular open source project without a logo?! It's amazing they've made it this far without having this essential feature. To motivate the creation of a Seam logo, I'm using the following butt-ugly logo in my presentation (found here). Hopefully something better comes along before I deliver my talk tomorrow. ;-)

Seam Logo

Update: Monday's post started an interesting thread on Stripes' mailing list. Also, I really like Spring MVC's new annotation support. It'd be nice to see it go a step further and use defaults (like ControllerClassNameHandlerMapping + subpackage support) and only require annotations to override the defaults. IMO, Stripes, Spring MVC and Struts 2 are all excellent choices if a request-based framework provides the best architecture for your application.

Update 2: Comparing Flex, Grails, GWT, Seam, Struts 2 and Wicket seems to gave gained a lot of interest (and support) in the blogosphere. Because of this, I'm considering submitting it as a JavaOne talk. If I were to do this, how would you like to see this presentation changed and improved?

Update 3: I received the following Seam logo via e-mail. Thanks Christian!

Seam Logo

Update 4: I've updated the Dice.com graph to include "Java" with every search term. To understand the comments on this entry, you might want to view the previous graph.

Update 5: This presentation was posted to the Wicket User mailing list. I followed up asking users to post the pros and cons of Wicket. Now there's a lengthy thread on Wicket's Pros and Cons. Good stuff.

Posted in Java at Nov 14 2007, 03:14:53 PM MST 39 Comments

Comparing Web Frameworks: Time for a Change?

I first came up with the idea to do a "Comparing Web Frameworks" talk in 2004. I submitted a talk to ApacheCon and it got accepted. From there, I outlined, created sample apps and practiced this talk before ApacheCon. Believe it or not, that was my first time speaking in front of a large audience.

Historical note: October 2004 was a pretty cool month - I discovered Rails and Roller had a 1.0 release candidate.

When I created the presentation, it was in large part due to all the WebWork and Tapestry folks harassing me on this very blog. I started using Struts in June 2001 (the same month 1.0 was released) and had used it successfully on many projects. Part of the reason this blog became so popular was I posted lots of tips and tricks that I learned about Struts (and its related project) while using it. After a while, the noise became too heavy to ignore it - especially after I'd tried Spring MVC. So in an effort to learn more about the the other frameworks, I submitted a talk and forced myself to learn them. It seems to have worked out pretty well.

With that being said, I think it's time for a change. The reason I originally wrote this was to educate developers on how the top Java web frameworks differed and encourage developers to try more than one. A while later, I realized there's different tools for different jobs and it's not a one-size-fits-all web framework world. It's not a component vs. request-based framework world either. There's lots of options now. When I've delivered this talk earlier this year, I've always felt like I've left quite a few frameworks out. The solution could be to add more and more frameworks. However, I don't think that's a good idea. The talk is already difficult to squeeze into 90 minutes and it's unlikely that adding more frameworks is going to help.

The change I'd like to do is to reduce the number of frameworks down to (what I consider) the top web frameworks for deploying to the JVM. What are those frameworks? IMHO, they are as follows, in no particular order:

  • GWT-Ext
  • Wicket
  • Grails
  • Flex/OpenLaszlo
  • Seam
  • Struts 2

The RIFE, Tapestry and ZK folks can start bitching now. Sorry - less frameworks make for a more interesting talk. Maybe I'll add you in the future and I can ask the audience which ones they want compared then we can choose four and go from there. Why don't I mention Spring MVC? Because I think Struts 2 is easier to learn and be productive with and I also like it's more open and active community. I've written applications with both and I like Struts 2 better. As for Flex vs. OpenLaszlo, I'm somewhat torn. It seems like learning Flex is going to be better for your career, but it's likely useless without the Flex Builder - which is not open source. However, at $250, it's likely worth its price. I know the Picnik folks used Flex for their UI - I wonder how much they used Flex Builder in the process?

What do you think? Are these the top web frameworks for JVM deployment today? The next time I give this talk is this Thursday at ApacheCon. I may try to re-write my talk and then give the audience a choice of old vs. new. The downside of doing the new talk is I won't have time to write apps with GWT, Flex or Seam. Anyone care to post their top three pros and cons for any of these frameworks?

Posted in Java at Nov 12 2007, 04:46:56 PM MST 50 Comments

SOFEA: Also known as SOUI

InfoQ asks Does the rise of Service Oriented UI (SOUI) means the death of server-assisted MVC? A similar thread was started on JavaLobby last week: Web frameworks peaking toward obsolescence. A month ago, TSS posted a whitepaper titled Life above the Service Tier.

As far as I can tell, Nolan Wright and Jeff Haynie haven't read the Life above the Service Tier article - where the very same architecture is called SOFEA. Nolan and Jeff are calling it SOUI. Is there a difference that you can see? I don't think there is. However, I do think there's a better acronym out there that could spark more interest in this type of architecture. After all, isn't the tipping point often triggered by good timing and clever marketing?

As I mentioned previously, I really like the ideas behind SOFEA/SOUI. However, I don't think it will replace the existing frameworks we use to develop web applications. Those have been very successful and will continue to be. The internet is growing - there's lots of room for new applications developed with new architectures. As long as this new architecture is scalable and maintainable, I can't think of a good reason why it won't succeed.

Posted in Java at Nov 12 2007, 10:36:41 AM MST 15 Comments

Upgrading AppFuse to Spring 2.5

Last night, I spent a few minutes upgrading AppFuse to Spring 2.5 RC1. According to InfoQ, Spring 2.5 is a drop-in upgrade for Spring 2.0. However, if you're using Maven, it's not quite that easy. The good news is it is easy, you just need to change your pom.xml a bit. The steps I used to upgrade AppFuse are listed below:

  • Add a repository for Spring's milestone releases:
    <repository>
        <id>spring-milestone</id>
        <url>http://s3.amazonaws.com/maven.springframework.org/milestone</url>
    </repository>
    
  • Change artifactId of "spring-mock" to be "spring-test".
  • Change version to be 2.5-rc1.

At this point, if you're using "spring" as your artifactId (instead of the smaller fine-grained dependencies), you'll likely get the following error in a Spring MVC application:

java.lang.NoClassDefFoundError: 
org/springframework/web/servlet/handler/AbstractUrlHandlerMapping

This happens because Spring MVC is no longer included in the uber spring.jar. You'll need to add a dependency on "spring-webmvc" to solve this problem. Unfortunately, this JAR is dependent on the fine-grained modules, so you may have to modify your pom.xml to depend on the fine-grained modules - or exclude them all from spring-webmvc.

The good news is Spring has excluded all the invalid commons-logging dependencies for you so you don't have to anymore.

After getting all the dependencies straightened out - I ran the integration tests:

org.springframework.beans.NotReadablePropertyException: Invalid property 
'fileUpload' of bean class [org.appfuse.webapp.controller.FileUpload]: Bean 
property 'fileUpload' is not readable or has an invalid getter method: Does the 
return type of the getter match the parameter type of the setter?

Looking at uploadForm.jsp, I'm guessing the problem happens because of the following code:

<spring:bind path="fileUpload.file">
<input type="file" name="file" id="file" class="file medium" value="<c:out value="${status.value}"/>"/>
</spring:bind>

Confirmed - changing the "path" attribute to "file" fixes the problem. I also found out that setting the "value" on an <input type="file"> doesn't work, so wrapping the field with <spring:bind> doesn't make a whole lot of sense anyway.

To conclude, it doesn't look like the first release candidate of Spring 2.5 is exactly a drop-in upgrade for Spring 2.0, but it's pretty darn close. I'm sure by the time it's released, it will be. I'd encourage you to try 2.5 in your Spring-dependent projects to see if you find any issues.

Update: I was successfully able to migrate AppFuse from using the uber JAR to fine-grained JARs. However, I ran into a couple issues in the process. The first is that even though I'm including spring-aop in the appfuse-service module, it's not pulled in for the web frameworks (which depend on appfuse-service). Explicitly declaring spring-aop as a dependency for the appfuse-web module fixes this. Secondly, I had to modify my Acegi Security exclusions so it wouldn't include dependencies that no longer exist in 2.5.

<dependency>
    <groupId>org.acegisecurity</groupId>
    <artifactId>acegi-security-tiger</artifactId>
    <version>${acegi.version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-dao</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-remoting</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-support</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Posted in Java at Nov 07 2007, 08:27:20 AM MST 3 Comments