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.
You searched this site for "form". 326 entries found.

You can also try this same search on Google.

Appcelerator with Matt Quinlan

This evening I attended the Denver Open Source User Group meeting where the Basic Concepts talk was on Appcelerator. Matt Quinlan (Twitter, Blog, LinkedIn) was the presenter. I arrived 10 minutes late, so I didn't hear any of the intro stuff. Below are my notes from the event.

The Appcelerator developers liked the "onclick" syntax, but found it was too limited to do everything they wanted. Rather than onclick, they use an on attribute. For example:

<div on="click then l:show.box">
Click me
<div>

"DOM Manipulation is JavaScript cruft."

Appcelerator allows you to implement the Observer pattern in the browser. In addition to allowing DOM elements to subscribe to messages, server-side objects (in any language) can subscribe as well. In Appcelerator syntax "l:" means local and "r:" means remote. The messages that are passed to the server are JSON and have payloads. JSON is more popular than XML because you can eval() it and create JavaScript objects from it. Appcelerator allows you to do Declarative Ajax. On the server-side, you can annotation Java and C# classes with @Service to subscribe to messages. In other languages (i.e. PHP), Javadoc-style comments are used.

Tagline: The seamless fusion of RIA and SOA.

Web Expression Language
Goal is to eliminate 90% of the JavaScript you write. Example syntax:

on="[condition] then [action]"

Conditions include DOM events (click, focus, blur, change, mouse events), key events (up, down, press), other (history, drag/drop, selected, resize, iPhone orient, sortXYZ), subscribe to custom message. Actions include Scriptaculous effects (show/hide, fade, move, drop, grow), set element value (static, dynamic, bind), set CSS class or attribute, execute custom JavaScript, publish custom message.

Now Matt is doing a demo on http://try.appcelerator.org. This site consists of a form that allows you to type in Appcelerator code and run it. 3 attributes can be added to any tag: draggable, droppable and resizeable.

Client-Side
Add simple tags to your HTML to inject RIA widgets. Add single property to existing HTML elements for dynamic behavior. Eclipse Plugin built on Aptana, but is generally targeted towards web developers moreso than business analysts (no drag and drop of widgets).

Server-Side
Server-side development done with your IDE of choices. Based on your server-side tehchnology platform. Easily create services using annotations.

App Command
The app command is similar to Rails' GEM command. Allows you to build scaffolding and deploy to cloud (AppEngine, Amazon S3). It also allows you to pulldown components from the main server and auto-updating.

Examples:

Appcelerator allows you to create prototypes easily by using a JavaScript file with mocks for the server-side objects. In the next version, you can "annotate" the UI and allow end-users to Ctrl+Click on elements and add feedback. For an example of this, see http://dev.appcelerator.com/pearson.

When starting with Appcelerator, you can start by crawling (including appcelerator.js for widgets) then move to walking (decouple server-side and client-side) and finally running (developing working prototypes with mocks for server-side).

"Let's face it, ASP, JSP, PHP and Ruby are just lipstick on CGI."

Posted in Open Source at Oct 07 2008, 07:08:19 PM MDT 5 Comments

Ajaxified Body

I've often wondered if it was possible to use Ajax to reload the main content of a web application without reloading the header, menu and footer. SiteMesh allows you to move these common elements to a decorator that gets wrapped around each page. Below is a diagram of how SiteMesh works.

SiteMesh

You can read the Introduction to SiteMesh article if you're interested in learning more about SiteMesh's basic features. By default, SiteMesh decorates text/html responses and ignores any other content type (e.g. image/gif). It also contains an <excludes> configuration element that allows you to turn off decoration when a URL matches a certain pattern. For example, the following allows you to disable decoration when "ajax=true" is passed in the URL.

<excludes>
    <pattern>**ajax=true</pattern>
</excludes>

To optimize the loading of an application so the common elements aren't loaded for each page, it should be possible to create an Ajaxified Body where the primary content area (PCA) of the site is loaded via Ajax rather than refreshing the whole page. The header, footer and navigation bar often stays the same from page-to-page, so it doesn't seem to make a whole lot of sense to load them each time the page loads. The image below shows the PCA (of an AppFuse Light application) as a grey square with a red border.

Ajaxified Body - AppFuse Light

Implementing an Ajaxified Body consists of the following steps:

  1. Adding SiteMesh and moving common elements to a decorator.
  2. Remove common elements from each individual page (if you're using includes).
  3. Configure SiteMesh so decoration is disabled when the requested URL contains "ajax=true".
  4. Write JavaScript that modifies all <a href=""> links (and buttons with onclick='location.href') in the PCA to have an onclick handler.
  5. The onclick handler should call a JavaScript function that loads the link's URL + ajax=true using XMLHttpRequest (XHR).
  6. Add XHR success handling to replace the PCA with the loaded content.
  7. Add XHR error handling to go to the URL normally when response.status != 200.
  8. Inspect the response HTML for <title> element and replace document.title if exists.
  9. Inspect the response HTML for <head> element and append to current if exists.
  10. Inspect the response HTML for <script> and <link> elements (JavaScript and CSS) and evaluate them if they exist.

As a proof of concept, I created a prototype using AppFuse Light (Prototype/Scriptaculous for Ajax). You can see a demo at the following URL. You can also download a patch or the source for this project.

http://demo.raibledesigns.com/ajaxifiedbody

Below are a number of things I discovered while writing this prototype:

  • The hardest part of implementing this seems to be coding the exceptions. It's possible you'll have some links with existing onclick handlers and you may have to disable "ajaxifying links" for those links.
  • A progress indicator is important or the page might load so fast that the user doesn't visually detect it changed. This can lead to a worse user experience because they don't see the flash of the blank page they're used to when a page load occurs.
  • While forms can be submitted via Ajax, there's no harm in leaving existing form behavior in place where the full site is reloaded after submitting a form.
  • If a particular page needs to change the common elements (header, menu, footer), it should be possible to do that with JavaScript after the PCA content loads.
  • If the success/error indicator is outside the PCA, it may need to be populated and displayed/hidden with JavaScript after the PCA loads.

I'm sure my implementation can be improved, but I'm also curious to see what you think of this idea. I know it's not revolutionary, but it's something I'm considering adding by default to AppFuse and AppFuse Light. Do any Ajax frameworks do something like this out-of-the-box?

Update: Thanks to everyone for the great feedback - keep it coming. I agree that adding history support is a must. I'll try to do that in the next day or two. This post has also been featured on Javalobby and Ajaxian.

Update 2: Added history support.

Posted in Java at Oct 03 2008, 02:33:09 PM MDT 19 Comments

[OSCON 2008] An Introduction to Ruby Web Frameworks by Ryan Carmelo Briones

Ryan is a Server Monkey / Code Sumari for Edgecase, LLC in Columbus, Ohio. A framework allows you to create re-usable code. Frameworks allow you to use encapsulation. Frameworks tend to be domain specific. For example, Rails works really for CRUD application, but not for others (i.e. Twitter).

Why Ruby?
Ruby has been Object Oriented since day 1. Ruby promotes Beautiful Code that's easy to read and maintain. Yes, MRI has performance issues. Matz has said "I'm a language designer" and has turned over the VM to others for Ruby 1.9. Another thing that might keep folks from using Ruby or its web frameworks is the libraries available. This is understandable, but it's being solved by alternative implementations. This includes YARV (the official 1.9 implementation), JRuby, IronRuby (not ready for production) and MagLev.

Rack
A framework that provides a minimal API for connecting web services and web frameworks. As a web application developer, this framework allows us to know about web services, but not worry about the details of talking to it. Below is a very simple Rack application.

class HelloWorld
  def call(env)
    [200, {"Content-Type" => "text/plain"}, ["Hello World!"]]
  end
end

Rack allows the handlers do the work and not worry about the web server abstraction. Handlers exist for WEBrick, LightSpeed, Mongrel, Fast-CGI and many others. As an application developer, it allows you to choose different architectures (threaded, evented, etc.). Ryan is talking about Rack first because it's used in all the other Ruby web frameworks.

Ruby on Rails
Rails is 4 years old now and was written by DHH when he was a contractor at 37Signals. Rails doesn't define and grand new ideas, everything has been done before (MVC, code generation, etc.). What Rails did is package everything in a unique way that makes it very easy to use. Rails has influenced a lot of what has come from web frameworks in the last few years. One of Rails' nicest feature is code generation. Ryan showed part of DHH's Create a weblog in 15 minutes video to demonstrate code generation. He noted that the minute he showed was picked because David said "Whoops!" and "Look at all the things I'm not doing". Rails popularized Convention over Configuration using naming conventions and load paths. While this is definitely a cool feature, I think most web frameworks have adopted CoC by now. Maybe not JSF, but who wants to use JSF w/o a framework on top of it anyway?

One warning about Rails: "The Golden Path" can get in your way. Rails is very Opinionated Software and that's how Rails works. As long as you follow that, you should be very productivity. If you decide to go off the Rails (i.e. namespaces), it can be difficult.

Rails uses a DSL in its models (i.e. has_many, has_one for relationships) and in the Rails router. It allows you to very simply map a URL to a controller/method. In addition to DSLs, Rails has first-class testing and its generators create stub tests for you.

Bad things about Rails: too much magic, moves to fast (too many releases).

Merb
Merb was originally developed by Ezra Zygmuntowicz to run alongside a Rails app to handle file uploads. It grew from there and became it's own beast. Merb is very much about using only what you need. It has "package repos" that allow you to add additional features. For example, merb-core doesn't contain an ORM framework, just a web framework. Merb also allows you to choose your ORM. It's standardized on Rack, so it can run on just about any web server. It also included "deferred actions" that allow you to send some URLs to evented web servers and others to threaded web servers. Merb eschews the "magic" that Rails has. It tries to stay away from making it's code a "monument to personal cleverness". Simple code scales better and runs faster.

One of the downers to Merb is that it's flexibility allows you to get down to the nitty gritty. However, it can be less productive than Rails because of its flexibility. Another downside is its documentation and examples are sparse. Merb is not recommended if you're just getting into Ruby.

Camping
Camping is a micro framework (< 4K) developed by why the lucky stiff. It's designed to develop small applications. You can do everything in one file and create prototypes very quickly. It uses Markaby to write HTML code in a builder-style fashion.

Since a Camping application is all in one file, it can be difficult to develop large applications. The solution is to write small apps and mount them in the same URL space. The only issue with small apps sharing the same space is they have to use the same database. One downside to Camping is there is no standard test framework. Mosquito was developed as a solution, but doesn't seem to be maintained.

Sinatra
Simple. Fast. Effective. It's designed to allow creating REST applications with minimal dependencies. Similar to Camping, it has one file for the entire application. Unlike Camping, Sinatra doesn't follow MVC conventions, so it may be difficult to port a Sinatra application to another framework.

Posted in Open Source at Jul 23 2008, 12:33:08 PM MDT 1 Comment

The Father's Day Camping Trip

This past weekend, I started a new tradition: taking my kids camping for Father's Day. Since I wasn't sure of the best place to go, I asked Do you know of some good camping spots for kids in Colorado? I received some good responses, but waited until the "day of" to decide where we should go. Bad idea.

I decided on Peaceful Valley since they didn't seem to require reservations and it wasn't too far. The kids and I left town around 1:30 and arrived at the campground (North West of Boulder) around 3:00. It was packed and there were no spots available. After driving around for another hour, I realized I might end up on the FAIL Blog for being the Dad who couldn't find a camping spot and had to spend the night in a motel. I don't know if it's because I grew up in Montana and we never had to reserve campsites or if it's because there's a lot more people in Colorado than I realized. Regardless, I believe I learned my lesson when it comes to campsite reservations.

The Tent After stopping in Nederland and asking for good camping spots at a gas station, we proceeded to drive around for another hour trying to find the perfect site. Finally, at around 5:30, we found a site in the high mountains near the Eldora Ski Resort. It was along the road, had a river nearby and included a family/friends/kids troupe of 15 w/in 100 yards.

We settled in by setting up the tent, starting a campfire and beginning a search for bears (kids' idea). We never found any bears, but we had a lot of fun exploring. I knew my mission had succeeded when Abbie said to me, "Daddy, I love camping." As it got dark, we put the fire out and climbed into the tent and our sleeping bags. Being that there was still snow near our campsite, I was a little worried about the kids getting cold - especially since their sleeping bags are only rated to 35°F.

As we were getting ready for bed, my car suddenly roared to life. Yikes, WTF?! Then I remembered the remote start I had installed after Snow White got molested. I scrambled for my keys, found them under my knee and quickly turned off the car. After telling some stories, we all fell asleep 20 minutes later.

In the middle of the night, Jack woke up every 10 minutes for a couple hours. He'd crawl out of his sleeping bag and then claim to be cold. I'd talk him back into his bag where he'd warm up and fall asleep. Abbie slept all night and never woke up. At around midnight, my car again roared to life. Since my keys were hanging on the tent wall, I was quite surprised. I scrambled to find my keys in the dark and turned it off again. This happened every 3 hours throughout the night. I'm sure the neighbors loved it considering I have some fancy glasspack exhaust system that makes it pretty loud when it starts. I'd be interested to know if this "start every 3 hours" phenomenon happens every night. Maybe that's the reason my tank is always empty. ;-)

The good news is Snow White never woke the kids up, so they seemingly got a good night's sleep. There was frost on the ground when we woke up the next morning, so it did get cold. However, when the sun hit us at 8:45 in the morning, the temperature rose from 40°F to 60°F in a matter of minutes.

The next morning as I was packing things up and the kids were running around, Abbie came up to me. She asked, "Daddy, when can we go camping again? I had so much fun!" I told her she was in luck - our next camping trip is only a couple weeks away. My dad is flying in next weekend and we're doing the annual 4th of July trek to The Cabin. On the way up, we'll be camping in Yellowstone Park. I can't wait, but I should probably start working on that reservation.

Have you taken your kids camping this year?

Posted in General at Jun 19 2008, 08:43:00 AM MDT 4 Comments

Running Spring MVC Web Applications in OSGi

For the past couple of weeks, I've been developing a web application that deploys into an OSGi container (Equinox) and uses Spring DM's Spring MVC support. The first thing I discovered was that Spring MVC's annotations weren't supported in the M1 release. This was apparently caused by a bug in Spring 2.5.3 and not Spring DM. Since Spring DM 1.1.0 M2 was released with Spring 2.5.4 today, I believe this is fixed now.

The story below is about my experience getting a Spring MVC application up and running in Equinox 3.2.2, Jetty 6.1.9 and Spring DM 1.1.0 M2 SNAPSHOT (from last week). If you want to read more about why Spring MVC + OSGi is cool, see Costin Leau's Web Applications and OSGi article.

To get a simple "Hello World" Spring MVC application working in OSGi is pretty easy. The hard part is setting up a container with all the Spring and Jetty bundles installed and started. I imagine SSAP might solve this. Luckily for me, this was done by another member of my team.

After you've done this, it's simply a matter of creating a MANIFEST.MF for your WAR that contains the proper information for OSGi to recognize. Below is the one that I used when I first tried to get my application working.

Manifest-Version: 1
Bundle-ManifestVersion: 2
Spring-DM-Version: 1.1.0-m2-SNAPSHOT
Spring-Version: 2.5.2
Bundle-Name: Simple OSGi War
Bundle-SymbolicName: myapp
Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/freemarker-2.3.12.jar,
 WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar,
 WEB-INF/lib/spring-beans-2.5.2.jar,WEB-INF/lib/spring-context-2.5.2.jar,
 WEB-INF/lib/spring-context-support-2.5.2.jar,WEB-INF/lib/spring-core-2.5.2.jar,
 WEB-INF/lib/spring-web-2.5.2.jar,WEB-INF/lib/spring-webmvc-2.5.2.jar 
Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
 javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
 org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional

Ideally, you could generate this MANIFEST.MF using the maven-bundle-plugin. However, it doesn't support WARs in its 1.4.0 release.

You can see this is an application that uses Spring MVC, FreeMarker, SiteMesh and the URLRewriteFilter. You should be able to download it, unzip it, run "mvn package" and install it into Equinox using "install file://<path to war>".

That's all fine and dandy, but doesn't give you any benefits of OSGi. This setup works great until you try to import OSGi services using a context file with an <osgi:reference> element. After adding such a reference, it's likely you'll get the following error:

SEVERE: Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Unable to locate Spring NamespaceHandler for
XML schema namespace [http://www.springframework.org/schema/osgi]

To fix this, add the following to your web.xml (if you're using ContextLoaderListener, as an <init-parameter> on DispatcherServlet if you're not):

  <context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
  </context-param>

After doing this, you might get the following error on startup:

SEVERE: Context initialization failed
org.springframework.context.ApplicationContextException: Custom
context class [org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext]
is not of type [org.springframework.web.context.ConfigurableWebApplicationContext] 

To fix this, I change from referencing the Spring JARs in WEB-INF/lib to importing the packages for Spring (which were already installed in my Equinox container).

Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/freemarker-2.3.12.jar,
 WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar
Import-Package:
javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
 javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
 org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional,
 org.springframework.osgi.web.context.support,
 org.springframework.context.support,
 org.springframework.web.context,
 org.springframework.web.context.support,
 org.springframework.web.servlet,
 org.springframework.web.servlet.mvc,
 org.springframework.web.servlet.mvc.support,
 org.springframework.web.servlet.view,
 org.springframework.ui,
 org.springframework.web.servlet.view.freemarker 

After rebuilding my WAR and reloading the bundle in Equinox, I was confronted with the following error message:

SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'freemarkerConfig' defined in ServletContext
resource [/WEB-INF/myapp-servlet.xml]: Instantiation of bean failed;
nested exception is java.lang.NoClassDefFoundError:
freemarker/cache/TemplateLoader
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:851) 

As far as I can tell, this is because the version of Spring MVC installed in Equinox cannot resolve the FreeMarker JAR in my WEB-INF/lib directory.

To prove I wasn't going insane, I commented out my "freemarkerConfig" and "viewResolver" beans in myapp-servlet.xml and changed to a regular ol' InternalResourceViewResolver:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
</bean>

This worked and I was able to successfully see "Hello World" from a JSP in my browser. FreeMarker/SiteMesh worked too, but FreeMarker didn't work as a View for Spring MVC.

To attempt to solve this, I create a bundle for FreeMarker using "java -jar bnd-0.0.249.jar wrap freemarker-2.3.12.jar" and installed it in Equinox. I then change my MANIFEST.MF to use FreeMarker imports instead of referencing the JAR in WEB-INF/lib.

Bundle-Classpath:
.,WEB-INF/classes,WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar
Import-Package:
javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
 javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
 org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional,
 org.springframework.osgi.web.context.support,
 org.springframework.context.support,
 org.springframework.web.context,
 org.springframework.web.context.support,
 org.springframework.web.servlet,
 org.springframework.web.servlet.mvc,
 org.springframework.web.servlet.mvc.support,
 org.springframework.web.servlet.view,
 org.springframework.ui,
 org.springframework.web.servlet.view.freemarker,
 freemarker.cache,freemarker.core,freemarker.template,freemarker.ext.servlet 

Unfortunately, this still doesn't work and I still haven't been able to get FreeMarker to work with Spring MVC in OSGi. The crazy thing is I actually solved this at one point a week ago. Shortly after, I rebuilt Equinox from scratch and I'm been banging my head against the wall over this issue ever since. Last week, I entered an issue in Spring's JIRA, but thought I'd fixed it a few hours later.

I've uploaded the final project that's not working to the following URL:

http://static.raibledesigns.com/downloads/myapp-osgi.zip

If you'd like to see this project work with Spring MVC + JSP, simply modify myapp-servlet.xml to remove the FreeMarker references and use the InternalResourceViewResolver instead.

I hope Spring DM + Spring MVC supports more than just JSP as a view technology. I hope I can't get FreeMarker working because of some oversight on my part. If you have a Spring DM + Spring MVC application working with Velocity or FreeMarker, I'd love to hear about it.

Posted in Java at Apr 30 2008, 12:42:34 AM MDT 14 Comments

Apache 2 on OS X: Configuring mod_proxy and SSL

I recently had to setup Apache as a front-end web server for multiple backend servlet containers. The backend containers serve up different web applications, and the Apache front-end unites them from a hostname and port standpoint. The following instructions describe how to configure Apache 2 on Mac OS X to proxy requests to Tomcat or Jetty running on localhost:8080. It also shows how to enable SSL on Apache and force it for certain URLs in your Java web application.

Apache comes pre-installed on OS X, so you should be able to start it by enabling "Web Sharing" in System Preferences > Sharing.

$APACHE_HOME on Leopard is /etc/apache2. On Tiger, it's /etc/httpd. If you've upgraded Tiger to Leopard, it's likely you'll have both directories so make sure you're modifying the right one. I lost a few hours figuring this out, so hopefully this knowledge will appease some googler in the future.

Configuring mod_proxy

  1. Open $APACHE_HOME/httpd.conf and add the following on line 480 - at the very bottom, just before "Include /private/etc/apache2/other/*.conf".
    #
    # Proxy Server directives. 
    #
    <IfModule mod_proxy.c>
        ProxyRequests On
        ProxyPreserveHost On
    
        ProxyStatus On
        <Location /status>
            SetHandler server-status
    
            Order Deny,Allow
            Deny from all
            Allow from 127.0.0.1
        </Location>
    
        ProxyPass    /myapp    http://localhost:8080/myapp
    </IfModule>

    ProxyPreserveHost allows request.getServerName() and request.getServerPort() to work as if there is no proxy server in place. In other words, even though Tomcat is running on 8080, request.getServerPort() will return 80.

  2. The most important line is the last one as this is the dictates the location of your applications. Add more lines as you need to add more applications.
  3. If everything is configured correctly, you should be able to run sudo apachectl restart and navigate to http://localhost/status. If you receive a "forbidden" error, make sure your /etc/hosts has an entry mapping 127.0.0.1 to localhost (as one of the last entries), or change "Allow from 127.0.0.1" to "Allow from localhost". If you get a "Server not found" error, you can tail the error log at "/var/log/apache2/error_log".

One issue I've seen with mod_proxy is when a request comes in and the backend server is down. When this happens, Apache returns a 503 Service Temporarily Unavailable and it doesn't seem to go away after the backend server is restarted. It does resume proxying after a while, but I haven't determined what causes the proxy to come back to life. If you know a setting that forces mod_proxy to check for the backend server on every request, please let me know.

Configuring SSL

  1. Open $APACHE_HOME/httpd.conf and uncomment the following on line 470:
    Include /private/etc/apache2/extra/httpd-ssl.conf
  2. Open $APACHE_HOME/extra/httpd-ssl.conf and change line 78 to:
    ServerName localhost:443
  3. In httpd-ssl.conf, change line 99 to:
    SSLCertificateFile "/private/etc/apache2/ssl.key/server.crt"
  4. In httpd-ssl.conf, change line 107 to:
    SSLCertificateKeyFile "/private/etc/apache2/ssl.key/server.key"
  5. In httpd-ssl.conf, add the following after SSLEngine on to allow proxying via HTTPS:
    SSLProxyEngine on
  6. Follow the Using mod_ssl on Mac OS X tutorial. For "Common Name/Server Name", use "localhost". You can download the source for mod_ssl (which you need at one point during the tutorial) at http://www.modssl.org/source/.
  7. Run sudo apachectl restart and go to https://localhost. If you get a "Server not found" error, run sudo apachectl -t to verify the syntax of your config files or tail -f /var/log/apache2/error_log to verify there are no errors in the log files.

Forcing HTTPS for certain URLs
If you proxy requests from /myapp -> http://localhost:8080/myapp, request.isSecure() will return false. If you change it to /myapp -> https://localhost:8443/myapp, request.isSecure() will return true. I needed to figure out a way to have http://localhost/myapp go to http://localhost:8080/myapp and https://localhost/myapp to go http://localhost:8443/myapp. Even better, I wanted to configure things in a way so request.isSecure() returned the value based on the originally requested URL, not on the proxied URL. Configuration like the following would be ideal:

ProxyPass    http://*/myapp    http://*:8080/myapp
ProxyPass    https://*/myapp   https://*:8443/myapp

The solution I came up with is to standardize on secure URLs in my application. That is, use /secure/* as a prefix for all URLs that should be accessed via SSL. To follow this convention and force it, I added the following in my application's web.xml file:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Secure Area</web-resource-name>
    <url-pattern>/secure/*</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>

Once this is in place, accessing http://localhost/myapp/secure/index.html will result in an error. Accessing it using https will succeed. Following this, you can change your ProxyPass rules to the following and all requests to /secure/* will be https; other requests will be sent to http. The order of the rules below is important.

ProxyPass    /myapp/secure   https://localhost:8443/myapp/secure
ProxyPass    /myapp          http://localhost:8080/myapp

If this isn't a good strategy for you, Tomcat has the ability to use a redirectPort (in server.xml) that auto-redirects from http to https when CONFIDENTIAL is used in web.xml. I'm not sure if this redirect will carry through values from a form post.

Posted in Open Source at Apr 24 2008, 10:58:03 AM MDT 8 Comments

Upgrading to Spring Security 2.0

This evening I spent a few hours and upgraded AppFuse to use Acegi Spring Security 2.0. The upgrade was fairly straightforward:

  • %s/org.acegisecurity/org.springframework.security/g
  • Upgraded dependencies (exclusions are necessary if you're using Spring 2.5.x and don't want 2.0.x dependencies pulled in):
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core-tiger</artifactId>
        <version>${spring.security.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-support</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    ...
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>${spring.security.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  • Changed taglib prefix from "authz" to "security" and change the associated taglib declaration to:
    <%@ taglib uri="http://www.springframework.org/security/tags" 
        prefix="security" %>
    
  • In web.xml, I changed <filter-class> to org.springframework.web.filter.DelegatingFilterProxy. Since I didn't name my filter springSecurityFilterChain, I also had to add the following <init-param>:
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>springSecurityFilterChain</param-value>
        </init-param>
    
  • Lastly, I modified security.xml to use the new syntax. AppFuse's security.xml went from 175 lines to 33 with the new security namespace configuration!

It's hard to believe I first looked at Acegi almost 4 years ago. At that time, I said it contained too much XML for my needs. Ben's reaction:

Seriously, the "whole lotta XML" gives you exponentially more power and flexibility than a method such as this could ever hope to provide you.

It's nice to see that Spring Security 2.0 gives you exponentially more power and flexibility without all the XML. Thanks guys!

P.S. You can also view the full changelog for this upgrade.

Update: If you're using <authz:authentication property="fullName"/> in your JSPs, you'll need to change it to <security:authentication property="principal.fullName"/>.

Posted in Java at Apr 17 2008, 02:45:47 AM MDT 19 Comments

Spring MVC's Conventions get even better

Spring 2.5.3 was released this morning and contains a new feature I really like. When I first started working with Spring MVC's annotations (way back in November of last year), I found it awkward that I had to hard-code the URLs for my controllers into @RequestMappings on methods. Previous to annotations, I was using Spring's ControllerClassNameHandlerMapping which allows for more conventions-based URL-mappings.

With 2.5.3, @Controller and ControllerClassNameHandlerMapping have been synced up so you don't have to specify URLs in your annotations anymore. Thanks guys!

Posted in Java at Apr 07 2008, 09:43:42 AM MDT 4 Comments

TSSJS Vegas Begins

This morning, I woke up early and headed down to the opening ceremonies for TheServerSide Java Symposium in Vegas. Joseph Ottinger and Eugene Ciurana kicked off the show and welcomed the seemingly large audience of Java Developers. After the introduction, Neal Ford delivered a keynote titled Language-Oriented Programming: Shifting Paradigms. You can download Neal's presentation from the TSSJS Wiki (requires creating an account).

I started live-blogging Neal's keynote, but quickly gave up when I realized it was going to be a very good talk and I'd miss the essence of it if I tried to write it down. So I closed my laptop, sat back and enjoyed. Neal is an excellent speaker and did a great job of telling a story of the next evolution in Java Development. First off, he talked about artwork, the Renaissance and the Age of Enlightenment.

The plethora of Frameworks today is similar to the Renaissance (where everyone painted Madonna and Child) in that they're all very similar, and most of them are configured with XML. XML is the external DSL that configures the framework and its needed to allow late-binding and flexibility. The reason folks use XML is because of Java's limitations as a language. There are better mechanisms (languages) to construct this DSL. He gave examples using Ruby and Groovy. Furthering the notion of DSLs are Language Workbenches that allow programmers to write DSLs that are IDE-aware, so tools like IntelliJ IDE can offer code completion and such. If DSLs are the next evolution of programming, then tools like IntelliJ's MPS (to be open sourced before year end) are going to become very important.

I think one of the most important things I took away was that the building blocks for the next generation of development is already there. Neal referenced Ola Bini and his idea of the Polygot Language Platform. He showed the following image of what the Polygot Platform might look like, where the Stable Layer is written in Java, it has a low-ceremony/dynamic language on top of it, and then a DSL that pertains to the particular application. If we start developing using this type of platform, we'll quickly move into our own Age of Enlightenment - where we're still using all the frameworks, we're just putting a prettier face (DSL) on them.

Ola's Layers

This was a very good talk that I enjoyed immensely. I'm glad I sat back and listened instead of typing like mad.

After Neal's Keynote, I went to Brian Goetz's talk on Java Performance Myths. In this session, Brian talked about how object allocation is no longer slow, benchmark frameworks are often flawed, (uncontended) synchronization is not slow and a couple other things. The room was packed and 10-20 people ended up standing up in the back. I didn't learn anything revolutionary as this talk seemed to be written a couple of years ago.

Following Java Performance Myths, I headed to my room to get some work done. On the way, I discovered the "gas is out" at the Venetian and it's recommended folks go across the street to eat lunch and such. I'm about to head back to the conference to grab some grub - it'll be interesting to see if this situation has caused any lunch chaos.

Posted in Java at Mar 26 2008, 02:06:11 PM MDT 2 Comments

Proposal accepted for OSCON 2008

OSCON 2008 From an e-mail I received earlier this afternoon:

We are pleased to accept the following proposal for OSCON 2008.

* Web Frameworks of the Future: Flex, GWT, Grails and Rails

It has been scheduled for 16:30 on 23 Jul 2008.

My Abstract:

What if the choices in web framework was reduced to 4? If RIA are the way of the future, it's possible that these 4 frameworks are the best choices for this development paradigm. This session will explore these frameworks, as well as entertain many other's opinions on the future of web development.

RESTful backends are easy to create with both Rails and Grails. Ajax frontends are simple to create and maintain with GWT. Flex gives you flash and a pretty UI. If you're an HTML developer, Rails allows you to quickly develop MVC applications. If you're a Java Developer, GWT + Grails might be a match made in heaven. This session is designed to help you learn more about each framework and decide which combination is best for your project.

I'm really looking forward to learning about GWT and Flex in the coming months. If you have any experience (or opinions) about the abstract above, I'd love to hear it. The louder the better.

For those who haven't been, OSCON is one of those truly special conferences. Possible reasons:

I'm going for all 4 reasons and even made a reservation to stay at The Kennedy School. Should be a fun show.

Posted in Open Source at Mar 17 2008, 07:21:10 PM MDT 9 Comments