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.

RE: Jetty Ant Plugin

It looks like Jetty has a new Plugin for Ant. If you've used the Jetty Maven Plugin, you know this is a slick way to quickly deploy your application. For those of you wondering about Tomcat, there's a similar Tomcat Maven Plugin that supports tomcat:run and tomcat:run-war. However, it's still in Mojo's sandbox.

I'm pumped to see this Jetty task for Ant because I've been thinking a lot about creating an exploded, full-source archetype for AppFuse 2.0. Of course, it's probably possible to start Jetty and monitor your project for changes w/o this task - but it does seem to make things a fair amount easier. If we do a full-source archetype, it makes sense to support Ant as well - especially since we can probably re-use the build.xml from AppFuse Light.

This brings up a related questions I asked on the AppFuse mailing list yesterday:

A couple of questions for folks using (or planning to use) 2.x:

1. As far as archetypes go, are you using basic or modular?

2. If there was a 3rd type of archetype that included the full source (like AppFuse 1.x), would you use it over the existing basic or modular archetypes? If yes, I'm assuming upgrading is not that big of an issue for you?

If you've tried AppFuse 2.x and would like to answer these questions, please add a comment.

There's another questions about Selenium vs. Canoo WebTest in that post, but that's reserved for another entry where I'll talk about Selenium options in Maven 2.

Posted in Java at Mar 08 2007, 08:13:08 AM MST 3 Comments

Zero Configuration in Struts 2

Struts 2 has a nifty zero configuration feature. However, it's only useful for registering actions, not for automatically registering results. In other words, you still have to use an @Result annotation to tell your action what page to dispatch to. To use default view names instead of requiring @Result, you can use the Codebehind Plugin. Also, did you know Struts 2 will autowire your Spring dependencies? It's pretty slick.

What does this all mean? It means you can write your Struts 2 application without writing any XML. Of course, you can still use XML to tweak behavior, but with these plugins enabled, you won't have to.

IMO, these plugins should be combined into a single zero configuration feature.

Here's how you can enable Struts 2's Zero Configuration feature in AppFuse 2.0:

  1. Add a packageNames parameter to the "struts" filter in your web.xml:
    <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
        <init-param>
            <param-name>actionPackages</param-name>
            <param-value>com.company.newapp.webapp.action</param-value>
        </init-param>
    </filter>
    
  2. Add the Codebehind Plugin as a dependency in your pom.xml:
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-codebehind-plugin</artifactId>
        <version>2.0.6</version>
    </dependency>
    
  3. Add a struts.codebehind.pathPrefix constant in struts.xml for your default pages directory:
    <constant name="struts.codebehind.pathPrefix" value="/WEB-INF/pages/"/>
    

That's it - now you can code away without configuring anything!

How does this compare to other web frameworks in AppFuse? Tapestry has a similar feature, but Spring MVC and JSF don't. Spring MVC still requires you create a bean definition for Controllers and JSF requires you write a chunk of XML for each managed bean. Of course, if you know how to do something similar with Spring MVC or JSF, please let me know.

Posted in Java at Mar 07 2007, 05:19:18 PM MST 9 Comments

Artifactory - a new Maven 2 Repository Manager for Enterprises

From the Maven 2 user list:

We would like to announce the immediate availability of Artifactory, a Maven 2 enterprise proxy.

Artifactory offers advanced proxying, caching and security facilities to answer the needs of a robust, reproducible and independent build environment using Maven 2. It uses a JSR-170 Java Content Repository (JCR) for storage, which makes it extremely easy to manage searchable metadata, and provide extended features such as security, transacted operations, auditing, locking, etc.

Artifactory is distributed under APLv2 at http://artifactory.sourceforge.net. It is currently available as a downloadable archive, that can be run out of the box (with default settings). An install script to run it as a Linux service is also provided. A (limited) guest live demo is available at http://www.jfrog.org/artifactory (username/password is guest/guest).

You are welcome to give it a go!

Cheers,

Yoav Landman,
The Artifactory Team

So how does this compare to Archiva, Proximity and Maven Proxy? One user writes (formatted for better reading):

My experience so far:
  • Archiva: Alpha; doesn't work (random webdav deployment failures), loads of bugs, low rate of progress. Feels dead.
  • Proximity: Works; slightly confusing (don't like the separation of metadata); lots of new releases constantly; hard to configure (hacking around with spring config files) - our install takes *forever* to restart.
  • m2proxy: simple, but simple.
Fingers crossed that artifactory hits the sweet spot...

It's interesting to see that Artifactory's UI is powered by Wicket and Dojo. The demo seems kind of sluggish, but I don't believe this application is meant to handle more than 10 users at a time. For more information on Artifactory's features, see its introduction page.

It's great to see a (seemingly) good tool come out for internal repository management.

I spent a couple days last week analyzing the best open source continuous integration server for Maven 2 projects. Hudson turned out to be the clear winner with the best UI and easiest setup. It also actually worked, which is a lot more than I can say for Continuum. While I did get Continuum to work, it required turning on anonymous SVN (no, putting the username/password in the URL did not work). CruiseControl worked as well, but required config.xml knowledge, which sometimes scares admins. Pulse and Bamboo continue to be the best commercial Maven 2 testers, while TeamCity failed my 10-minute test (twice!). One of the features I was looking for was Trac integration and that only exists for CruiseControl and Continuum.

It's amazing to see projects like Continuum and Archiva. If they're any reflection of the Maven team's ability to develop software, that's frightening. My advice: discontinue both of these projects as they're a waste of anyone's time to even research them.

Update October 2009: Fast forward a couple years and I take back what I said about the Maven's team ability to develop good software. Nexus is a kick-ass Repository Manager.

Posted in Java at Mar 05 2007, 07:35:00 AM MST 24 Comments

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