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.

JCIFS and jWebUnit

On my current project, we're using JCIFS to integrate our application authentication process with NT Domain logins. While I found it quite easy to integrate, the one issue I found is I couldn't replicate the login process in a jWebUnit test. I tried setting the WWW-Authentication header to NTLM, but couldn't get it to work. The solution I ended up using is to subclass the NtlmHttpFilter and disable authentication when the User-Agent is "httpunit".

public class LoginFilter extends NtlmHttpFilter {

  public void doFilter(ServletRequest req, ServletResponse res,
                         FilterChain chain)
    throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequestreq;
        String userAgent = request.getHeader("user-agent");

        // prompt for login, except when jWebUnit is used
        if (userAgent == null || !userAgent.startsWith("httpunit")) {
            super.doFilter(req, res, chain);
            return;
        }

        chain.doFilter(req, res);
    }
}

Hopefully this is useful for others. If you've managed to get regular jWebUnit authentication working with NTLM, I'm all ears.

Posted in Java at Jan 20 2005, 09:34:41 AM MST 16 Comments

Using JasperReports with AppFuse and Spring

In Spring 1.1.3, support was added for using JasperReports with Spring MVC. Today, Gregory Beumer posted a nice overview of JasperReports. This inspired me to dig up Gilberto's post on How to integrate JasperReports with AppFuse. If you're looking for a reporting solution in your AppFuse-based application, and you're using Spring MVC ... enjoy! I plan on adding this to the wiki in the future, along with howtos for integrating JasperReports with Struts, WebWork, JSF and Tapestry. If you happen to know of tutorials for integrating JasperReports with these other frameworks, please let me know.

Posted in Java at Jan 20 2005, 08:12:04 AM MST 17 Comments

Riding to Work

One of the reasons I'm jazzed about my new gig is it's within (bike) riding distance from our house. Usually I start riding to work when it gets warm, which is usually in March or April. However, I used to ride to downtown to the Tivoli Theater when I worked there in college. Back then, I'd ride no matter what, and I worked there in the winter. A buddy of mine works downtown and he's been riding to work all winter - even when it was 0°F out. To make a long story short, I got motivated by him this weekend and decided to start riding my bike to work. Today it was 29°F and the ride was beautiful. Riding in the cold is a lot like skiing - you just have to be dressed for it. It only took 30 minutes, which is 5 minutes slower than the Light Rail and the same duration as the bus.

Posted in General at Jan 17 2005, 08:41:23 AM MST 5 Comments

Upgraded to Roller 1.0

Dave released Roller 1.0 yesterday, so I decided to spend 20 minutes and upgrade today. I have customized a few pieces in Roller and added a bunch of my own files, so I always build from CVS for this site. I did find a bug with twisty comments (fixed in CVS) when testing locally, but everything else appears to be working OK. Let me know if you see any issues and feel free to play with my test user if you like. Username is "test", password is "roller". Well done Dave!

Update: Remember Me seems to be broken. I thought I fixed it last week. I'll investigate further tomorrow.

Update 2: Strange... it works when I test it locally, but not on this site.

Solved: It turned out to be related to installing Roller as the root app, and only seems to affect Firefox. Fixed in CVS.

Posted in Roller at Jan 15 2005, 04:27:18 PM MST Add a Comment

AppFuse distributed with Gentoo Linux?

According to the Gentoo Java Roadmap, AppFuse is on the list of apps to integrate. Nice! I'm going to rebuild my Windows 2000 Server as a Suse 9.2 box in the next couple of weeks, but I might have to reconsider and go with Gentoo. I was going to buy a gig o' RAM for the box, but it looks pretty spendy.

Today I added another item for AppFuse 1.8 in the roadmap: create an installer using MyJavaPack that can install Ant, AppFuse, MySQL and Tomcat. Basically, give developer's a way to install and start developing with AppFuse in under 5 minutes. Let me know if you're interested in helping out with this.

Posted in Java at Jan 15 2005, 03:30:10 PM MST 4 Comments

G5 Powerbooks in July?

According to quite a few sources, Apple will be shipping PowerBook G5s in the next 6 months. The timing sounds right. Tiger will be shipping by the Developer's conference and they need to announce something big - so G5 Laptops sounds like a logical choice. I can wait 6 months - where can I pre-order a 17"?

Posted in Mac OS X at Jan 15 2005, 03:10:58 PM MST 7 Comments

Running Cargo from Maven

Yesterday, I integrated Cargo into our application so we could start/stop Tomcat before running our jWebUnit tests. I use Cargo in AppFuse and Equinox - which are both Ant-based. Since we're using Maven on our project, I had to do a bit of futzing to get Cargo integrated into Maven. I prefer to use the Ant tasks from Cargo than the programmatic API because it's nice to run your tests when you start Tomcat manually. If you use the programmatic API, and start/stop Tomcat in setUp()/tearDown() methods - your test will fail if Tomcat is already running.

Below is what I added to maven.xml. With this, we can run "maven test-web" to test our UI with Tomcat running or "maven test-tomcat" to start/stop Tomcat before running our tests. Now I just need to figure out the best way to configure the proper port in my jWebUnit test. I'll probably put it into project.properties and the read the value as part of my test. I've also included a "deploy" goal in this example to demonstrate an easy way to deploy to Tomcat.

    <property environment="env"/>
    <property name="maven.tomcat.home" value="${env.CATALINA_HOME}"/>

    <!-- deploy the directory created by war:webapp to tomcat/webapps -->
    <goal name="deploy" prereqs="war:webapp">
        <copy todir="${maven.tomcat.home}/webapps">
            <fileset dir="${maven.build.dir}">
                <include name="${pom.artifactId}/**"/>
            </fileset>
        </copy>
    </goal>

    <goal name="test-tomcat" prereqs="war:war"
        description="Starts Tomcat, runs jWebUnit tests, stops Tomcat">

        <taskdef resource="cargo.tasks" classpathref="maven.dependency.classpath"/>

        <cargo-tomcat5x homeDir="${maven.tomcat.home}"
            output="${maven.test.dest}/cargo.log" action="start" >
            <war warFile="${maven.war.build.dir}/${maven.war.final.name}"/>
            <configuration dir="${maven.test.dest}/tomcat5x">
                <property name="cargo.logging" value="high"/>
                <property name="cargo.servlet.port" value="8280"/>
            </configuration> 
        </cargo-tomcat5x>
        
        <attainGoal name="test-web"/>
        
        <cargo-tomcat5x homeDir="${maven.tomcat.home}" action="stop"/>
    </goal>

    <goal name="test-web" prereqs="test:compile" description="Runs JUnit tests">

      <taskdef name="junit"
        classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask"/>
      
        <mkdir dir="${maven.test.reportsDirectory}"/>
        <junit printsummary="no" errorProperty="test.failed" 
            failureProperty="test.failed">
            <classpath>
                <pathelement location="${maven.test.dest}"/>
                <pathelement location="${maven.build.dest}"/>
                <path refid="maven.dependency.classpath"/>
                <path location="web"/>
            </classpath>
            <formatter type="xml"/>
            <formatter type="brief" usefile="false"/>
            <batchtest todir="${maven.test.reportsDirectory}" if="testcase">
                <fileset dir="${maven.test.dest}">
                    <include name="**/*${testcase}*"/>
                    <exclude name="**/*TestCase.class"/>
                    <exclude name="**/*$*.class"/>
                </fileset>
            </batchtest>
            <batchtest todir="${maven.test.reportsDirectory}" unless="testcase">
                <fileset dir="${maven.test.dest}">
                    <include name="**/*WebTest.class"/>
                </fileset>
            </batchtest>
        </junit>

        <fail if="test.failed">
          Unit tests failed. For error messages, check the log files in
          ${maven.test.reportsDirectory}.</fail>
    </goal>

Posted in Java at Jan 15 2005, 02:15:05 PM MST 2 Comments

Being in the office is like being on vacation

Ever since June of last year, I've worked out of my house. I had a couple of different clients, but none of them required I go to their office - so all my work was remote. I'd done this before - in fact all of 2002 I worked out of our house in Morrison. Working at home has its perks: no need to get dressed, fast equipment/network, seeing the family more and highly flexible hours. It also has its downsides. The biggest downside I'm finding is you actually have to work all the time. For the most part, when I worked from home, I wrote code 8 hours+ per day. Sure I'd read blogs and have a conference call every now and then, but for the most part, I was working and thinking the entire time.

After being in an office environment for the past 4 days, I'm finding it's like being on vacation. In an office environment, you typically have meetings. In meetings, you don't really need to think - you just sit their and participate. No coding, no problem solving, just good ol' human interaction and communication. Not only that, but the team I'm on is a great group of guys and I feel like I've been working there for years. Stuff that used to take me 2 days to figure out now takes a couple of hours with a team member's help. Furthermore, since we all have similar interests - there's a fair amount of water-cooler talk. The part I really like is the comradery. You know the kind - where guys insult each other to no end and both parties are laughing the whole time. I can't tell you how many times I've sat in my cube and laughed my ass off while these guys take jabs at each other. Downtown Denver

Of course, my perspective could be scewed. I've been working on my Mac all week, which Powerbook owners know is a pleasant experience. It may be slow, but I'm paid hourly, so I don't mind too much. Oh yeah, and the best part? I got a window seat. I can see out over the city as well as the mountains. Life is good in downtown Denver these days.

Posted in General at Jan 13 2005, 11:04:24 PM MST 5 Comments

Installing Jetspeed 2 and deploying Struts/JSF Portlets

One of things we're moving to on my current project is portlet development. The client has a bunch of apps they want developed and it makes a lot of sense to develop them as portlets and deploy them in a portlet container. Because of this, we spent some time this week mucking around with Jetspeed-2. Bruce and I figured out how to install it, and then I did a bit of work with Equinox to deploy the Struts and JSF versions as portlets.

I didn't get equinox-struts or equinox-jsf fully functioning in Jetspeed, but I did get them to deploy and bring up the first page. I expect to do some more work in the next month to get these apps fully functional. In the meantime, I've put together the following tutorials.

If you have any tips on getting JSF or Struts WARs working in Jetspeed, please let me know.

Posted in Java at Jan 13 2005, 08:44:53 PM MST 10 Comments

[DJUG] Testing and Handling Exceptions in the Web Tier

I'm attending Denver's JUG tonight, where Scott Davis is talking about Unit Testing the Web Tier. His opening slide says he's going to cover HttpUnit, Canoo WebTest and JMeter. I'm most interested in the JMeter stuff as I've been meaning to integrate it into AppFuse. I've used HttpUnit and it's a little verbose for me. I prefer using Canoo WebTest or jWebUnit over HttpUnit. On my current project, we're considering using jWebUnit or HttpUnit to act as a browser when interacting with a 3rd-party system.

All of these tools run functional tests - which are much different from unit tests. Unit tests usually tests the bricks, whereas functional tests test the building. For unit and functional tests to be truly effective, they must be:

  • Scriptable
  • Repeatable
  • Automated
  • Darn close to 100% coverage

The tools Scott is talking about tonight have passed his basic tests:

  • Can I learn it in 10 minutes?
  • Does it play nicely with my existing test environment?
  • Does it play nicely with my existing production environment?

I didn't take any notes about HttpUnit or Canoo WebTest because I didn't really learn anything new. Scott did do a nice job in his HttpUnit examples - he made it look a lot simpler than I've previously seen. I've used it HttpUnit before and it seems a bit verbose. I've always used jWebUnit, which simplifies HttpUnit's API.

JMeter allows you to do the same thing as HttpUnit and Canoo WebTest. It's a standalone GUI, for the complete non-programmer. It does not plug into Ant/JUnit and is mostly used for load testing. I thought it was exclusively used for load testing - and I think it has an Ant task. I could be wrong.

<sidenote>Scott uses Smultron for XML editing on his Mac.</sidenote>

The basic building block of JMeter is a "Thread Group". The Thread Group allows you to control the number of users/threads that run a particular test. You can test gets, posts, change the protocol and even upload files. For load testing, make sure and check "Retrieve all Embedded objects in HTML files". You have to view the "result windows" to view that your tests actually ran - there's no "green bar" feature.

I think JMeter has improved a lot since I last looked at it. Scott's overview and demonstration make it look very straight forward and easy to use. One guy asked if it's possible to see a a global view of all tests run. Scott thinks it's possible by adding a Listener to the Thread Group and creating a graph (one of the options). Scott is now showing a lot of the options in JMeter - there's a ton! It's almost overwhelming.

Next up is "Exceptional" Web Apps by Stephen A. Stelting, a senior Instructor and Author from Sun. His latest book is "Robust Java". Stephen has spent the last year and 1/2 figuring out how to make Java fail.

Objectives:

  • Describe the types of errors that occur in the web
  • Explain how exceptions and errors can be handled
  • Describe the web container response to exceptions
  • Present best practices to address web tier exceptions
  • Show how web frameworks handle exceptions

Payoff: As a result of this talk, you'll have a better understanding of how to use exceptions in Servlets and JSPs, improving the robustness of your webapps.

I'm a little skeptical at this point. I think most folks don't do exception handling in their webapps. I hope Stephen has some good tips and tricks for those of us who are familiar with handling exceptions. I wonder how he feels about Spring and its runtime exceptions?

There are two types of exceptions in the web tier: HTTP Errors and Java Exceptions. Standard HTTP Errors are handled by the web server. You can also send your own HTTP errors by calling HttpServletResponse.sendError(). If you're using response.sendError(), make sure and call it before you commit the output. The web.xml file allows you to specify errors and exceptions with the <error-page> element.

Servlets and Filters have similar exception behavior. Both declare exceptions in both of their lifecycle methods: init and service (doFilter for Filters). Developers throw exceptions in lifecycle methods to "tell" the container about problems.

  • javax.servlet.ServletException
  • javax.servlet.UnavailableException
  • java.io.IOException

Stephen is now describing the init() method and the exceptions it can throw. Yawn. I think most Java web developers use frameworks these days. Because of this, most developers probably don't use these methods because they don't write plain ol' servlets. One thing I didn't know is that UnavailableException takes a time parameter - if you throw an UnavailableException with this parameter, the container will retry after the specified amount of time.

Result of Exceptions in init(): The destroy() method is never called, since the initialization did not complete. Client calls during component unavailability render a 500 error.

I stopped taking notes at this point because my laptop battery was dying. I didn't really learn much in the rest of the presentation. While I can appreciate Stephen's enthusiasm, it was obvious that he was an instructor and not an in-the-trenches developer. He explained a lot of what and didn't have any code to show how to do stuff. There wasn't a single demo in the entire presentation.

Most of the exception handling stuff Stephen talked about for the rest of the session was common sense (IMO). It also centered around the Servlet and JSP API, which most folks probably don't mess with. The Struts and JSF coverage at the end was cool. If nothing else, it was to nice to hear a Sun employee confirm that JSF is quite deficient in its hooks to allow easy framework-configurable exception handling.

Now that I'm working at home, and working/interacting with friends all day - it seems that the DJUG meetings aren't as exciting. They used to be fun because I could get out of the house and have a few beers with friends. Maybe it was the lack of learning anything new tonight.

Posted in Java at Jan 12 2005, 11:30:50 PM MST 3 Comments