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 "java". 1,857 entries found.

You can also try this same search on Google.

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

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

New Phone - BlackBerry Pearl

BlackBerry Pearl Yesterday I picked up a new phone - a BlackBerry Pearl. The main reason I got it is because I couldn't get my e-mail with my old phone. It seemed like I was tethered to my computer all the time when I was waiting for an important e-mail. Now I feel free. Not only does it works great as a Bluetooth Modem, but it also supports browsing the internet and all of Google's Mobile apps (GMail, Google Talk and Google Maps). Even cooler - when you add a bookmark to a page that has an RSS feed, it detects that and allows you to add a "Web Feed" or a Bookmark. When I added this site as a web feed, it prompted me for Atom Entries/Comments or RSS Entries/Comments. It also allows you to auto-synchronize with your bookmarks or feeds. In other words, it has a built in feed aggregator. With a $20 unlimited data plan from T-Mobile, I love this phone!

The BlackBerry Pearl doesn't work with iSync, but PocketMac seems to do the trick. Unfortunately, PocketMac makes you synchronize with a USB cord whereas iSync uses Bluetooth. The Missing Sync for BlackBerry may solve this problem, but with everything else being free, I don't know if it's worth shelling out $40 so I don't have to plug in.

Some of you may ask, "Why didn't you just get a smart phone with EVDO built in?" The reason I didn't do this is I had a Verizon EVDO card. We were up in Steamboat for a week in January and it absolutely sucked. I worked for 3 days while were were up there (8-12 hours per day) and it was way too slow for me. The average speeds where 120KB/sec and I can easily get those with the Bluetooth Modem on the BlackBerry. Also, I don't want a fully-functional mini-computer for a phone, I just want it for basic calling functionality and the ability to check my e-mail.

What about the iPhone? I'm sure this phone will kick ass, but the fact that it won't support J2ME means that Google's apps won't work. Of course, they'll probably create widgets that'll work on the iPhone, so that argument may be invalid in a few months. The biggest reason I don't like the idea of having an iPhone is one thing - Cingular. I had AT&T as my carrier for a couple years and their customer service was beyond awful. Whenever I would call them for help, it'd take anywhere from 15-45 minutes before I talked to anyone. Today, when I called T-Mobile to get my BlackBerry Internet service setup, they told me the wait would be 6 minutes and they'd call me back when it was my turn. I was very impressed. I hope more phone systems start using a "call me back" feature instead of the current "wait on hold for X minutes" debacle.

So I'm very happy with my new phone and anxious to use it in my travels next week. Where am I going? I signed a contract with a company out in Massachusetts to help them architect and implement a Java-based web infrastructure across all their projects. The initial scope is estimated to be 2-3 months. I'll be flying out to Boston periodically, but most of the time I'll be working from home. I had a number of very interesting full-time opportunities, but the gig I'm taking seemed to be the most interesting technically. With any luck, I'll make it to the New England JUG on Thursday night to hear Mark Fisher's talk on Message-Driven POJOs.

Update: I just found NewsGator Go! for J2ME. I use NetNewsWire on my Mac and FeedDemon on Windows, so it's great to see I can subscribe to my existing feeds on my phone. Thanks NewsGator!

Posted in General at Feb 17 2007, 06:07:08 PM MST 3 Comments

Database Profiles in AppFuse 2.0

Last night, I added several database profiles to AppFuse 2.0 and its archetypes. What does this mean? It means AppFuse should work out-of-the-box with several databases, including:

  • H2
  • HSQLDB
  • MySQL
  • PostgreSQL
  • SQL Server

For example, here's how to test a new AppFuse project works with H2:

mvn archetype:create -DarchetypeGroupId=org.appfuse -DarchetypeArtifactId=appfuse-basic-struts -DremoteRepositories=http://static.appfuse.org/repository -DarchetypeVersion=1.0-m4-SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject
Yeah, I wish there was a way to shorten this command (or prompt for choices) too.

After doing this, you can cd into the "myproject" directory and run mvn integration-test -Ph2. AppFuse 2.0 projects are configured for MySQL by default, so if you want to permanently activate one of these profiles, you can add the following between the <id> and <properties> section of the profile.

    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>

In addition to the profiles listed above, I tried to get Oracle Express and embedded Derby working. No dice on either one. I took a brief look at DB2 Express as well, but with a 400 MB download and 3 JARs required for its JDBC Driver - it seemed like a lot more trouble than it was worth.

Maven 2's build profiles are a powerful feature that we hope to make easy to use. For example, to test your new project with H2 and JBoss, you can simply run mvn integration-test -Ph2,jboss. Thanks to the power of Cargo, this will download JBoss 4.0.5, install it, and run all the Canoo WebTests within it. Of course, this will take a while the first time - especially since JBoss is a 77MB download. Fortunately, we allow you to change one small setting in your pom.xml and use an existing install instead.

Maven 2 is a kick-ass build/deploy/test tool once you figure it out. With AppFuse 2.0, we're doing all the "figuring out" for you. ;-)

NOTE: I would add more server profiles, but Cargo's Maven Plugin (version 0.2) has issues with Geronimo 1.1, Jetty 6.x and Resin 3.x. Strangely enough, Jetty's Maven Plugin version 6.0.0 works great, but 6.1.0 throws stack traces.

Update: Support for Oracle and Derby (in networked mode) has been added. We'll consider adding support for DB2 if IBM can figure out how to package their JDBC Driver into a single JAR.

Posted in Java at Feb 14 2007, 05:41:37 PM MST 27 Comments

Slick looking Confluence sites

You have to admit, both Wicket and Cayenne have nice looking websites. Did you know they're both backed by Confluence? Wicket has a Writing documentation page that explains how it works. Basically, they use the autoexport plugin to export their content to static files. If you configure this plugin to be invoked from a cron job, it's a great way to create a constantly updating dynamic-but-static site.

I believe there's a couple reasons Apache uses this setup: 1) it allows projects to customize the look and feel of their site w/o customizing how Confluence looks and 2) it reduces load on its servers since most content is served up statically. I've thought about using a similar setup for AppFuse's documentation, but I've run into a couple issues:

  • The autoexport plugin is pretty flaky. The latest release (0.13) doesn't work with Confluence 2.2.9. Strangely enough, the previous version (0.12) works fine. It looks like the author had a good run with this plugin when he created it (almost a year ago), but hasn't updated it since.
  • The dynamic tree menu doesn't get included in the export. If I could somehow include this tree (and the current theme) when exporting, it'd be very cool.
  • The new code macro works much better than the {code} macro, but it has exporting issues both with PDF and the autoexport plugin. I tried using the code macro, but it doesn't show any syntax highlighting when using an Adaptavist Builder theme.

Apache's setup for Confluence appears to be quite good. I wonder if we should use it for AppFuse? We don't have the bandwidth/load issues that they do - and we've managed to make the site look decent using Adaptavist Builder. I like having a single source of constantly changing documentation, rather than two sites, where one is static. I think this causes confusion for users if the documentation changes a lot. That being said, I would like to export the content for bundling and versioning with each release. I wonder if Atlassian is planning on fixing the new code macro exporting issue anytime soon?

Posted in Java at Feb 09 2007, 08:02:54 AM MST 5 Comments