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.

Upgrading to Tomcat 6

Erik did it, so I tried it as well. This site is now running Tomcat 6.0.10 and it has to be the least painful major Tomcat upgrade I've ever done. By major, I mean upgrading from one version number (5.5.17) to the next. Apparently, no XML files changed (like they did from 4.1.x -> 5.0.x -> 5.5.x) because I was able to copy over conf/server.xml and conf/Catalina/** without any issues. The only change I had to make was to copy commons-logging.jar from Roller's WEB-INF/lib to JSPWiki's.

I have seen a couple of the following errors in my log files since I upgraded, so if you see any strange behavior, please let me know.

2-Mar-2007 12:36:10 AM org.apache.tomcat.util.http.Parameters processParameters
WARNING: Parameters: Character decoding failed. Parameter skipped.
java.io.CharConversionException: EOF
        at org.apache.tomcat.util.buf.UDecoder.convert(UDecoder.java:83)
        at org.apache.tomcat.util.buf.UDecoder.convert(UDecoder.java:49)
        at org.apache.tomcat.util.http.Parameters.urlDecode(Parameters.java:410)
        at org.apache.tomcat.util.http.Parameters.processParameters(Parameters.java:392)
        at org.apache.tomcat.util.http.Parameters.processParameters(Parameters.java:508)
        at org.apache.tomcat.util.http.Parameters.handleQueryParameters(Parameters.java:266)
        at org.apache.catalina.connector.Request.parseParameters(Request.java:2404)
        at org.apache.catalina.connector.Request.getParameterValues(Request.java:1089)
        at org.apache.catalina.connector.RequestFacade.getParameterValues(RequestFacade.java:396)
        at javax.servlet.ServletRequestWrapper.getParameterValues(ServletRequestWrapper.java:189)
        at org.acegisecurity.wrapper.SavedRequestAwareWrapper.getParameter(SavedRequestAwareWrapper.java:325)
        at org.apache.roller.ui.rendering.velocity.deprecated.OldPageRequest.(OldPageRequest.java:164)
        at org.apache.roller.ui.rendering.velocity.deprecated.RedirectServlet.figurePageRedirect(RedirectServlet.java:285)
        at org.apache.roller.ui.rendering.velocity.deprecated.RedirectServlet.doGet(RedirectServlet.java:131)

I tested AppFuse 2.0 on Tomcat 6.0.10 earlier today and impressed that 1) Cargo worked perfectly and 2) most of the web frameworks worked. Which one didn't? You guessed it - good ol' JSF. That's OK though, the JSF version of AppFuse (MyFaces 1.1.5 with Facelets 1.1.11) doesn't work with Jetty 6.1.1 either. The good news is I found a workaround - removing the el-api dependency from my pom.xml makes it work on both.

    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>el-api</artifactId>
        <version>1.2</version>
    </dependency>

If I remove this dependency, everything works fine on Tomcat 6.0.10 and Jetty 6.1.1. Unfortunately, it seems this dependency is needed for Tomcat 5.x. Hopefully some fancy stuff with Maven profiles can fix this incompatibility.

Posted in Java at Mar 02 2007, 12:44:46 AM MST 10 Comments

Steamboat: 5 Feet in 5 days!

From Steamboat's Snow Report:

Over 5 feet of snow in 5 days! I'm still trying to catch my breath. It was lost hours ago in the 16" of fresh glorious snow at the top of 3 O'clock trees. Still breathing hard...

If your not skiing sweet turns through the trees today kick yourself. The snow is bottomless and the skies are still snowing. Looks like Mother Nature is going to keep the white stuff falling for the next few days.

We're heading up tomorrow night - sounds like it's going to be an epic weekend. I might have to buy new powder skis! :-D

Photo of the Day - 2/28/07
Steamboat Photo of the Day

Posted in General at Feb 28 2007, 12:49:37 PM MST Add a Comment

Airport Extreme

Airport Extreme Even though I managed to get my home network speedy again after my bandwidth speed issues, I bought a new Airport Extreme last week. My main reason for buying it was its USB device sharing feature. I have a Suse 10 box that runs Samba, DHCP, DNS right now, but for some reason, my MacBook Pro doesn't work for printing to CUPS over Samba. In my experience, printing is one of the major issues with Macs - it just never seems to work when you want to print over a network. I have gotten it to work in the past, but it's often been a wretched weekend's adventures where I end up sacrificing a goat to the CUPS gods to get everything working.

So by buying an Airport Extreme, I figured I'd have an Apple product at the center of my network and all my problems would be solved. I was wrong.

First of all, why can't there be a web interface on this sucker? Why does it require that I have a client installed to configure it? With most routers I've worked with in the past (NetGear and Linksys), the web interface might've been clunky, but it didn't require I install a CD. I initially tried installing the software on Windows XP, but for some reason it wasn't able to communicate. So I installed it on my Mac and was able to configure everything. While the setup process worked, and I was able to access the internet afterwards, this device doesn't seem to work well with my network. After plugging my printer in (an HP OfficeJet G85), I was able to add it on both XP and OS X using Bonjour. However, no matter what I sent to the printer, it'd never print. Further gripes: it might have an integrated firewall, but there doesn't seem to be a way to configure it. I couldn't find any way to do port forwarding. This stuff is so simple to do on my Netgear router.

At this point, it seems logical to return my Airport Extreme as it simply doesn't work as expected. Of course, my frustration could be from my lack of knowledge, but that's the point - I shouldn't have to read the documentation or contact Apple Support - it should all just work.

Posted in Mac OS X at Feb 28 2007, 09:23:29 AM MST 35 Comments

The Good Seats

There's nothing like getting the good seats when you attend a sporting event or concert. This weekend, we had 4th row seats to the Nuggets game on Friday night, 2nd row to the DU Hockey game on Saturday night and first row to The Doodlebops show on Sunday. Believe it or not, The Doodlebops was probably the most fun. The fact that smiles were plastered on Abbie and Jack's faces made it great, but also Abbie got to give Mo a high five and both kids were dancing like they actually knew how. Fun stuff.

Next weekend looks to be great as well. It's dumping in the hills - Steamboat got around 4 feet of powder last week. The forecast is snow all week, with Spring-skiing temperatures this weekend. We're heading up at the end of week, so I'm crossing my fingers hoping for mounds of champagne powder. In the meantime, it's time to start coding like a madman on my new project where I'm building an e-commerce site with AppFuse 2.0.

Posted in General at Feb 26 2007, 05:15:36 AM MST 6 Comments

Upgrading to MyFaces 1.1.5 and Spring 2.x + Resin 3.x + Cargo

This week, I encountered a few issues with some open source software that I hadn't seen before. Furthermore, it was difficult to find the problems' solutions via Google, so I figured I'd blog about them and make life less painful for the next person.

Upgrading MyFaces to 1.1.5
The first issue I experienced was when I tried to upgrade from MyFaces 1.1.4 to 1.1.5. After upgrading, my Canoo WebTests failed on some pages because the page kept redirecting to itself instead of submitting a form and properly processing the result. The solution was found with a simple e-mail to the project's mailing list. If you have a view template that auto-submits to a backing bean, you need to change "_link_hidden_" to "_idcl". Apparently, this change was made to be more similar to the JSF RI. Of course, this hack wouldn't be necessary if JSF would simply allow you to call a method from a URL without going to a view page first.

Spring 2.0's RequestContextListener has issues on Resin and WebSphere
Spring 2.0.2 has a bug where its RequestContextListener throws a NPE on WebSphere 6.0 and Resin 3.x. This is fixed in Spring 2.0.3.

Making Resin 3.x XSD-aware when using Cargo
By default, Resin 3.x doesn't ship with an XSD-aware parser turned on. This means that if you're using Spring 2.0 XSDs, you will need to set some configuration options on Resin. I don't know why Resin doesn't ship with these on by default, but it doesn't. This presents a problem if you're using Cargo to download and install Resin. The good news is you can configure Cargo to set system properties and turn Resin's XSD parser on. Adding the following to the <container> element in the Cargo plugin's configuration to solve the problem.

<!-- Make Resin aware of Spring 2.0 XSDs -->
<systemProperties>
    <javax.xml.parsers.DocumentBuilderFactory>
        org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
    </javax.xml.parsers.DocumentBuilderFactory>
    <javax.xml.parsers.SAXParserFactory>
        org.apache.xerces.jaxp.SAXParserFactoryImpl
     </javax.xml.parsers.SAXParserFactory>
</systemProperties>

Resin and Cargo
Finally, Cargo 0.2 throws a NoClassDefFoundError when shutting down Resin 3.0.23 and doesn't work at all with Resin 3.1.0. What does this mean? It means Cargo works great with Tomcat and JBoss, but not so good with Resin 3.x, Jetty 6.x or Geronimo 1.1.

It's too bad, Cargo really is a great project idea. Maybe the container developers should get involved to help it support all the latest versions?

Posted in Java at Feb 24 2007, 04:33:20 PM MST 1 Comment

Message Driven POJOs by Mark Fisher

Last night, I attended the New England Java Users Group to see Mark Fisher talk about Message Driven POJOs. This was the first JUG I've been to (outside of Denver's) where I was an attendee instead of a speaker. It was interesting to see how they do things. They have one main speaker who speaks for two hours. After the first hour, they have a break, offer pizza and do a raffle. Then the speaker continues. They require you to "register" at least 48 hours before the meeting starts. This is because the meeting is held at Sun and they (apparently) need to do it for security purposes. They actually checked my ID and made sure I was registered at the door. After I passed their verification test, I received a name tag. While I like Denver's Basic Concepts followed by Main Speaker setup, I liked that this JUG meeting was over at 8:15. Below are my notes from the event.

Topics in this Session: Overview of JMS, Spring's JmsTemplate and implementing a Message Driven POJO.

Goals of JMS: provide a vendor-neutral abstraction for accessing Message Oriented Middleware from Java. It provides for enterprise messaging systems what JDBC provides for relational databases. See Wikipedia's definition of JMS for more information.

The API is what insulates your code from the JMS implementation you're using. The JMS implementation will use a message broker to communicate between servers. Tonight, Mark will be using ActiveMQ in his examples. He plans on doing most of his presentation in Eclipse because he's been spending 14 hours per day in PowerPoint revamping Interface21's training courses (I don't miss that at all).

The JMS Message is the central object to JMS. There's various types of messages, TextMessage, ObjectMessage (I missed the rest). Two types of JMS Destinations are available: Queues and Topics. A JMS Session is used to create messages as well as producers and consumers. Examples calls:

  • session.createTextMessage(String)
  • session.createConsumer(dest)
  • session.createProducter(dest)

A JMS Connection is obtained from a JMS ConnectionFactory. The ConnectionFactory is typically accessed by a JNDI Lookup.

JMS is most commonly used for internal application communications (not public facing).

Templates are common in the Spring Framework and are used to simply API usage. Their main goal is to reduce boilerplate code (resource management, try/catch, etc.). Examples include JdbcTemplate, JpaTemplate, JndiTemplate, TransactionTemplate and (you guessed it) JmsTemplate. Spring also translates exceptions to consistent runtime hierarchies. In addition to one-line methods, Spring's templates supply callbacks that alleviate try/catch blocks - but give you full power of the API.

JmsTemplate has a couple of capabilities: it handles acquisition and release of resources and translates checked JMS Exceptions to a parallel hierarchy of RuntimeExceptions. It's also capable of converting a payload to the corresponding JMS message type with a MessageConverter strategy. Lastly, it provides convenience methods to allow sending asynchronous messages.

Now Mark is showing us how you configure a ConnectionFactory, Queue and JmsTemplate in a Spring context file. The first couple of beans only take 3 lines of code to configure, the 3rd one takes 4 because it has a dependency on the first two. Pretty easy configuration if you ask me. After composing bean definitions, Mark created a JUnit test and called jmsTemplate.convertAndSend() to send a message in 2 lines of Java code.

To receive messages with JmsTemplate (pre Spring 2.0), you could use synchronous receive calls: receive(), receive(Destination) and receive(String). There are also receiveAndConvert() methods.

In Spring 2.0, they added the ability to do MessageListener containers to enable asynchronous reception in a non application server environment. Implementations include SimpleMessageListenerContainer, DefaultMessageListenerContainer and ServerSessionMessageListenerContainer. The DMLC adds transactional behavior, and the SSMLC hooks into the server's SPI. Spring's MessageListenerAdapter enables the delegation to a POJO for handling the payload.

For the next 1/2 hour or so, Mark wrote a bunch of Java and XML to create a simple Trader application. About the same time, I got managed to get an internet connection from somewhere and started browsing the net and answering e-mail. Every once in a while I looked up to see Mark's code - it all looks very simple and straight forward. In Spring 2.1, a <jms:*> namespace will be added to simplify the XML configuration.

For those of you out there using Spring's JMS support - are there any issues you've run into? Are you using it in production? It's always pimped as "awesome", so I'm looking for pain points that folks might encounter when using it.

Related: Spring's JMS Documentation and ActiveMQ's JmsTemplate Gotchas.

Posted in Java at Feb 23 2007, 11:25:59 AM MST 6 Comments

Comparing Java Web Frameworks at ApacheCon Europe

It's been almost 2 1/2 years since I created and presented my "Comparing Web Frameworks" talk at ApacheCon 2004. It's hard to believe that was my first talk in front of a large audience. Before that conference, I posted a list of possible topics, as well as an outline a few days later. The most recent time I presented this talk was at Spring Forward 2006.

At this year's ApacheCon Europe, I'll be presenting Comparing Java Web Frameworks again. This time, I'll be adding Wicket and Stripes to the mix. I'm adding these two because they seem to be getting the most hype in Java developer's blogs. Of course, it would be great to add Grails, RIFE and Seam, but that's just too much to cover in an hour. Also, Grails is just Spring MVC and Seam uses JSF - so RIFE is the only one that stands out as unique. Here's the current session description:

One of the most difficult things to do (in Java web development) today is pick which web framework to use when development an application. The Apache Software foundation hosts most of the popular Java web frameworks: Struts, MyFaces, Tapestry and Wicket. This session will compare these different web frameworks, as well as Spring MVC and Stripes. It will briefly explain how each works and the strengths and weaknesses of each. Tips, tricks and gotcha's will be plentiful. Lastly, it will provide attendees with a sample application that utilizes all 6 frameworks, so they can compare line-by-line how the frameworks are different. This sample application will include the following features: sortable/pageable list, client and server-side validation, success and error messages as well as some Ajax functionality. The frameworks will be rated on how easy they make it to implement these features.

Over the next couple months, I'll try to post a revised outline so all the folks who care about a comparison like this can voice their opinions. I'll also be integrating Stripes and Wicket into AppFuse and AppFuse Light.

I'm still not sure about the name "AppFuse Light", but it's probably better than "AppFuse LE" which doesn't seem to convey the concept enough. The problem with "Light" is how to spell it (Bud Light vs. Miller Lite). The nice thing about AppFuse LE is we can shorten it to ALE. Regardless, you gotta love how it can all be related back to beer. ;-)

I've never been to Amsterdam before, so I'm definitely looking forward to this trip. My dad will be joining me, so I'll probably do more site-seeing that conference-going. If you're from the area, do you have any suggestions on what to do and where to stay? My dad has been pricing tickets and thinks we'd be better off flying into Frankfurt, spending a few days in Germany, and then arriving a day or two before my talk (on Friday). However, Queen's Day is the Monday of the conference and I've heard rumors it shouldn't be missed. I've got some Dutch and German in my blood, so it should be fun to visit my ancestral homeland.

Posted in Java at Feb 22 2007, 04:44:43 PM MST 12 Comments

Seam Security's X509 Certificate Support

You gotta love Gavin's description of why Seam should support X509 certificates:

I have no idea what these things are, but apparently people want to get them. Supposedly, they are nothing to do with certificates you get when you win something like a spelling competition in primary school. 'Cos if they were, we could have used Norman's PDF stuff. So anyway we can just steal code from Acegi. Then I can tell people "we've got a certificate for X509" in talks, and they will think I know what it is.

At least he's honest. ;-)

Update: Seam now has Spring support - very cool! FWIW, we talked a bit about Seam on the AppFuse mailing list today.

Posted in Java at Feb 22 2007, 10:41:13 AM MST Add a Comment

Java is more complicated than .NET ... unless you use AppFuse

From Java to .NET, Back To Java Again, My Little Impression of The Two:

Having said all these, integration of various java projects together really do take a lot of Java people's time, it's no joke, but it's not desperate. For example, the open source project "AppFuse" does a fantastic job integrating various frameworks for us, I strongly encourage everyone to give it a shot and see how much time it saves you.

So which platform do I like? My impression is Java offers a lot flexibility and choices, but at the same time introduced the "Paradox of Choices", having so many things and integrate them together is no easy task, it simply overwhelm the human brains. .NET on the other hand is in a controlled environment, less choices, but easy to develop.

In other words: Java development is way more complicated than .NET ... unless you use AppFuse. ;-)

Posted in Java at Feb 20 2007, 09:25:15 PM MST 5 Comments

NBA Fans are using AppFuse

Did you know that the Utah Jazz and LA Lakers Fan sites are powered by AppFuse? I've had a few beers with Eric (the guy who developed these sites) and he's finally given me permission to post links to both of them.

In addition to these sites, AppFuse also powers the Sacramento River Cats Fan Loyalty Portal. Eric notes:

You might want to mention in your blog that for LA and Utah, if you don't want to create an account you can just click on the demo link on the landing page to see what's inside. But you won't get to enter any of the contests and you'll miss some of the cheerleader pix. There's also a whole admin side for report generation and CMS, but of course that's restricted.

I wonder if Eric has any plans to develop a Denver Nuggets fan site? Julie and I have 4th row tickets to Friday night's game against the Jazz. Should be a fun game for sure. Go Nuggets!

Posted in Java at Feb 19 2007, 09:11:01 PM MST Add a Comment