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.

DB2 JDBC Driver

Since most folks come to this site from Googling errors, here's a new one for you - complete with a solution! When I tried to connect from OS X to a DB2 database today, I received the following error:

java.sql.SQLException: java.lang.UnsatisfiedLinkError: no db2jdbc in java.library.path
        at COM.ibm.db2.jdbc.app.DB2Driver.<init>(Unknown Source)

The reason this happens is because there are two JDBC Drivers for DB2 - the first is a native type-2 driver (signified by app in the classname) and the 2nd is a type-4 driver (signified by net in the classname). This page describes the difference between the DB2 JDBC Drivers.

To solve this issue, I changed my JDBC classname to be COM.ibm.db2.jdbc.net.DB2Driver and the error went away. Of course, the type-2 driver is faster, but since there is no client for DB2 that I can install on OS X, I'll still with .net. on the Mac, and .app. with the DB2 client on Windows. Of course, I prefer no client install - it just seems cleaner and easier to me.

The Next Day: I also discovered that it's very important that your db2java.jar file is really the db2java.zip file from the server. If the versions don't match (i.e. trying to connect to a 7.2 db with an 8.1 driver), it actually kills the JDBC Listener! What a pile of...

Posted in Java at Jan 12 2004, 05:57:34 PM MST 1 Comment

The Verge Web Framework

After reading this post on the Server Side, I'd hate to be the guy who invented Verge. He's getting pounded like a rabbit during mating season!

Personally, I don't think there's anything wrong with another web framework. Competition is good. The funny thing is that I've never had a need to migrate away from Struts. I do admit that the IoC (Inversion of Control) in WebWork looks cool, but I don't have a need. After reading most of Rod Johnson's J2EE Design and Development, I do understand IoC (I didn't have a clue before), but I still don't see how I need it. I've never run into a problem with Struts that I couldn't solve. Maybe it helps that I've written my own app to make Struts development simpler.

Even though I do like Struts, and I do find it easy to develop with, I also plan on stuffing my head in a couple of books and learning all about Spring, Tapestry and WebWork. Why? Mainly because I'm a fool and I can't be happy just sitting on the couch and watching TV (which would probably help my blood pressure and make my family happier). I'm a fool because I'd rather learn than relax. Back to the point - why do I want to learn these "big 3?" To be honest, it's primarily because some big names (and folks I'd consider friends) are saying they're cool and they'll make my job easier. If only I wasn't so easily influenced...

What I hate about all of this is that as soon as I decide to integrate Spring into AppFuse, it becomes more complicated. Yes, an XML BeanFactory file is more complicated than Interface i = new InterfaceImpl(), especially for newbies.

Furthermore, I'm willing to bet that I'll end up writing workarounds for issues I encounter in Tapestry and WebWork. I'll even put my money where my mouth is - if your framework doesn't require me to write any workarounds, I'll donate $100 to the project. Heck, if it really is that cool - I'll donate money regardless of workarounds.

The worst part is that there's really no reason to convert my Struts webapp to these newer, cooler frameworks. About the only good reason is so I can say "I know the XXX Framework." I doubt XXX Framework will make anything easier, but it certainly might make my webapp a whole lot cooler. wink

Posted in Java at Jan 12 2004, 03:57:49 PM MST 13 Comments

AppFuse on DB2 and WebSphere

I did some trial-and-error this morning, and with the help of a lot of handy-dandy unit tests, I got [Appuse working on DB2|AppFuseOnDB2]. I learned that I need to figure out how to create a database with page size = 8 by default - anyone got a SQL script to create DB2 databases (with reasonably sized table spaces) lying around?

Next up: Getting AppFuse running on WebSphere 5.1, this should be fun. Especially considering that they only seem to support .ear files, not .war files. I've only glanced at the thing for 5 minutes - any advice/links would be awesome.

Posted in Java at Jan 12 2004, 10:23:11 AM MST 9 Comments

iLife - not in stores until Friday (1/16/04)

Abbie and I drove around for a 1/2 hour this morning waiting for the Apple Store to open at 11. When we got there, I woke up the beautiful one (she fell asleep while driving) and went into buy iLife. No such luck, it won't be in stores until Friday. Those bastards! Hopefully, this will prevent you from wasting your time like I did.

Posted in Mac OS X at Jan 11 2004, 12:47:59 PM MST Add a Comment

Should I buy a PowerBook or a PC?

I received the following e-mail from Jason Boutwell a couple of days ago (published here with his permission).

I'm in the market for a new development laptop, either a P4 or a G4. I see from some of your older blog posts that you went through the same thing last year. First you went with a P4, then ended up with a PowerBook, so you've done both.

Since we seem to have similar professional interests (jobs where you BYOL, developing J2EE apps with tools like Hibernate, Struts, XDoclet, IDEA, etc.), you seem an ideal person to ask.

It's as simple as this: you can't beat the form-factor of the PowerBook. The fact that it's so small and light really make it a killer laptop. iPhoto, iMovie and iTunes are all killer apps and make digital photography and video so much easer. However, as a development environment - it sucks. It's sooooo much slower that my Windows XP desktop (that only cost $800).

My perspective of the speed difference might not be fair though - desktops (most likely) will always be faster than laptops. However, to run "ant deploy" for AppFuse takes 23 seconds on my 2.6 GHz CPU / 1.5 GB RAM desktop and 36 seconds on the PowerBook (1.33 GHz CPU / 1 GB RAM). It is difficult for me to develop on the Mac after developing on my PC for awhile, it's just so much slower. That being said, I don't think I'd be happy with a PC laptop - they're too ugly and bulky (for the 17" models) and don't offer the slick digital hub integration that the Mac does.

Don't expect the PowerBook to be a desktop replacement. And if you've never used a Mac, prepare to be frustrated. I've been a Windows user for 10+ years and getting used to the way a Mac works is not easy. It's been most frustrating for me because I can navigate around and do stuff on Windows really fast - it's almost like second nature. On the Mac, I have to think about how to do stuff. I think that Mac or Linux users migrating to Windows would feel the same frustration.

Above all else, you need to experience a Mac first hand. Go to your local Apple Store and play around with one. Download your favorite IDE and checkout an open source project from SourceForge. Download and install Ant and try compiling the project. You're gonna love the feel of the Mac, but you might find it's a bit slower than you're used to.

The one problem with not buying a PowerBook is that you'll always long for one. ;-) Would I buy a PowerBook again? Definitely. Would I give up my Windows desktop for a Mac desktop? No. Why should I give up all my years of becoming an efficient Windows user to be a slow-ass frustrated Mac user - it just doesn't make sense.

Posted in Mac OS X at Jan 10 2004, 05:58:17 PM MST 23 Comments

SourceBeat - would you buy a subscription?

I came across this site last week and I'm wondering what Java developers think of it?

SourceBeat Logo

How it works differently than the traditional publishing model is that instead of buying one static book, users will subscribe to a particular book for 12 months. The expert authors provide updates each month on their respective topics, ensuring that you always have the latest and greatest information on your topic. No more buying multiple books on the same topic in order to cover all the areas you need. In addition, as a subscriber you can interact with the author through list servers and weblogs. This way you can let them know your thoughts on current items and also what you would like to see in future updates.

It sure sounds like a good model, but would you buy a subscription? Personally, I hate online books (HTML or PDF) because I like to have a book in front of me. I like to take books to the library or to a quiet room, eliminate distractions, and read. If I'm on the computer reading, I get distracted and end up reading blogs or writing code. The model seems cool though - the ability to shape an authors writing and get them to cover topics on whatever technology you're subscribed to. It'd be cool if it was only $29.95/year for all books rather than each book, but it's probably still cheaper than buying books from your favorite bookstore.

Posted in Java at Jan 10 2004, 05:51:16 PM MST 1 Comment

What should I learn next?

I received an e-mail a few minutes ago from an old friend. We used to work together at eDeploy, which has finally gone out of business, 2.5 years after they closed their doors. This was my last full time job and was also my favorite job of all time. I rode my bike to work, got to learn Java, wore shorts all the time, and thoroughly enjoyed our Friday lunches.

His questions were fairly simple:

  • What is the best way to find a Java job/contract in Denver?
  • Since you've had a lot more exposure to what technologies are being used more than others, is there somethings that I should brush up on while I've got the time off (i.e. struts, xslt, EJBs, . . .)?

I wrote a long answer and thought others might be able to benefit from it - so here it is (please add your own advice as you see fit):

What I'd recommend is to subscribe to the following local mailing lists:

RMIUG Jobs: RMIUG Jobs: http://rmiug.org/html/email_lists.html
DJUG Jobs: http://www.denverjug.org/resources/mailinglist.html

They get a fair amount of jobs that come across the wire, and I actually got 2 gigs last year through the RMIUG list. Struts is definitely one of the hottest skills, but I continue to get a lot of calls as a UI/Java Developer. Having the ability to write clean and pretty HTML as well write Java seems to be rare. To complement Struts, I'd focus on JSTL and JSP 2.0. You can't go wrong learning more about Ant and JUnit - I think a lot of people know JUnit, but not many put it on their resume.

You could check out my AppFuse application which uses all of these, as well as Hibernate (another hot one) for the persistence layer.

I started writing AppFuse when I wrote a couple chapters for Pro JSP last year. I use it on all my projects and it really helps accelerate the whole JSP/Struts/JUnit/Tomcat development cycle.

I'd also recommend reading a couple of really great books:

Java Development with Ant: a truly awesome book
Pro JSP: of course ;-)
J2EE Design and Development: I'm reading it right now

EJBs are a thing of the past - you might be able to get a gig doing them, but they're definitely waning. Rod Johnson (author of the 3rd book) wrote the Spring Framework as part of the book, and it's a pretty slick framework for taking the ugly out of J2EE. The project is getting a lot of press, and I hope to use Spring pretty soon to bind all my components together in AppFuse.

Above all else, I recommend starting to read weblogs (a.k.a. blogs), and if you like it, start your own. The best place to start reading them is JavaBlogs, JRoller and Java.net. I'm a committer on the open source project (Roller Weblogger) that runs JRoller. It's some damn slick blogging software. I host my site at KGBInternet for a measly $20/month and I get my own instance of Tomcat to screw up. Reading blogs is definitely the best way to stay on the bleeding edge of Java (and any other industry for that matter).

Posted in Java at Jan 09 2004, 12:38:04 PM MST 1 Comment

The Battle of the GZip Filters

When I first added a Compression/GZip filter to AppFuse, I used the one from Roller, which I believe Lance found in this book. This has worked fairly well since I added it in July last year. When I discovered that there were issues with it on Resin, I chaulked it up as "no big deal" since I don't use Resin anyway. But yesterday, when I discovered that it stopped my apps from displaying my 403 <error-code> page, that was the last straw. I remembered seeing the "Two Servlet Filters Every Web Application Should Have" article on ONJava.com about a different implementation, so decided to download the source and try it out.

I quickly discovered that this Filter does work on Resin, so that's quite a bonus. I've had issues getting Roller to work on Resin with the Filter enabled, so I might have to replace Roller's CompressionFilter. However, I did still have to change a few things to convince this Filter to satisfy my needs.

Here are a few things I discovered about this GZIPFilter vs. Roller's CompressionFilter:

  • Don't download the GZIPFilter from the article. There is a newer version of the code. Not much has changed, save for an almost completely re-written GZipResponseStream.java file. This one supposedly does better handling of large files.
  • This Filter has the same problem I experienced with Roller's CompressionFilter: JSP pages don't finish rendering when running my Canoo WebTests. I'm assuming that this is because the buffer hasn't finished spitting out HTML. I ended up writing a new isGZIPSupported() method (in GZIPFilter.java) to do the check for GZip support. This allows my webtests to run smoothly by disabling the filter for HttpUnit.
  • This Filter shares another issue that I found in the CompressionFilter yesterday. When my webapp returns an HttpServletResponse.SC_FORBIDDEN error code (from trying to access a method that denies the users role), the Filter suppresses the error and the user is not served up the 403 error page defined in my web.xml. To fix this, I overrode sendError() in GZIPResponseWrapper.java and added a check for this error code in the getWriter() method.

Overall, I'm pleased with this code because I love the concept of GZip Filtering, and now it's not causing any conflicts in my app or targeted appservers.

GZIPFilter.isGZIPSupported(HttpServletRequest):

    private boolean isGZIPSupported(HttpServletRequest req) {
        String browserEncodings = req.getHeader("accept-encoding");
        boolean supported =
            ((browserEncodings != null&&
            (browserEncodings.indexOf("gzip"!= -1));

        String userAgent = req.getHeader("user-agent");

        if (userAgent.startsWith("httpunit")) {
            if (log.isDebugEnabled()) {
                log.debug("httpunit detected, disabling filter...");
            }

            return false;
        else {
            return supported;
        }
    }

GZIPResponseWrapper.sendError(int, java.lang.String):

    public void sendError(int error, String messagethrows IOException {
        super.sendError(error, message);
        this.error = error;

        if (log.isDebugEnabled()) {
            log.debug("sending error: " + error + " [" + message + "]");
        }
    }

GZIPResponseWrapper.getWriter():

    public PrintWriter getWriter() throws IOException {
        // If access denied, don't create new stream or write because
        // it causes the web.xml's 403 page to not render
        if (this.error == HttpServletResponse.SC_FORBIDDEN) {
            return super.getWriter();
        }

        if (writer != null) {
            return (writer);
        }

Posted in Java at Jan 09 2004, 11:30:43 AM MST 15 Comments

Cactus and Form-Based Authentication

Quick Summary: Did you know it's possible to login (with form-based authentication) before running each of your testXX methods in a ServletTestCase or CactusStrutsTestCase? Just add a "begin" method in your Base class, or in each of your Tests, and it will be called automatically, just like setUp() is called.

    public void begin(WebRequest request) {
        request.setRedirectorName("ServletRedirectorSecure");
        request.setAuthentication(new FormAuthentication("tomcat","tomcat"));
    }

Long and Winded: Yesterday, I began adding the "roles" attribute to my Struts action-mappings - to limit access for certain user roles (Yes, XDoclet 1.2 supports this). This worked great in my web UI, until I tried to run my StrutsTestCases. Access was denied because I was not logged in. Rather, I was "faking it" by retrieving a UserForm object in my setUp() method and stuffing it into the session [View Source]. This worked like a charm until I added the roles restriction.

Cactus has a nice feature: if you write a beginXX method, it will be called before your testXX method. In other words, begin = client, test = server. So I added a number of beginEdit, beginSave, etc. method to my Action Tests. Great - everything worked. But it was ugly to add all those beginXX methods. Then, via Vincent Massol's wisdom, I learned of the global begin(WebRequest wr) method. Now I simply have a begin() method in my BaseStrutsTestCase class, and everything works as smooth as pie.

    public void begin(WebRequest request) {
        request.setRedirectorName("ServletRedirectorSecure");
        request.setAuthentication(new FormAuthentication("tomcat","tomcat"));
    }

A couple of issues I discovered:

  • If you have an Action that doesn't have any roles in any of it's mappings, this will fail, so you have to override the begin() method with an empty {} method in your *Test.class. I believe the error message was it couldn't find the SecureServletRedirector.
  • You must define all the roles (you plan to authenticate with) in your Ant build.xml file. [Read More]
  • My <error-code>403<error-code> is not working on AppFuse or the current real-world app I'm working on. [Read More]

All in all, I'm pretty pumped that Cactus makes it this easy to test my app in its true production environment.

Later: I figured out the source of the 403 error-page not rendering. Once again, my Compression Filter does more harm than good. I switched it out for a more recent GZIPFilter and the same thing happens. The good news is that the new filter works on Resin, whereas the old one did not.

Posted in Java at Jan 08 2004, 01:46:32 PM MST Add a Comment

Hacked (Again)

This morning, a reader was kind enough to let me know that this website has been hacked.

The web pages at http://raibledesigns.com/tomcat/ with information about Apache, Tomcat and load balancing have been defaced.

I've contacted my sys admin and will hopefully get these files restored in the next few hours. I could do it myself, but I want to 1) see if this is a widespread problem (i.e. not just me) and 2) make sure all my defaced files are replaced. I got hacked a couple of months ago too, and I believe the same files were defaced. If it's another ISP issue, vs. someone logging in as me - it might be time to make the leap.

Posted in General at Jan 07 2004, 06:18:41 AM MST 4 Comments