Matt RaibleMatt Raible is a writer with a passion for software. 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 "young russian teenboy model pre teen". 788 entries found.

You can also try this same search on Google.

[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

[OSCON 2008] The Keynote

This morning, I woke up awful early to polish my presentation, walked to the train station and rode Amtrak from Salem to Portland. The commute was great: there's nothing better than traveling with power and an EVDO card + the option to get a cup of coffee. After getting off the train, riding The Max and walking to the Oregon Convention Center, I'm now sitting in the Keynote at OSCON. Here's my notes from this session.

10 years ago, leaders of the free software movement got together and tried to figure out a way to help people understand how to get access to software freedom. As they talked, there was a gradual meeting of minds. Finally, one person suggested "Open Source". A few weeks later, there was a larger meeting of people and they heard about this term. It was an idea that changed the idea of software freedom and what free software was. We've come along way since then. Last year, we heard about open source and and it trying to find identity in corporations. This year, we're hearing about corporations trying to find their identity in open source.

The official tag for this conference is: oscon08.

Tim O'Reilly
While this is the 10th Anniversary of OSCON, it's also the 12th Anniversary of the O'Reilly Perl Conference (where it all started). Tim began his activism with Perl when it got on the web. He was thinking about the internet and the online world, from the beginning (when many others were coming from Linux). Open Source was almost named "SourceWare". Tim believes his biggest contribution is bringing Open Source and the Internet together.

"Keep your History" - make the things you put online accessible for years to come.

When OSCON first started, it was all about the OS Wars. Tim is showing a shirt with the famous Ghandi quote on it about "First they laugh at you..." and it has a Linux logo on the bottom. It's seems ironic that Microsoft is now one of the major sponsors of this conference (my thoughts, not Tim's).

Open Source Technology in the Enterprise. IT jobs are 2.3% of all jobs posted, according to the Bureau of Labor Statistics. Technology oriented companies (e.g., Google, Yahoo, Sun) make heavy use of Open Source (40% of all jobs posted by Y!). Open source is growing faster in non-tech companies. Of the open source technologies in the enterprise, the highest share of jobs is Linux (19%), followed by Perl, JavaScript and PHP. As far as the fastest growing, Django and Alfresco are at the top.

Three Big Challenges and Opportunities:

  1. Cloud Computing
  2. The (Open) Programmable Web
  3. Open Mobile

Cloud Computing: Amazon Web Services, Google App Engine, The Engine Yard, etc.

Jesse Vincent: "Web 2.0 is Sharecropping"

Danny O'Brien: "If we want people to have the same degree of user autonomy as we’ve come to expect from the world, we may have to sit down and code alternatives to Google Docs, Twitter, and EC3 that can live with us oon the edge, not be run by third parties."

Basically, Tim is saying the that cloud computing is great, but it doesn't fit well with open source. This is primarily because if you build on a cloud, you have to be careful not to get locked into that platform.

Data is the "Intel Inside".

The Web is the Internet Operating System - the subsystems will be data subsystems.

Locking in data: iTunes and Amazon's Kindle. On the other hand you have Yahoo's BOSS, which is doing the opposite.

We Need the Open Web Platform! Tomorrow's Keynote, "Supporting the Open Web" will talk much more about this.

The Mobile Web has caused the "browser wars" to resurface. However, big companies like Google are putting a stake in the ground and saying "We believe in open". Net Neutrality and The Open Handset Alliance are two of Google's smartest strategic decisions. They understand how much they depend on the open ecosystem.

When we look at our success in the last 10 years, we can be really excited. But what's really impressive is how much we (as an open source community) is how we've risen to new challenges and challenged the openness of new platforms and industries.

Christine Peterson
Christine is the President of the the Foresight Institute. Christine was the person who suggested the term "open source" at the meeting referenced above. Unfortunately, my first battery died as Christine was coming on stage, so I missed writing down the first 10 minutes of her 15 minute talk. She's talking about the openness vs. privacy of keeping US citizens safe. She started her talk apologizing for the ethnocentricity of her talk and moved to quickly note that the e-voting controversy wouldn't have happened if open source software was used.

"Who would have guessed that the folks with the pocket protectors would turn out to be the ones with the right stuff?" -- LA Times

Founding Geeks: Thomas Jefferson (mechanical geek) and Thomas Edison (electricity geek).

You can't just complain about things. The fear is real. We can't just complain about how DC is solving problems, we have to step up and solve them ourselves.

"No Secret Software for Public Sensing Data."

Dirk Hohndel
Dirk is the Chief Linux and Open Source Technologist at Intel. He's talking about Moblin: Linux for Next Generation Mobile Internet. This sounds like something that has been talked about a million times before. Why is it interesting today? Because we're at an open source conference and open source is what makes it interesting.

When people look at Intel, they don't think of open source. However, Intel is very involved in open source and uses an open source methodology internally for their development process. They also have one of the largest grids powered by open source (~100K Linux servers).

Moblin is about the internet, about mobility, about flexibility and extensibility. What's happening today is the ideas of 10 years ago have become affordable to produce (for manufacturers) and purchase (for consumers). There's lots of proprietary ways to develop the mobile web, but it needs to be open in order to prevent lock-in (to a platform) and encourage innovation.

A year ago, Intel started Moblin. Initially, there wasn't a lot of interest from open source developers. The majority of interest came from companies, particularly hardware vendors. To Dirk, this was disappointing as he really wanted a community to guide the project and make choices about the platform. There's lots of Open Mobile/Linux efforts out there, but there aren't any that are truly open - with access to the source code and everything else you'd expect from an open source project. Intel was hoping to announce a cutting-edge infrastructure for Moblin here at OSCON, but they're a few weeks behind. They hope to be ready for soon.

"The hope that I have is the community takes this from us. Show us where to go. Show us where not to go. Help us get this right."

Tim O'Reilly interviews Monty Widenius and Brian Aker
Tim asks how it's going 6 months in. Monty responds that he's very happy they didn't have to go public and that Sun is still trying to figure out what they bought. One of the things difficulties they've seen about encouraging Sun's engineers to be involved in open source is some are hesitant about open sourcing their code. The biggest problem is engineers are afraid of the feedback/scrutiny that their code will receive.

MySQL was very unique as a company in that it was a virtual company, with most engineers working out of their homes. MySQL has become an enabling force for moving Sun to a similar model.

Monty is working on Maria (new storage engine) and Brian is working on Drizzle (a slimmer version of MySQL). Drizzle was inspired by a conversation when Brian was talking to Rackspace's CTO.

"Do less and then create extensibility mechanisms." -- Tim O'Reilly

Posted in Open Source at Jul 23 2008, 11:29:21 AM MDT Add a Comment

GWT and REST

I've posted two message to the GWT Google Group in the last couple of days. However, new member messages are moderated and neither has shown up yet. I'm reposting my questions here in hopes of getting some answers.

Is there a way to easily use a REST backend with GWT? I tried GWT-REST. It works, but it seems to be centered towards Rails (I'm using Grails) and it suffers from the SOP issue.

JSONRequest looks promising for cross-domain support, but I can't get it to work either. The provided examples work, but not my simple hello world that returns:

{"response":"Hello World!"}

Also, the example implementation only has GET support, not PUT, DELETE or POST. I can post my REST backend on the public internet if anyone is interested in seeing the issues I'm having.

Thanks in advance for any advice.

Posted in Java at Jul 21 2008, 10:31:58 AM MDT 14 Comments

Good times with kids in Colorado

A friend recently sent me an e-mail asking the following question:

May be coming to Colorado in early August for a good break. Can you share ideas on having good times with kids?

His kids are 3 and 5 years old, the same as Abbie and Jack. Here's my response:

[Read More]

Posted in General at Jun 11 2008, 12:16:22 PM MDT 8 Comments

New Mac Pro

It sure is cool when dreams come true. Look what arrived at the Denver office today. :-)

New Mac Pro

Update: Believe it or not, I rebooted my MacBook Pro the same minute I plugged in my Mac Pro. Upon reboot, the MBP choked and I've been looking at a gray screen with a spinning icon for most of the day. I'm soooo glad I have Time Machine. Let's hope I can do a restore on the MBP tomorrow.

Update 2: I was able to successfully build the Mac Pro from my latest MacBook Pro backup on Time Machine. Sweet! Let's see how this works:

$ echo $JAVA_OPTS
-Xms512M -Xmx4096M -XX:PermSize=384m -XX:MaxPermSize=512m -Djava.awt.headless=true -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled -XX:+UseConcMarkSweepGC -server

Posted in Mac OS X at Jun 05 2008, 11:21:17 AM MDT 13 Comments

Should we change AppFuse to be Struts 2-specific?

Dusty recently posted an interesting idea to the AppFuse developers mailing list:

After thinking/coding/reading for a while I think the more interesting task is: Retool AppFuse to be one or more Struts2 plugins based on various higher level app patterns. (AppFuse Facebook, AppFuse Employee DB, AppFuse Blog, AppFuse Basic LDAP, AppFuse Basic Crowd).

This all comes from the fact, that I have been wanting to refactor the AppFuse web layer for Struts. One of the interesting aspects of AppFuse is that it works pretty much the same across all its web frameworks. It does so with some lowest common denominator abstractions that can be ported and look and work the same across frameworks. I have picked my tool(s): Struts 2 and Ruby On Rails when I want to pretend I am young again. I know Spring MVC, JSF, etc. but I have no desire to build significant apps on those platforms. It's not because they suck and Struts2 rules, it is because I know Struts 2 the best, I am most efficient there and it provides everything I need to build great webapps (Let's not devolve to a framework debate). So, I would rather have a more Struts 2-specific web stack, that really leverages conventions born and raised there. The nice thing about the Struts 2 web stack is that it is complemented nicely by AppFuse's data/service layer, since unlike Grails or Rails, Struts 2 has no data or service layer. [Read More »]

Seems like a good idea to me. What do you think?

Someday I'd like to come up with a "compatibility test" that allows others to improve upon the ideas in AppFuse and develop their stacks independently. A suite of Selenium tests that require extensionless URLs might be a good start.

Posted in Java at May 29 2008, 08:29:44 AM MDT 11 Comments

LinkedIn Groups

LinkedIn This afternoon, I noticed there's a LinkedIn "GlassFish" group now available and it reminded me of a couple things:

  • LinkedIn currently doesn't have a way to search for groups, but Jason Bailes has setup a LinkedIn Groups Search with Google Custom Search. Thanks Jason!
  • I created a Apache Software Foundation group on LinkedIn a few months ago. If you're a committer or member, you're more than welcome to join the group.

LinkedIn Groups don't provide a whole lot of functionality at this point, but I've heard there's big things in store for them. Chances are they'll be very valuable in the future.

Posted in The Web at May 20 2008, 02:16:18 PM MDT 6 Comments

Extensionless URLs with Java Web Frameworks

Last week, I had a go of making a Spring MVC application use extensionless URLs. I did some googling, found some tips on the Spring Forums and believe I arrived at a solid solution. Using the UrlRewriteFilter (version 3), I was able to create a rule that looks for any URLs without an extension. If it finds one, it appends the extension and forwards to the controllers. This rule is as follows (where *.html is my servlet-mapping for DispatcherServlet in web.xml):

  <rule>
    <from>^([^?]*)/([^?/\.]+)(\?.*)?$</from>
    <to last="true">$1/$2.html$3</to>
  </rule>

As long as I hand-write all my URLs without an extension (<a href="home"> vs. <a href="home.html">), this seems to work. To combat developers that use "home.html", one solution is to require all links to be wrapped with <c:url value="url"/> (or some other macro that call response.encodeURL()). If you can convince everyone to do this, you can write an outbound-rule that strips the .html extension from URLs.

  <outbound-rule>
    <from>^(.*)\.html(\?.*)?$</from>
    <to last="false">$1$2</to>
  </outbound-rule>

In an ideal world, it'd be possible to modify the <a> tag at the very core of the view framework you're using to automatically encode the URL of any "href" attributes. I don't think this is possible with JSP, FreeMarker, Facelets or any other Java Web Framework templates (i.e. Tapestry or Wicket). If it is, please let me know.

Below is my final urlrewrite.xml with these rules, as well as my "welcome-file" rule at the top.

<?xml version="1.0" encoding="utf-8"?>
<!DOCENGINE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
  "http://tuckey.org/res/dtds/urlrewrite3.0.dtd">

<urlrewrite>
  <rule>
    <from>/$</from>
    <to type="forward">home</to>
  </rule>

  <rule>
    <from>^([^?]*)/([^?/\.]+)(\?.*)?$</from>
    <to last="true">$1/$2.html$3</to>
  </rule>

  <outbound-rule>
    <from>^(.*)\.html(\?.*)?$</from>
    <to last="false">$1$2</to>
  </outbound-rule>

</urlrewrite>

If you have other solutions for extensionless URLs with Java web frameworks, I'd love to hear about them. With any luck, 2008 will be the year we drop extensions (and path-mappings) from our URLs. The stat packages might not like it, but I do.

Posted in Java at May 13 2008, 09:50:51 PM MDT 18 Comments

Issues with AntRun Plugin and Maven

I started seeing the following error today when using Maven and the AntRun Plugin.

[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error executing ant tasks
	
Embedded error: java.lang.IllegalAccessError: tried to access method 
org.apache.tools.ant.launch.Locator.decodeUri(Ljava/lang/String;)Ljava/lang/String; 
from class org.apache.tools.ant.AntClassLoader

Searching the internet provided no results, so I was pretty stumped - especially since this error didn't happen on my MacBook Pro. It happened on AppFuse's Bamboo server (Linux), but not locally. Luckily, I was able to reproduce it on my Windows box and discovered the solution: upgrade to a newer version of Maven. I was using 2.0.6/2.0.7 and upgrading to 2.0.9 fixed the problem.

BTW, when is the Ant project going to release a new version of Ant? The current 1.7.0 version doesn't support spaces in path names, which seems like a pretty big issue to me (especially for Windows users).

Posted in Java at May 10 2008, 06:23:26 PM MDT 6 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