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 "appfuse". 771 entries found.

You can also try this same search on Google.

First impressions of the ZX7

When I bought my PowerBook, it was at a disadvantage because all of my comparisons where not only Laptop vs. Desktop, but also OS X vs. Windows XP. With this laptop, it's really just Laptop vs. Laptop. First impression of this thing - it's HUGE! The screen is awesome and it's tough to watch TV and work on this at the same time. I was expecting better resolution (1400 x 900 max), but it's good enough. The keyboard rocks - it's actually a full size keyboard! I keep making typing mistakes because I'm used to the (smaller) PowerBook's keyboard. Even better - it's got a keypad! I really like the plastic piece where my wrists sit. On the PowerBook, this is metal - and it quickly got scratched up from my watch. The speakers are great (the PowerBooks sucked) and I dig the webcam at the top of the monitor (though it's a bit dark - maybe it's just cause it's night time). I like Hypersonic's setup - very minimal as far as packaging. All the CDs are on the hard drive as well as in a small bag, which was enclosed in a leather (or maybe it's pleather?) carrying case.

Now for the cons. It's heavy and hot - both which I expected. You gotta install Java - both OS X and Linux come with it installed. The embedded wireless card only seems to work when I'm 5 feet from my access point. I have a couple of wireless cards, so I plugged one in and now I'm able to write this from my living room. Hopefully Hypersonic will be able to fix that. I kinda like the CD drive on the PowerBook better - though it can be a real pain when you can't get a CD out. The power cord has a humongous adapter-thingy on it - makes me long for the rather small PowerBook's cord. No NetNewsWire - good thing I still have a PowerBook. There are two folders on my C-Drive (with GUID-like names) that I can't delete. That sucks - I've been here before and never found a way to delete them (save re-installing Windows). Also, the lit-up keyboard on the new PowerBooks is a nice feature that I could really use right now.

Lastly, the performance numbers for opening Photoshop and Eclipse:

  • Opening Photoshop 7.0: 5 seconds
  • Opening Eclipse 3.0 M2: 5 seconds

Damn, not the performance jump I was hoping for. I'll post AppFuse and Roller compilation numbers when I get everything setup. Here are numbers to compare against the 2 GHz desktop I have at work. Am I happy with my decision? You bet - it's a wicked laptop.

Posted in General at Aug 06 2003, 10:17:31 PM MDT 3 Comments

RE: Which new laptop would you buy?

Thanks to all who left comments about my (possible) new laptop purchase. I did some more tests today, and I'm going to have to go with a Windows machine, especially since I hope to replicate the performance I get from my machine at work (Dell Optiplex GX260: 2 GHz, 512 MB RAM, Windows 2000 SP4):

  • Opening Photoshop (7.0): 3 seconds
  • Starting Eclipse (3.0 M2): 6 seconds
  • Running "ant clean package-web" on AppFuse: 18 seconds
  • Running "ant rebuild" on Roller: 36 seconds

Yep, that's right, my (work) desktop is twice as fast when opening Eclipse and 4 times faster opening Photoshop (than the Powerbook). So if I get a 3 GHz laptop with 1 GB RAM, it should be even faster than that right?

Hibersonic Aviator ZX7 Alienware Area-51m

Right now, I'm looking at the Alienware Area-51m or the Hibersonic Aviator ZX7. At first glance, I'm leaning towards Area-51m, although the Bluetooth USB Adapter (vs. integrated Bluetooth) is disappointing. The Hibersonice has a 17" screen, but that doesn't seem to be that big of deal (after hearing y'all speak up). Also the Hibersonic has a 802.11b NIC, where the Alienware one has a 802.11g.

Posted in General at Jul 22 2003, 09:11:05 AM MDT 5 Comments

Which new laptop would you buy?

If you could pick between a new Dell Laptop or a new Powerbook, which would you choose? If performance was your top priority? If you were going to buy a Windows-based laptop, which would you buy (doesn't have to be a Dell)?

Powerbook Dell Inspiron 8500

Update: OK, I'm at the Apple Store, on a 17" Powerbook with 512 MB of RAM. Let's do some performance numbers. If you have a laptop that you think I should get, post your numbers as a comment.

  • Opening Photoshop (7.0.1): 13 seconds
  • Starting Eclipse (3.0 M2): 12.5 seconds

Posted in Mac OS X at Jul 21 2003, 10:11:34 AM MDT 17 Comments

HowTo: Upgrade your app to JSP 2.0

I did some more playing with Tomcat 5.0.4 today - and converted appfuse to a JSP 2.0 application. After accomplishing this task, I created a "jsp-2" task that can (optionally) be run at build time, and whalla, you've got a Servlet 2.4/JSP 2.0 application. I learned a number of things in the process.

1. The expression language in JSP 2.0 replaces in JSTL is <c:out>, that's it. I was under the impression that I could use <c:if> or <c:forEach> tags without declaring the tag library URI, etc. I was wrong, if you want to use JSTL tags, you must import the declare the taglibs, just like you do now in Tomcat 4.x.

2. The EL is turned off by default if you have a 2.3 DTD for your web.xml. If you have a 2.4 XSD in web.xml, the EL is turned on by default. This means that you can write ${param.foo} and it will be analyzed when the EL is on (when off, it's not analyzed).

3. You can replace <html:rewrite page=""/> with <c:url value=""/> and get the same effect. The only difference is that html:rewrite is context and module-sensitive, whereas c:url is only context-sensitive.

4. I had to replace the URI's for JSTL core and fmt with their run-time URIs - http://java.sun.com/jstl/core_rt vs. http://java.sun.com/jstl/core. Otherwise, I would get something similar to the the following error.

According to TLD or attribute directive in tag file, 
  attribute test does not accept any expressions

I figure upgrading to JSTL 1.1 might solve this issue, but since it hasn't been released, why bother? So to convert appfuse to be a JSP 2.0 webapp, here's what my Ant task does:

  • Replaces URIs with their run-time equivalent.
  • Removes <c:out> tags, leaving the value of the "value" attribute intact.
  • Replaces 2.3 DTD in web.xml with 2.4 XSD.

I did some (rough) benchmarking of running my JSP tests, here are the results on a Pentium IV (2 GHz, 512 MB RAM).

start Tomcat, run tests, stop Tomcat:
 Tomcat 4.1.24: 1 minute, 17 seconds
 Tomcat 5.0.4: 1 minute, 7 seconds
 Tomcat 5.0.4/JSP 2.0: 1 minute, 3 seconds

run tests, Tomcat already started:
 Tomcat 4.1.24: 33 seconds
 Tomcat 5.0.4: 22 seconds
 Tomcat 5.0.4/JSP 2.0: 22 seconds

According to these numbers, Tomcat 5 is quite a bit faster than 4.1.x.

Posted in Java at Jul 17 2003, 01:27:01 PM MDT 5 Comments

Fun with Tomcat 5.0.4

After reading Dave's post about Tomcat 5, I got interested and decided to try it out. For those that don't know, Tomcat 4.0.5 Alpha was released today. I figured out how to make AppFuse run through a series of steps. Basically, I had to put log4j.jar in $CATALINA_HOME/common/lib and appfuse.xml in $CATALINA_HOME/conf/Catalina/localhost. Details are on my wiki.

Posted in Java at Jul 15 2003, 04:14:15 PM MDT Add a Comment

Compression Filter Issues - EOFException

I'm having some issues with implementing a Compression Filter in my day-time project. It works fine via the browser (and in AppFuse/Roller), but not in one of my Webtests. I think this is because my response doesn't have anything in it, but who knows. From my log file:

CompressionFilter.doFilter(87) | Unzipped size: 0
CompressionFilter.doFilter(106) | Zipped size: 20

And then the lovely error message from my testcase:

[canoo] java.io.EOFException
[canoo]     at java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:200)
[canoo]     at java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:190)
[canoo]     at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:130)
[canoo]     at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:58)
[canoo]     at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:68)
[canoo]     at com.meterware.httpunit.WebResponse.defineRawInputStream(WebResponse.java:617)

I'm thinking I need to close a stream or something, but since it works fine via the browser - I'm stumped! Any ideas are appreciated. I can post the testcase if necessary.

Update: Richard Hill on the Webtest mailing list hooked me up with the solution. It turned out to be a bug in the JDK, which causes issues in HttpUnit. Here's the solution I used to workaround it.

Posted in Java at Jul 10 2003, 04:59:51 PM MDT 2 Comments

Changing Struts' bean:message to JSTL's fmt:message

I converted AppFuse to use JSTL's <fmt:message> tag instead of Struts' <bean:message> tags this morning. It was pretty easy. Here's the steps I took:

1. First, I added the following to metadata/web/seb-settings.xml:

<!-- Define the basename for a resource bundle for I18N -->
<context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>ApplicationResources</param-value>
</context-param>

2. Then I added the format tag to web/common/taglibs.jsp:

<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>

3. Finally, I did find/replace with <bean:message/<fmt:message.

4. I also had to change my title and header keys in web/WEB-INF/tiles-config.xml to remove the . from the bean names. In other words, I converted title.key and heading.key to titleKey and headingKey and also made the appropriate changes in web/layouts/baseLayout.jsp.

Easy as Pie!

Posted in Java at Jul 10 2003, 07:59:29 AM MDT 35 Comments

[ANNOUNCE] Struts 1.1 Final Released!

The Struts team is proud, and extremely pleased, to announce the Final release of Struts 1.1. This release includes significant new functionality, as well as numerous fixes for bugs which were reported against the previous release, and supersedes the earlier 1.0.2 version as the latest official release of Struts from the Apache Software Foundation.

Download Binary | Download Source | JARs Only | Release Notes

test-all:                                                                                                               
                                                                                                                        
BUILD SUCCESSFUL                                                                                                        
Total time: 8 minutes 10 seconds                                                                                        
[minime:~/projects/appfuse] matt%   

Results look good!

Posted in Java at Jun 30 2003, 06:17:31 AM MDT Add a Comment

Professional JSP 2.0 Update

Just in case anyone is interested, I thought I'd report on how Professional JSP 2.0 (now being published by Apress) is progressing. I received some initial feedback that my Struts/XDoclet chapter would not be included in the book, but would be a separate download (I'd still get paid for it though). Most of the reasons seemed to be indicating that the chapter was too advanced - newbies wouldn't get it. Personally, I hate reading newbie books, so why would I write a newbie chapter? I also hate simple sample apps, that's why I wrote a fully functional one. Anyway, I convinced them that this chapter did have value and now they are going to include it in the book, but as a case study rather than a regular chapter.

As for the security chapter, they said they really liked the content, but (again) the example was too advanced. I have been asked to remove XDoclet as a dependency since I don't explain it until the Struts chapter. This turned out to be a lot easier than I thought it'd be - only took me about an hour last night. I simply built the project with XDoclet, and then copied the artifacts (web.xml, generated ValidatorForms, struts-config.xml, validation.xml, *.hbm.xml, etc.) back into the source tree. I then tweaked the build.xml file to pick up the artifacts, ran "test-all" and voila - it worked?!

The lesson I learned from all this is that XDoclet is great for rapid development - but possibly only while you you are developing new features. Once an application stabilizes or development is discontinued (I don't plan on further developing security-example), it's pretty easy to strip out the XDoclet dependency and (probably) make it easier for users to understand.

Posted in Java at Jun 20 2003, 10:40:55 AM MDT 11 Comments

Using Struts' Declared Exceptions

With a little prodding from Erik Hatcher today, I took another look at Struts' Declared Exceptions feature. At the end of last year, I was wishing I could use declared exceptions to do chained exceptions for my Action classes. Basically, in each of my Actions, I have a try/catch wrapped around a call to the Business Delegate (example: UserAction.java). You'll notice that all the CRUD methods have the same catch block for exception handling:

} catch (Exception e) {
    e.printStackTrace();
    errors.add(ActionErrors.GLOBAL_ERROR,
               new ActionError("errors.general"));

    while (e != null) {
        errors.add(ActionErrors.GLOBAL_ERROR,
                   new ActionError("errors.detail", e.getMessage()));
        e = (Exception) e.getCause();
    }

    saveErrors(request, errors);

    return mapping.getInputForward();
}

After talking with Erik this morning, I decided to create an ActionExceptionHandler for java.lang.Exception. In my struts-config.xml, I added:

<exception type="java.lang.Exception" key="errors.general"
    handler="org.appfuse.webapp.action.ActionExceptionHandler"/>

I have "errors.general=The process did not complete. Details should follow." Here is the code for ActionExceptionHandler:

public final class ActionExceptionHandler extends ExceptionHandler {

    public ActionForward execute(Exception ex, ExceptionConfig ae,
                                 ActionMapping mapping,
                                 ActionForm formInstance,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
      throws ServletException {
        ActionForward forward = null;
        ActionError error = null;
        ActionErrors errors = new ActionErrors();
        String property = null;

        // Build the forward from the exception mapping if it exists
        // or from the form input
        if (ae.getPath() != null) {
            forward = new ActionForward(ae.getPath());
        } else {
            forward = mapping.getInputForward();
        }

        ex.printStackTrace();
        errors.add(ActionErrors.GLOBAL_ERROR, new ActionError(error.getKey()));

        while (ex != null) {
            errors.add(ActionErrors.GLOBAL_ERROR,
                       new ActionError("errors.detail", ex.getMessage()));
            ex = (Exception) ex.getCause();
        }

        // Store the errors and exception
        request.setAttribute(Globals.ERROR_KEY, errors);

        return forward;
    }
}

This allows me to remove my generic try/catches from my action classes - very slick IMO (or at least better than the code smell I had)! Of course, I still have some catch blocks that catch specific exceptions, but I can either (1) leave those intact, or (2) create another declared exception for that particular action/exception. I dig it and will be adding it (in short order) to AppFuse.

Update (June 23, 2003): Here's a more thoroughly tested code sample of this same class.

Posted in Java at Jun 19 2003, 05:55:20 PM MDT 3 Comments