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.

Upgrading Equinox to Tapestry 4.0

Last week, I upgraded Equinox from Tapestry 3.0.3 to Tapestry 4.0. The commit log can be found on Fisheye. Here are some details that might help you upgrade.

  • Tapestry 4.0 doesn't support Spring out of the box. This was surprising to me b/c one of the advertised features of Tapestry 4.0 (or Hivemind actually) was native Spring support. Luckily, Howard released the tapestry-spring project which solves this problem. Dropping the JAR in your classpath is enough to get built-in integration. It'd be nice to see this library become part of tapestry (possibly in the tapestry-contrib.jar).
  • Tapestry-Flash makes it easy to do success messages when redirecting. Furthermore, it's nice to see how to do redirecting w/o throwing a PageRedirectException.
  • PageRenderListener has changed to PageBeginRenderListener.
  • When using <inject> for a property, I had to remove any public abstract void setXXX methods as I got an error otherwise. Luckily, the error message told me exactly what to do.
  • Injecting dependencies during testing is fairly simple using the Creator class. Equinox's UserFormTest.java has a good example of this. I did have to create a MockRequestCycle and a MockPageService, but both were pretty easy to write.
  • Friendly URLs are much easier to implement in Tapestry 4.0. However, Tapestry still doesn't allow you to use the same extension for everything - so I ended up with .html, .direct, .sdirect and .svc extensions. I'd prefer a single extension, but oh well.
  • You'll need to change all your *.page files to use the new 4.0 DTD. I don't think this is absolutely necessary, but it does simplify things.
  • As part of the 4.0 DTD, <property-specification> has changed to <property> and the "type" attribute is not allowed (b/c it's inferred using reflection I assume). In addition, <binding name="foo" expression="bar"> has changed to <binding name="foo" value="bar"> and <context-asset> has changed to <asset>. Also, <message-binding> has been removed in favor of <binding>. The userForm.page diff shows detailed changes.
  • @Conditional has changed to @If.
  • The issue where Tapestry sets the focus on the first required field still occurs. An easy workaround is to make the first field required.
  • The @DatePicker component has changed from using the "format" attribute to using the "translator" attribute for formatting dates. The popup calendar also seems to have changed - I had to add new CSS rule to colorize the header properly.

Hopefully this simplifies your Tapestry 4.0 upgrade.

Posted in Java at Feb 21 2006, 03:26:51 PM MST 2 Comments

What do we need to do to make WebWork/Action 2 the best framework for *everything*?

From Ted Husted on the Struts mailing list:

Seriously, hype aside, engineer to engineer, if we can use the new standalone Tiles with WebWork, and use Ajax to store the state of UI controls, what else do we need to do to make WebWork/Action 2 the best framework for *everything*?

My reply:

The tag documentation (and documentation in general) for WebWork is difficult to navigate. Struts' documentation has generally made it easier to find stuff.

I think the hardest part of WebWork/Action 2 is providing the path for migration. If Struts 1.x applications can run in Struts Action 2.x, and users can create new Actions following WW's APIs - that will be truly awesome.

Another that would be cool is smart defaults. For example, having Actions that end with "Action" be available at the "everythingbeforeAction" URL. Spring has something similar coming in 2.0 - and it's mainly just done by extending a certain class.

http://jroller.com/page/raible?anchor=an_example_of_smart_defaults

So if I have UserAction, it's automatically available at /users, /user/edit, /user/save, etc. Default CRUD in a sense. No xwork.xml required by default. But users can override. Default everything w/o requiring annotations, but allow overriding. Or maybe there's different default schemas - a CRUD one, store front, etc.

Ajax stuff that I think WW already has: in-page updates, sortable/pageable lists with something like the displaytag - but with Ajax. There's a lot of these components already available for this stuff, so it might just be a matter of documenting how to integrate them.

Promoting Maven 2 for building might be an easy way of promoting inclusion of 3rd party libraries. Add 3 lines of XML, use this code in your JSP/template, boom - you're good to go. Those that don't like Maven can use the Ant tasks and pom.xml.

Archetypes could be pretty big too - create starter applications that users can use. Even better, provide a means to upgrade the archetypes. Of course, that might be a Maven thing - and editing pom.xml to change versions really isn't that hard.

Above all else - to become the best MVC framework for Java - documentation and easy migration are essential.

Just my $0.02 of course. ;-)

What's your opinion?

Posted in Java at Feb 21 2006, 02:19:17 PM MST 3 Comments

New MacBook Pro has shipped!

A week ago, Apple announced that it was shipping MacBook Pros with faster processors. At the time, this seemed like an excuse for Apple to change the shipping date from February 15th to the 28th. Since I was already disappointed by the extra 2-week wait, I upgraded to the 2.16 GHz chip. This bumped my ship date back even further - to March 17th.

However, I just received an e-mail from Apple saying that my laptop has shipped! WTF? Either there's a glitch in their system or I'm gonna be one happy camper at the end of this week. ;-)

Posted in Mac OS X at Feb 21 2006, 02:22:53 AM MST 9 Comments

[CSS Fundraiser] Brrrrrrrr

At 14°F, it was definitely a cold ride to work this morning. It took about a mile and a half before my face when numb. Then I stopped to snap some pictures, which made my fingers go numb. However, the sun was out and it is a beautiful morning in Denver.

Washington Park Cherry Creek Trail

Cold!

Why am I doing this? To raise money for a CSS Design contest.

Tuesday Morning Update: Last night's ride home was pretty warm - 35°F. This morning's ride was fairly nice too (31°F). Here's proof from last night.

Late for dinner Warm Night

Posted in Java at Feb 20 2006, 09:17:10 AM MST 5 Comments

Fundraiser for CSS Framework Design Contest

A week ago, I received a $250 donation for "AppFuse Development". This is a significant amount of cash, and unfortunately the committers can't do a "beer at the local pub". We've decided that a good thing to do with the money is to use it to buy a prize for a CSS Framework Design Contest. The AppFuse Logo Contest went well, but I also gave away an iPod to the winner.

This contest will be a bit different. First of all, the CSS Framework is not AppFuse-specific at all. It's just a structured bit of XHTML for page layout, and a number of CSS files for positioning. What's missing is a number of good-looking templates to make this framework look even better. I have aspirations of creating something like CSS Zen Garden - but with more of a web-application flavor. Hopefully we can use the same submission guidelines as well as offer the contest's themes for anyone to use. The CSS themes from this contest should be usable in corporate intranets, as well as customer facing applications. Sure, wacky designs are cool, but sharp and clean are better.

I hope to start this contest as soon as I've raised some funds for good prizes. Of course, donating good prizes is most welcome too. In order to provide some motivation, I'm going to do something that will hopefully inspire you to donate. It's butt-ass cold in Denver this week, and it's not warming up anytime soon. Here's the current forecast from the local news channel:

Forecast: 2/19/06 - 2/24/06

So to try and raise money, I'm going to ride my bike to work every day this week. Will this inspire folks to donate? I don't know, but it's worth a try. I'll try to be in the office by 9, and won't be home before 5. This should ensure that it's good and cold out. Furthermore, I'll blog about my ride everyday, and hopefully snap some pictures as well. It's supposed to snow tonight, so this should be good.

320

Remember, anything will help - and all donations will go to a good cause. I plan on starting the actual design contest next week sometime. Now it's time to donate using the button below - and watch me freeze my ass off this week! ;-)

Posted in The Web at Feb 19 2006, 09:34:39 PM MST 9 Comments

RIFE: Which template syntax looks best to you?

Geert Bevin of the RIFE project asks:

Many times I have wondered why people are so reluctant to investigate RIFE. After having asked around a bit, the most recurring critique was that our template syntax is too arcane at the initial glance. Somehow the look of the tags syntax pushes people away without them ever checking out any of the features of our framework.

Ironically, none of the users consider the syntax to be a problem. Many even love how it stands out while still being totally invisible to a browser or an XHTML editor.

Still, initial adoption seems to be all about appearances, so I think this issue needs to be addressed. That's why I'm asking you, the non-rife users which alternate syntax looks best to you. [Read More »]

I'm one of those folks that thinks RIFE's current template syntax is difficult to understand. I was scared away from RIFE for this reason alone. It's good to see them asking the community for a better formula.

There's one thing I've learned from leading an open source project: your users aren't always right. Just because they like the way things are done, it doesn't make it the best way to do it. Often, developers merely like something because they've learned it, and would rather not learn something new. Look at all the folks that prefer Struts, yet have never tried another web framework.

Personally, I like Velocity's variable style, which is now used by JSP 2.0. Most new Java web developers are going to learn JSP. If you can make the transition from JSP to your template syntax easier, you'll likely get more users.

Posted in Java at Feb 19 2006, 08:33:00 PM MST 3 Comments

Rough week for Jack

Last week, I flew out to San Francisco on Monday evening to meet with a client. My meeting was on Tuesday, and I spoke with Julie shortly before flying home on Tuesday night. No, she wasn't mad I missed Valentine's Day - we're both aware it's a Hallmark Holiday. She said that Jack had a rough day - going through something like 20 diapers. When I arrived home at midnight, he still wasn't feeling very well.

The next morning, he threw up on me after drinking a bunch of milk. The vomiting continued for 2 more days and got really bad on Thursday. He couldn't even hold down water. Thursday morning, Julie took him to the doctor, and they said it was probably Rotavirus. He'd lost 3 pounds, which is a lot for a guy his size. Thursday afternoon, we noticed he was turning white and was very lethargic.

Julie and her sister (who is a nurse) took Jack to the emergency room Thursday evening. They were planning on waiting a few hours for anyone to see him. Instead, they took him right away and hooked him up to an IV. His glucose level was at 36, which is way below "very bad". He recovered nicely after getting some fluids and was back home by 9:00 p.m.

Today, he's back to his normal self - laughing, crying and bugging his big sister. I heard Rotavirus lasted 7 days, and it appears to be true. Here's a picture we took of Abbie and Jack yesterday - you can tell he's not 100%, eh? ;-)

February 2006

Posted in General at Feb 19 2006, 06:16:46 PM MST 3 Comments

Redirect-after-Post in Tapestry 4.0

I just noticed a good Tapestry nugget on Howard's blog. With Tapestry 3.0, one of the things I complained about was the need to throw an exception when redirecting. With 4.0, it looks like you can plug-in this flash component and get exactly the flash message functionality I try to put in all the web frameworks that AppFuse supports. Now I just need to figure out how to do @InjectObject("engine-service:page") without using annotations.

I'm hoping to upgrade AppFuse to WebWork 2.2 and Tapestry 4.0 in the next few days.

Posted in Java at Feb 17 2006, 12:44:14 PM MST 8 Comments

Updated Web Tier Specs for Java EE 5

Ed Burns (JSP Spec Lead) points out there's New Drafts of Java EE Web Tier: JSF 1.2, JSP 2.1, Servlet 2.5

I'm pleased to announce another revision of the Java EE Web Tier. In Jan Luehe's blog you can find out what's new in JSP 2.1 Proposed Final Draft 2 (PFD2). The Change Log for Servlet 2.5 will give you the scoop on the Servlet spec. This blog entry will show what's new in the JSF spec.

In JSF, the most visible new feature since the last draft of the spec is the addition of the invokeOnComponent() method on UIComponent. See below for more details.

This revision of the Java Web Tier is fully implemented in glassfish build 37, Sun's open source Java EE 5 Application Server, and the basis for the upcoming Java EE SDK.

I changed the link to Jan Luehe's blog because Ed's link seems to be incorrect. My guess is Java EE will be finalized and released before JavaOne. This is how Sun usually does things: work like mad until JavaOne, then take a week or two off to celebrate the release. Other rumors I've heard are that JBoss and Geronimo hope to release Java EE 5 compliant releases by or at JavaOne.

2006 is shaping up to be quite a year for the popular Java web frameworks. Tapestry 4.0, WebWork 2.2, JSF 1.2 and Spring MVC 2.0 (with form tag libraries and smart defaults). The question is, how long will it take for MyFaces to implement JSF 1.2? And when will we see a large-scale site deployed with JSF?

Why isn't Struts or your favorite framework in this list? Struts is being replaced by WebWork and the rest simply don't have the market share. No one has heard of RIFE or Wicket. However, that didn't stop me from encouraging SourceBeat to publish a Wicket book. Having good (published) documentation about a project is the first step to corporate adoption IMO.

Posted in Java at Feb 17 2006, 11:06:34 AM MST Add a Comment

Dependency Injection with SiteMesh

Let me start off by saying I think that both SiteMesh and Tiles are great frameworks. I was a long time user and fan of Tiles, and I think it's appropriate for certain situations. However, I've been a heavy user of SiteMesh since it passed the 10 minute test. While most heavy users of SiteMesh (the Atlassian guys come to mind) say that it can do everything that Tiles can do, these features are largely undocumented. This is my attempt to document a cool feature.

In a site I recently helped develop, we needed a couple of features:

  • A tabbed menu that highlighted the current tab based on which page you were on.
  • A bunch of "panels" on the right sidebar that changed according to the page.

To make this work, we used the meta tag functionality that SiteMesh provides.

Funny side/related note, I just googled for this tag and found this howto, which is similar to this one.

In our pages, we added the meta tags to set the active menu, as well as which panels to show in the sidebar:

<head>
    <title><fmt:message key="authorList.title"/></title>
    <meta name="menu" content="Authors"/>
    <meta name="panels" content="administration,blogs,events"/>
</head>

Then, in our decorator, we interpret these separately. First, we used Struts Menu (with Velocity) for the navigation system:

<c:set var="currentMenu" scope="request">
    <decorator:getProperty property="meta.menu"/>
</c:set>
<c:import url="/WEB-INF/pages/menu.jsp">
    <c:param name="template" value="/template/menu/tabs.html"/>
</c:import>

The menu.jsp page takes "template" as a parameter so we display the same menu links using a different Velocity template (for example, links at the bottom of the page).

<menu:useMenuDisplayer name="Velocity" config="${param.template}" permissions="rolesAdapter">

Then our tabs.html Velocity template uses the "currentMenu" attribute to determine which menu to highlight.

## displayMenu is defined in WEB-INF/classes/globalMacros.vm
#macro( menuItem $menu $level )
  #set ($title = $displayer.getMessage($menu.title))
  #if ($menu.url)
    #if ($menu.name == $currentMenu)
      <span class="current">
    #end
      <a href="$!menu.url" title="$title"><span>$title</span></a>
    #if ($menu.name == $request.getAttribute('currentMenu'))
      </span>
    #end
  #end
#end

#if ($displayer.isAllowed($menu))
    #displayMenu($menu 0)
#end

As far as the panel injection goes, that's processed using the following logic in our decorator:

<c:set var="panels"><decorator:getProperty property="meta.panels"/></c:set>
<!-- No panels set, use default set of panels -->
<c:if test="${empty panels}"><c:set var="panels" value="different,partners"/></c:if>
<c:forEach var="panel" items="${panels}">
    <c:import url="/WEB-INF/pages/panels/${panel}.jsp"/>
</c:forEach>    

Since this site used WebWork, the <ww:action> tag made it easy to give each panel independence. That is, each panel could load on its own, supply its own data, and not worry about the data being prepared beforehand. Here's an example:

<%@ include file="/common/taglibs.jsp"%>

<h2>Author Blogs</h2>

<ww:action name="'authors'" id="authors" namespace="default"/>

<div class="item">
    <ww:iterator value="#authors.authors" status="index">
        <a href="<ww:property value="blog.feedUrl"/>">
            <img src="${ctxPath}/images/icons/xml.gif" alt="XML Feed" 
                style="margin-right: 5px; vertical-align: middle"/></a>
        <a href="<ww:property value="blog.url"/>"><ww:property value="name"/></a>
        <br />
    </ww:iterator>
</div>

Of course, now that you can use Tiles with WebWork, Struts, Spring MVC and JSF - you could use Tiles for the injection and SiteMesh for the decoration.

Now if we could just get someone to write a JSF Decorator for SiteMesh, like Erik Hatcher did for Tapestry.

Posted in Java at Feb 16 2006, 09:57:23 AM MST 6 Comments