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 "mvc". 279 entries found.

You can also try this same search on Google.

Enhancing your GWT Application with the UrlRewriteFilter

Last week, I spent some time trying to change the location of my cache/nocache HTML files in my GWT project. I started the project with the gwt-maven-plugin's archetype. The message I posted to the gwt-maven Google Group is below.

Rather than having my application's HTML file in src/main/java/com/mycompany/Application.html, I'd like to move it to src/main/webapp/index.html. I tried copying the HTML and adding the following to my index.html, but no dice:

<meta name="gwt:module" content="com.mycompany.Application"/>

Is this possible with the gwt-maven-plugin? I'd like to have my main HTML and CSS at the root of my application.

The good news is I figured out a solution using the UrlRewriteFilter that 1) allows hosted mode to work as usual and 2) allows your app to be served up from the root URL (/ instead of /com.company.Module/Application.html). Here's the urlrewrite.xml that makes it all possible.

<?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" last="true">/com.mycompany.app.Application/Application.html</to>
    </rule>
    <rule>
        <from>/index.html</from>
        <to type="forward" last="true">/com.mycompany.app.Application/Application.html</to>
    </rule>
    <-- This last rule is necessary for JS and CSS files -->
    <rule>
        <from>^/(.*)\.(.*)$</from>
        <to type="forward">/com.mycompany.app.Application/$1.$2</to>
    </rule>
</urlrewrite>

If you're using the gwt-maven plugin, this file goes in src/main/webapp/WEB-INF. In addition, you'll need to add the following to your web.xml.

    <filter>
        <filter-name>rewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>rewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Finally, add the UrlRewriteFilter dependency in your pom.xml:

    <dependency>
        <groupId>org.tuckey</groupId>
        <artifactId>urlrewritefilter</artifactId>
        <version>3.1.0</version>
    </dependency>

Please let me know if you have any questions.

Update: Jeff posted an alternative configuration that allows you to eliminate the last rule in urlrewrite.xml, as well as use the beloved mvn jetty:run command. To use cleaner WAR packaging and the Jetty plugin, add the following to your pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <webappDirectory>
            ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application
        </webappDirectory>
    </configuration>
</plugin>
<plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>maven-jetty-plugin</artifactId>
    <version>6.1.14</version>
    <configuration>
        <webAppConfig>
            <contextPath>/</contextPath>
            <baseResource implementation="org.mortbay.resource.ResourceCollection">
                <resourcesAsCSV>
                    ${basedir}/src/main/webapp,
                    ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application
                </resourcesAsCSV>
            </baseResource>
        </webAppConfig>
        <scanIntervalSeconds>3</scanIntervalSeconds>
        <scanTargets>
            <scanTarget>${basedir}/src/main/resources</scanTarget>
            <scanTarget>${basedir}/src/main/webapp/WEB-INF</scanTarget>
            <scanTarget>
                ${project.build.directory}/${project.build.finalName}/com.mycompany.app.Application
            </scanTarget>
        </scanTargets>
    </configuration>
</plugin>

Then you can trim your urlrewrite.xml down to:

<urlrewrite>
    <rule>
        <from>^/$</from>
        <to type="forward" last="true">/Application.html</to>
    </rule>
    <rule>
        <from>/index.html</from>
        <to type="forward" last="true">/Application.html</to>
    </rule>
</urlrewrite>

Of course, you could also change the welcome-file in your web.xml or use index.html and the <meta http-equiv="REFRESH"> option. Personally, I have so much affection for the UrlRewriteFilter that I like having it in my project. I'm sure I'll need it someday.

Thanks Jeff!

Posted in Java at Feb 23 2009, 05:02:29 PM MST 13 Comments

Comparing Web Frameworks Book

A publisher recently sent me an e-mail asking some advice. They received a proposal for a book that compares CakePHP, Symfony, Zend, TurboGears, Django, Struts, RoR. Here's a quote from the proposal:

We would like to compare a couple of frameworks and present their advantages and disadvantages in various applications.

Obviously, that kind of manual would be very useful for readers who are starting their 'adventures' with web applications, as it would facilitate their choosing the best framework for their particular application. The manuscript would offer a comparison of the most popular solutions (CakePHP, Symfony, Zend Framework, TurboGears, Django, Struts, Ruby on Rails) and demonstrate the main differences between each.

Therefore, the target audience would mainly be project managers, responsible for deciding on the technologies to be used for in-house projects, as well as less experienced, web application beginners.

Another purpose of the book would be to present 'good practices' in various frameworks, such as code re-factoring, design patterns and application security. From this point of view, it could become a valuable asset for experienced and learner programmers alike.

Since I got a lot of feedback from my tweet on this subject, I figured I'd ask it here.

What do you think of such a book?

Here's my response:

How do PHP books do these days? Of the list of frameworks (CakePHP, Symfony, Zend Framework, TurboGears, Django, Struts, Ruby on Rails), I think there's interest in Django and Rails, but not so much the others. And Struts sucks, so having that as a comparison is obviously going to make it look bad. I wouldn't buy it, but I'm a Java guy that's mostly interested in web frameworks that make developing SOFEA-based applications easier. In my mind, these are Flex and GWT.

The book I'd like to see would cover developing RESTful backends and SOFEA front-ends. RoR, Grails or Django could be used to develop the backend and Flex, GWT and X could be for the front-end. In reality, this is probably a tough book to write b/c things move so fast. If you decide to do it, I'd keep it short and sweet so you can get it to market and update it quickly.

Posted in Java at Feb 23 2009, 09:49:15 AM MST 17 Comments

Testing GWT Applications

Last week, I did some research on GWT, how to test it and code coverage options for tests that extend GWTTestCase. The reason I did this is because I've found that most of the GWT tests I write have to extend GWTTestCase and I'd like to have code coverage reports. Read below for more information on my findings for testing GWT classes.

There are quite a few articles about testing GWT applications. Here are a few samples:

The main gist of these articles is that you should structure your code to make the core functionality of your application testable without having to depend on GWTTestCase.

All of them also advocate using an MVC or MVP (Model View Presenter) pattern. Currently, I'm using GXT and its MVC Framework. Unfortunately, GXT's MVC doesn't have much documentation. The good news is there is a good article that explained enough that I was able to refactor my project to use it.

The unfortunate side of this refactoring was I discovered that classes that extend GXT's MVC Framework have to be tested with GWTTestCase. The downside to extending GWTTestCase is there is it's difficult to create code coverage reports.

GWT's issue 799 has some patches that should make code coverage possible. I tried to implement code coverage with Eclipse and EclEmma using this README, but failed. In the process, I discovered an issue with Eclipse 3.4 and JUnit on OS X. Reverting to Eclipse 3.3 solved this problem, but I was still unable to make EclEmma work with GWT.

After failing with Eclipse, I tried to use the emma-maven-plugin. I was also unable to get this to work, with my findings documented in this thread.

Finally, I did have some luck with getting IDEA's built-in code coverage feature working. However, after getting it to work once, it failed to work for the rest of the day and I haven't had success since.

Code Coverage and GWT
Because of these issues with GWT 1.5 and code coverage, I think I'll wait until GWT 1.6 to worry about it. The good news is 1.6 M1 was released last Friday. If continuing to use GWTTestCase becomes an issue, I may write my own MVC Framework that doesn't use classes that call native JavaScript. Hopefully GXT MVC's framework will provide a good example.

In addition to trying to get code coverage working, I used the internets to figure out how run GWT tests inside of Eclipse and IDEA. I don't remember the resources I used, but hopefully this up-to-date documentation will help others. The nice thing about using an IDE to run these tests is they typically execute much faster.

Running GWT Tests in Eclipse
You should be able to run most of your GWT tests from within Eclipse using the following steps.

  1. Right-click on a test that extends GWTTestCase and go to Run As > JUnit Test. It's likely you will see the error message below.
    Invalid launch configuration: -XstartOnFirstThread not specified.
    
    On Mac OS X, GWT requires that the Java virtual machine be invoked with the
    -XstartOnFirstThread VM argument.
    
    Example:
      java -XstartOnFirstThread -cp gwt-dev-mac.jar com.google.gwt.dev.GWTShell
    
  2. To fix this error, go to Run > Open Run Dialog. Click on the Arguments tab and add the following values. The 2nd value is to increase the amount of memory available to the test and avoid an OOM error.
    -XstartOnFirstThread -Xmx512M
  3. When you re-run the test, you will probably see the following error:
    com.google.gwt.junit.JUnitFatalLaunchException: The test class 'org.richresume.client.home.HomeControllerGwtTest' 
    was not found in module 'org.richresume.client.Application'; no compilation unit for that type was seen
      at com.google.gwt.junit.JUnitShell.checkTestClassInCurrentModule(JUnitShell.java:193)
      at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java:628)
      at com.google.gwt.junit.JUnitShell.runTest(JUnitShell.java:150)
      at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:219)
    
  4. To fix this, open the Run Dialog again, click on the Classpath tab and click on User Entries. Click on the Advanced button and select Add Folders. In the Folder Selection dialog, select your source and test directories (e.g. src/main/java and src/test/java).
  5. Run the test again and you should see a green bar in your JUnit tab.
  6. To create a JUnit configuration that runs all tests, duplicate the previously mentioned run configuration. Then change the name to "All Tests" and select the 2nd radio button to run all tests in the project.
  7. Click Run to execute all the tests in the project.

Running GWT Tests in IDEA
You should be able to run your GWT tests from within IDEA using the following steps.

  1. Right-click on a test that extends GWTTestCase and go to Run "TestNameGwtTes...". It's likely you will see the error message below.
    Invalid launch configuration: -XstartOnFirstThread not specified.
    
    On Mac OS X, GWT requires that the Java virtual machine be invoked with the
    -XstartOnFirstThread VM argument.
    
    Example:
      java -XstartOnFirstThread -cp gwt-dev-mac.jar com.google.gwt.dev.GWTShell
    
  2. If you get a compiler error instead, you may need to add the GWT Facet to your project. To do this, right-click on your project's top-most folder in the left pane. Select Module Settings > Facets and enable GWT for your module.
  3. To fix the -XstartOnFirstThread issue, go to Run > Edit Configurations. Add the following values to the VM Arguments field. The 2nd value is to increase the amount of memory available to the test and avoid an OOM error.
    -XstartOnFirstThread -Xmx512M
    NOTE: If you still get a compiler error, see this page for a possible solution.
  4. Run the test again and you should see a green bar in your Run tab.
  5. To create a JUnit configuration that runs all tests, duplicate the previously mentioned run configuration. Then change the name to "All Tests" and change the Test configuration to search for tests in the whole project.
  6. Run the new configuration to execute all the tests in the project.

Testing GWT applications isn't as straightforward as writing JUnit tests, but I do believe it's getting better. If you have any additional tips and tricks, please let me know.

Posted in Java at Feb 09 2009, 03:27:36 PM MST 6 Comments

What's the best Java Hosting Solution?

A friend recently asked me who I'd recommend for a Java hosting provider. Since I get asked this question every-so-often, it seemed appropriate to post my answer here.

  1. KGB Internet - I use KGB for this site. I have my own JVM and have full control over what I want to install. I can control Tomcat versions and upgrade as needed. I don't know if I'd recommend him for a business site as he can take up to 12 hours to respond to requests.
  2. Kattare - These guys will give you your own Tomcat instance and seem to have reasonable prices. They do seem to take quite some time to respond to requests (24-48 hours). I have a free instance that I use for a non-profit, so that could be the reason.
  3. Contegix - These guys are far-and-away the best company for Java-based hosting. They're not cheap though. However, they have the best customer service in the business - often responding to e-mails in less than a minute.

Do you agree with these recommendations? If not, who do you recommend for Java hosting and why?

Posted in Java at Feb 07 2009, 10:21:28 AM MST 38 Comments

Choosing an Ajax Framework

This past week, my colleagues and I have been researching Ajax Frameworks. We're working on a project that's following SOFEA-style architecture principles and we want the best framework for our needs. I'm writing this post to see 1) if you, the community, agree with our selection process and 2) to learn about your experiences with the frameworks we're evaluating. Below is the process we're following to make our choice.

  1. Choose a short list of frameworks to prototype with.
  2. Create an application prototype with each framework.
  3. Document findings and create a matrix with important criteria.
  4. Create presentation to summarize document.
  5. Deliver document, presentation (with demos) and recommendation.

For #1, we chose Ext JS, Dojo, YUI and GWT because we feel these Ajax libraries offer the most UI widgets. We also considered Prototype/Scriptaculous, jQuery and MooTools, but decided against them because of their lack of UI widgets.

For #2, we time-boxed ourselves to 3 days of development. In addition to basic functionality, we added several features (i.e. edit in place, drag and drop, calendar widgets, transitions, charts, grid) that might be used in the production application. We all were able to complete most of the functionality of the application. Of course, there's still some code cleanup as well as styling to make each app look good for the demo. The nice thing about doing this is we're able to look at each others code and see how the same thing is done in each framework. None of us are experts in any of the frameworks, so it's possible we could do things better. However, I think it's good we all started somewhat green because it shows what's possible for someone relatively new to the frameworks.

For #3, we're creating a document with the following outline:

Introduction

Ajax Framework Candidates
(intro and explanation)

  Project Information
  (history)
  (license / cost)
  (number of committers)
  (support options)
  (mailing list traffic (nov/dec 2008))

Matrix and Notes

Conclusion

For the Matrix referenced in the outline above, we're using a table with weights and ranks:

Weight Criteria Dojo YUI GWT Ext JS Notes
# Important Criteria for Customer 0..1 0..1 0..1 0..1 Notes about rankings

Our strategy for filling in this matrix:

  • Customer adjusts the weight for each criteria (removing/adding as needed) so all weights add up to 1.
  • We rank each framework with 0, .5 or 1 where 0 = doesn't satisfy criteria, .5 = partially satisfies, 1 = satisfies.

The list of criteria provided to us by our client is as follows (in no particular order).

  • Quality of Documentation/Tutorials/Self Help
  • Browser support (most important browsers/versions based on web stats)
  • Testability (esp. Selenium compatibility)
  • Licensing
  • Project health/adoption
  • Performance
  • Scalability
  • Flexibility/extensibility
  • Productivity (app dev, web dev)
  • Richness of widget/component library
  • Charting capability
  • Ability to create new widgets
  • Match to existing Java team skill-set
  • Ease of deployment (on Ops, QA, Users)
  • Degree of risk generally
  • Ability to integrate with existing site (which includes Prototype)
  • Easy to style with CSS
  • Validation (esp. marking form elements invalid)
  • Component Theme-ing/Decoration
  • CDN Availability (i.e. Google's Ajax Libraries API or Ext CDN)

What do you think? How could this process be improved? Of course, if you have framework answers (0, .5 or 1) for our matrix, we'd love to hear your opinions.

Posted in Java at Jan 08 2009, 09:36:22 PM MST 39 Comments

2008 - A Year in Review

In 2005 and 2006, I did "A Year in Review" entries. 2007 was the year I got divorced, which probably motivated me to write a bit less. This year I'm back and ready to spend the next few hours writing, copying/pasting and linking like a madman. Hope you enjoy!

Workin' on the Feedlot 2008 was the year I traveled the world and developed a true passion for skiing. In January, my good friend Jason Miller moved back to Denver after quitting his job at Bear Stearns in NYC. We spent the first weekend in Nebraska working on Cletus's feedlot. The next week, my car stereo got stolen and I wondered if my bad knee would make it through the ski season (the good news is not only did I ski the rest of the season, but my knee healed itself over the summer).

Abbie and Jack on Green Mountain At the end of January, the kids and I hiked to the top of Green Mountain and Don Brown made Maven not suck. Then I wondered if there was room for both Rails and Grails at a company and quickly learned both.

February started fantastically with a 14" Powder Day at Steamboat. I wondered if there is no "best" web framework and reviewed Grails and Rails books. After spending an awesome weekend in Tahoe, I took the kids on The Ski Train and learned more about Selenium at Google.

Breathtaking Miller and Vial Lake Tahoe - Last Run

This brings us to one of my favorite posts of all time. On February 28th, Jack got a bead stuck in his nose. After taking him to the ER and paying $800, we found out magic recipe for bead removal is to "hold one nostril and give him a CPR-type breath/blow into his mouth". The reason I love the post so much is it's solved the problem for other frantic parents when they Google for "bead stuck in nose". Whenever I get a new comment, it always makes me smile.

March started out with a Powder Day at Whistler. I thoroughly enjoyed the rest of the weekend with good friends Jarvis and Korn Dog. After returning to Denver, I was allowed to blog about building a UI Frameworks Team at LinkedIn and posted my thoughts on Grails vs. Rails.

View from Our Condo In mid-March, I achieved an all-Mac family and traveled to Lake Chelan for my sister's birthday. Shortly after, The AppFuse Primer was released. At the end of the month, I attended TSSJS in Vegas and moderated a Web Framework Smackdown.

In April, the LinkedIn Denver office opened and we all celebrated by attending the Rockie's Home Opener. The ski season came to an end and I wrote a howto for configuring Apache with mod_proxy and SSL on OS X. Then I discovered the JavaOne parties and wrote about running Spring MVC Web Applications in OSGi.

April ended with 82°F and May started with snow. I attended JavaOne (or at least the parties), released AppFuse 2.0.2 and figured out how to do extensionless URLs with the UrlRewriteFilter. The kids and I spent an afternoon in Rocky Mountain National Park and I did some coding in my backyard.

Jack's Special Rock Nice Trail Beautiful Smile Here's Hoping for another run in October

On Memorial Day, I enjoyed a liver-wrenching, Rockies-filled weekend with my sister her girlfriend Mya and Mr. Miller. I also contemplated making AppFuse Struts 2-specific.

June started with some mountain bike riding, planning some excellent vacations and getting a dream machine. I rode the annual trip to Big Head Todd at Red Rocks with Matt and Bruce. I took the kids on their first camping trip for Father's Day and had a blast. It took us several hours to find the campsite and my car kept starting all night long. It's sure to be a family tradition from now on.

Catchin' Bugs

The next weekend, I attended the American Craft Beer Fest in Boston. To end the month, I embarked upon Raible Road Trip #12 with Abbie, Jack and my Dad.

Grand Tetons In July, the bus project began and I posted pictures of the trip to Montana. This year, I hope to spend the whole month of July at the cabin. I bought an iPhone (one of my best technology-related purchases to date). OSCON was fun but the week after wasn't.

Nice 'n Snug August revealed my favorite birthday present. I didn't blog much the rest of the month, revealing why later.

Jack on his 4th Birthday Jack's Birthday Weekend was an outstandingly fun mixture of old friends and good Colorado beer. In September, I went to see the bus at MotorWorks, Abbie lost her first tooth and co-workers and I performance tested Memcached.

What followed was wonderful. Miller and I headed to Oktoberfest for the Best. Vacation. Ever. We still talk about how much fun we had on that vacation. October finished with the Colorado Software Summit and a hunting trip to the cabin.

November was a crazy month. I got laid off and celebrated Abbie's birthday on the same day. Jack got a mohawk and I traveled coast-to-coast in the same week. To close the month, I announced what's next and headed to Costa Rica.

Costa Rica, courtesy of Rob Misek

I had a fantastic time in Costa Rica and was impressed to see Abbie is a blue skier shortly after. I did a Dojo/Comet Research Project for a week and enjoyed the location of my newest client last week. A small adventure turned into a scary adventure and I enjoyed telling my stories to fellow Java Enthusiasts in Portland.

Phew! It's been quite a year. For 2009, I'm still hoping for what I tweeted shortly after Costa Rica. I'd like to visit 3 foreign countries, take 3 months of vacation and spend 1 month in Montana. I have technology goals too, but those aren't nearly as much fun to dream about. ;-)

Happy New Year!

Posted in Roller at Dec 31 2008, 04:56:32 PM MST 2 Comments

AppFuse Light converted to Maven modules, upgraded to Tapestry 5 and Stripes 1.5

This past week, I stayed up a couple of late nights to do some of the AppFuse Light work I wrote about in October. I converted all web frameworks to Maven modules, as well as made them inherit from the appfuse-web project. Below is what the new module structure looks like:

New AppFuse Light Modules

At this point, the project is ready to import into AppFuse's SVN project. Here's a list of other changes I made:

  • Modules now depend on AppFuse's backend and allow you to use Hibernate, JPA or iBATIS as the persistence framework. Implementations for Spring JDBC, OJB and JDO have been removed.
  • Upgraded to JWebUnit 2.1, which now uses HtmlUnit under the hood and has much better JavaScript support. It also has Selenium support, but I've yet to try it.
  • Ajaxified Body integrated into all frameworks. You can easily turn it off by modifying the global.js file.
  • Prototype and Scriptaculous loaded from Google's Ajax Libraries CDN.
  • Upgraded to Tapestry 5. Mad props to Serge Eby and his tapestry5-appfuse project for showing me how to do this. Serge became a committer on AppFuse recently, so hopefully we'll continue to see great things from the Tapestry 5 support. I really like the clean URLs and minimum configuration required in Tapestry 5. It's testing framework is nice too, but I believe it could be improved.
  • Upgraded to Stripes 1.5. This was easy and painless. I'm definitely a fan of Stripes and look forward to reading the Stripes book on my bookshelf.
  • Dropped support for: Struts 1.x, WebWork, Spring MVC + Velocity.

If you want to try any of these applications, you can create archetypes using the following commands:

svn co https://appfuse-light.dev.java.net/svn/appfuse-light/trunk appfuse-light
cd appfuse-light/preferred-web-framework
mvn archetype:create-from-project
cd target/generated-sources/archetype
mvn install
cd ~/dev
mvn archetype:generate # The new archetype should show up as an option

Next steps include figuring out a way to flatten the inherited dependencies and plugins so archetype:create-from-project can create truly standalone projects. Please let me know if you have any questions.

Posted in Java at Dec 20 2008, 06:42:03 PM MST 9 Comments

Dojo/Comet support in Java Web Frameworks

Dojo Logo This week I'm doing a research project for a client. The main purpose of the project is to find out which Java-based web framework works best with Dojo and Comet. Here's the key requirement from the client:

It's all about Comet, we want Comet everywhere we can put it, but we want to isolate the icky bits of fiddling with pages with JavaScript. We're kind of wed to the Dojo implementation of the client-side bit, so we may as well use more of the Dojo widgets for a richer UI. For us, "works best with" needs to pay a certain amount of consideration to "fits naturally with", if you understand what I mean. I know that any framework that lets you spit out raw HTML will let you hand code in your Dojo / Comet, but that's certain to become very tiresome very quickly.

The candidate frameworks they asked me to look at are Wicket and Tapestry 5. They're willing to upgrade to Struts 2 since they're already using Struts 1. However, they don't feel that action-based frameworks naturally lead to rich UIs, so they'd prefer a component-based framework. They're currently using Seam for an administration-type application and feel it's too heavy for their customer-facing application.

Here's what I've found so far in my research. Please let me know if anything is incorrect.

  • Tapestry 5 doesn't have Dojo or Comet support (Prototype and Scriptaculous are the baked-in Ajax frameworks).
  • Struts 2 has old (version 0.4.3) and somewhat deprecated Dojo support. The developers seem to be in favor of removing it and promoting people hand-code Dojo instead. Struts 2 doesn't have support for Comet.
  • Wicket has support for Dojo 1.1 that includes Comet support. This was written by Stefan Fußenegger and posted to the mailing list last month. I e-mailed Stefan and asked him about documentation. His response: "I lost my ambition to document it properly since I didn't receive any feedback on the mailing list. :)"

At this point, it seems that if the client really wants to use Dojo, they should use Wicket, and possibly pay Stefan to document it properly. However, they're willing to consider other options, as long as they have Comet support.

One option I thought of is to use DWR and its Reverse Ajax/Comet support. Another option would be to add better Dojo support to Tapestry 5. However, I don't think this is possible since the Prototype/Scriptaculous code is generated by the framework and would likely require a changes to switch it to Dojo.

Are there any other Java-based web frameworks that support easily creating Dojo widgets and working with Comet? Keith Donald tweeted that Spring MVC has Dojo support. However, I believe it's only for widgets and it still requires you to write JavaScript. If your framework doesn't have Dojo/Comet support, how hard would it be to add it?

Update: I also posted this question on LinkedIn. Make sure and check my question for additional thoughts from folks.

Posted in Java at Dec 18 2008, 03:58:37 PM MST 19 Comments

Moving from Spring's XML to Annotations in AppFuse

Last night, I did a spike on AppFuse to change XML to Spring annotations (@Repository, @Service and @Autowired) in its service and data modules. While I was able to accomplish everything in a few hours (including converting tests), I did run into a couple issues.

AbstractTransactionalJUnit4..Tests vs. AbstractTransactionalDataSource..Tests
I've switched from my favorite Spring class to the annotation-happy AbstractTransactionalJUnit4SpringContextTests. However, this has presented an issue: when using ATDSSCT, I was able to call endTransaction() and startNewTransaction(). With ATJ4SCT, this doesn't seem possible. Below is a screenshot of the diff on a test method in the JPA implementation of UserDaoTest:

AbstractTransactionalJUnit4SpringContextTests vs. AbstractTransactionalDataSourceSpringContextTests

On the right, you'll notice that I had to comment out @ExpectedException to get the test to pass. This concerns me since this exception should be thrown. Is there a way to call endTransaction() and startNewTransaction() when subclassing AbstractTransactionalJUnit4SpringContextTests?

Instantiating GenericDao Implementations Programmatically
The second feature I tried to add is the ability to instantiate a GenericDao programatically rather than requiring a XML bean definition. In current versions of AppFuse, you can use the following bean definition to create a GenericDao for a model object.

<bean id="personDao" class="org.appfuse.dao.hibernate.GenericDaoHibernate">
    <constructor-arg value="org.appfuse.tutorial.model.Person"/> 
    <property name="sessionFactory" ref="sessionFactory"/>
</bean> 

When moving to a no-XML required architecture, it'd be nice to allow users to create GenericDao's programmatically. Below is the easiest way I've found to do this in a test:

GenericDao<User, Long> genericDao;
@Autowired
SessionFactory sessionFactory;

@Before
public void setUp() {
    genericDao = new GenericDaoHibernate<User, Long>(User.class);
    genericDao.setSessionFactory(sessionFactory);
}

However, there's a couple problems with this. First of all, mixing constructor injection and setter injection probably isn't a good idea. Changing the constructor to take a SessionFactory solves this problem, but now all subclasses need to have a more verbose constructor:

@Autowired
public UserDaoHibernate(SessionFactory sessionFactory) {
    super(User.class, sessionFactory);
}

Whereas before they had:

public UserDaoHibernate() {
    super(User.class);
}

In an ideal world, I could call new GenericDaoHibernate<User, Long>(User.class) and the SessionFactory would be wired in auto-magically. Is this possible with Spring 2.5?

The 2nd problem this presents is your client code will now be dependent on an implementation rather than the interface. I don't know how to solve that one, but I'd love to figure out a way to create GenericDaos with no XML and no implementation details in the client. Any ideas are most welcome.

If you'd like to see all the changes I made in converting from XML to Annotations, please see this patch.

Posted in Java at Nov 04 2008, 11:39:54 AM MST 14 Comments

Applying Flash to Java: Flex and OpenLaszlo with Dustin Marx

If you're going to choose Flex or OpenLaszlo, chances are you're targeting Flash. The Flash Player allows you to abstract the browser idiosyncrasies and give users a better experience. It hides the browser quirks from both developers and users. It's also a highly ubiquitous web browser runtime environment. It provides a user experience way beyond traditional HTTP request-response. Also, its visual effects and "richness" rival of non-browser desktop applications.

Mark's blog stats show that 95% of readers are using Flash 9 and 1% is Flash 10. All others don't have their version exposed. Most other sources claim that Flash 9 has 98% penetration in mature markets. One of the nicest things about Flash is it frees users from limitations of traditional web applications. Request/response is largely a thing of the past and Ajax-like behavior was built-in from the beginning.

Flash Criticisms: has reduced SEO as well as bookmarking and URL history support.

Flash Player Criticisms: not open source, no significant alternative, no 64-bit player, loading performance and it's only useful for games, movies and annoying advertisements.

The good news is Flash is getting better. There's currently a SWF Searchability initiative with Google and Yahoo!. For bookmarking and URL History, you can use "deep linking" with mx.managers.BrowserManager and mx.managers.HistoryManager. Flash Player issues are also being addressed. There's a Flash Open Screen Project, there's a 64-bit player in Adobe Labs and Flash 9/10 is much better than in the past.

To prove that Flash is a compelling technology, all you have to do is look at Microsoft's Silverlight and Sun's JavaFX. These are direct competitors that are fairly new and prove that companies like what Flash has.

Flex
Flex is not Flash. Flex requires Flash (9+), but Flash does not require Flex. Flex is a language and framework and applications are compiled into .swf files. Flash is the runtime environment that executes .swf files. Flex 3 is FREE. The Flex SDK, compiler and debugger are open source. They have no license costs. BlazeDS is also open source and has no license cost.

Flex MXML was formerly called Macromedia XML. It's an XML-based presentation/layout language that's editable with any text editor or IDE. MXML is to ActionScript 3 as JSP is to Java. MXML provides the layout and ActionScript provides the dynamic business logic.

ActionScript
ActionScript is an ECMAScript implementation that's been proposed as the Edition 4 implementation. It's not your older sibling's JavaScript. It uses class-based object-oriented features and static typing. Thanks to the Flash Player, it works the same across multiple browsers. Most of the things you can do with MXML, you can do with ActionScript. However, MXML typically requires less LOC.

ActionScript allows packages, interfaces, inheritance, objects and methods. It includes extensive XML Support, particularly E4X (ECMAScript for XML). It has a large class library and can talk directly to the Flash Player. Finally, it has many Java-like features and it's syntax looks similar.

At this point, Dustin started doing demos of two popular Flex components: RichText Editor (which creates horrible HTML) and Data Grid. More third-party Flex components seem to appear every day. Examples include flexlib, ASDIA as well as all those listed on FlexBox. Additionally, it's not too difficult to create your own Flex components (no proof provided).

Flex's property binding is one of Dustin's favorite features, but he says he has a difficult time conveying how cool it is. Property binding allows you to tie data in one object to data in another object. Updates in one object affect another. To use it in MXML, you can use curly braces or the tag. In ActionScript, you can use the BindingUtils object. You can also use Flex's metadata annotation "Bindable" to denote bindable objects.

To compile Flex applications, you can use mxmlc from the command line. You can use Ant with the <exec> task or using Flex's Ant Tasks. You can also invoke mxmlc from Java as long as you include mxmlc.jar in your classpath. FlexBuilder is an Eclipse-based IDE that's not included with the free Flex SDK. It's not a free product and can be used as a plugin or a standalone IDE.

Flex and Java
There's two predominant out-of-the-box methods for Flex to communicate with Java EE backends.

  • HttpService: traditional HTTP request/response.
  • WebService: SOAP-based Web Services.

If the above two methods aren't fast enough, you can use BlaseDS and it's additional options.

  • Web Messaging: HTTP publish/subscribe with JMS, ColdFusion and/or other Flash/Ajax client.
  • Remoting with AMF: access server-side objects from Flash client-tier as if they were hosted there.

Flash applications can access either a client's machine or a remote site, but not both. You can use a crossdomain.xml file on your server to allow remote Flash clients to connect. This file allows access for both Flex and OpenLaszlo applications.

BlazeDS adds proxy server support for HTTPService and WebService. To use, set the useProxy attribute to "true". Features include authentication and logging. It adds a new RPC mechanisms called RemoteObject. This object allows ActionScript and Java EE transparent integration. It also adds publish/subscribe messaging with a JMS Adapter available. Lastly, it adds Ajax support to your Flex application.

GraniteDS is an open-source (LGPL) alternative to Adobe LiveCycle and is similar to BlazeDS. It has COMET-like functionality and supports Spring, Spring Security, EJB 3, Seam and Guice.

Flex Frameworks: Cairngorm (Adobe Consulting), Pure MVC, Mate and many others.

Flex 4 (Gumbo) will have improvements for designers (easier customization, better tool support), improvements for developers (faster compiler, two-way data binding) and will leverage new features of Flash 10.

OpenLazlo
OpenLaszlo 4 is XML-based and uses an XPath syntax for data access. OpenLaszlo was actually created before Flex and is ECMAScript-based. Unlike Flex that requires Flash 9, OpenLaszlo is architected to deploy on different runtime environments, including: Flash 7/8/9 and DHTML. Dustin believes OpenLaszlo would be a lot more appealing if your source code could be compiled into Silverlight or JavaFX.

OpenLaszlo's syntax looks a lot like Flex, except it does not use namespaces. OpenLaszlo's Constraints are similar to Flex's property binding, except the syntax is a bit different. You use ${} in LZX tags or applyConstraint() and LzDelegate in scripts. OpenLaszlo's event handling is similar to Flex and JavaScript event handling. All attributes have an implicit "on" event that is triggered when an attribute's value is changed. Event handlers can be written CSS-style in LZX nodes or using the <handler></handler> tag. Script code can be embedded in LZX XML in many ways:

  • Inside event attributes
  • Within <script></script> tags
  • Within <method></method> tags
  • Within <handler></handler> tags
  • In a separate file (<script src="someFile.js" />)

Dustin believes the debugger and view-source tools in OpenLaszlo are much better than the ones available for Flex.

For the rest of the presentation, Dustin covered many of Laszlo's feature, how they relate to Java as well as how to integrate SWF and HTML. SWFObject is Dustin's preferred method for adding Flash to HTML. One of its nifty features is it allows SWF-to-SWF communication.

This talk was an excellent and in-depth overview of Flash, Flex and OpenLaszlo. I especially liked all the details on ActionScript and the different methods for remote communication. Nice job Dustin!

Posted in Java at Oct 22 2008, 02:31:10 PM MDT 2 Comments