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 "matt". 663 entries found.

You can also try this same search on Google.

How do I customize Eclipse on-the-fly?

My task for this week is to figure out how to customize Eclipse on-the-fly? By this, I mean that we're going to install Eclipse and then programmatically add plugins and configure them. Is this possible? We'd also like to add projects to the workbench and have them be there when the user first opens Eclipse. My current technique is to do diffs on directories after I've configured/added stuff, but that's probably not a good long-term solution.

Posted in Java at Aug 24 2004, 11:22:24 AM MDT 9 Comments

My Tiles to SiteMesh Migration

I spent a few hours last night replacing Tiles with SiteMesh in AppFuse. I had the Struts version done in 2 hours, and most of the Spring version done in an additional hour. Then I spent another 3 hours today twiddling with things and getting it just right. During this process, I discovered a few things I thought I'd share. Keep in mind that I'm pretty much a SiteMesh rookie. Hopefully, implementing and using it in AppFuse will help me to fully understand its power.

  • SiteMesh lacks injection. Tiles allows you to inject JSP fragments into your base layout on a per-page basis. I didn't use this feature much, but I did use it to determine which menu should show up on what pages. For example, the login page would get a "projects used" menu, the signup page wouldn't have a menu, and all other pages would get the standard site menu. With SiteMesh, all of this seems to be done best with JSP includes and some <c:if> logic in your decorator. I ended up using <c:import> in my login.jsp for the login menu, importing nothing for signup, and using <c:if> statements in my decorator to see if the user was logged in. If they were, then I import the site menu and its necessary scripts and styles. In the end, this worked fine and it's probably easier for new AppFuse users to understand - so that's a good thing.
  • Injecting scripts and stylesheets. With Tiles, I was able to easily control which scripts and stylesheets were shown on each page. With SiteMesh, this is pretty easy to do by putting them in the <head> element of your page. However, what I would've really liked to see is the ability to put these in an included JSP and have them end up in the <head> of the final document. I know it's virtually impossible, but it would be cool.
  • Headings. Adding a <title> title element per-page works great using the <title> tag. However, if you want to add a heading (which I specify with an <h1> tag), you have to use a <content> tag. It would be cool if I could somehow use <h1> or <heading> in my page to indicate a heading. I ended up going with the following in each page to specify the title and heading:
    <title><fmt:message key="mainMenu.title"/></title>
    <content tag="heading"><fmt:message key="mainMenu.heading"/></content>
    There's probably an easier way to do this, but this works for now.
  • Injecting <body> ids. Using body ids to set styles on a per-page basis is a great way to control CSS. With Tiles, I set this as an attribute in tiles-config.xml and then grabbed/used it with the following JSTL code:
        <c:set var="bodyId" scope="request">
            <tiles:getAsString name="body.id" ignore="true"/>
        </c:set>

    <body<c:if test="${not empty bodyId}"> id="<c:out value="${bodyId}"/>"</c:if>>
    Yeah, it's ugly, but it works. With SiteMesh, you can easily set a body id by using <body id="name">. In fact, you don't even need to wrap your content with it, you can simpley do <body id="name"/>. I'm grabbing and using this in my decorator with the following code. This works, but it would be cool if I could check for the existence of the attribute first - so I could eliminate id="" when no body id is set.
    <body id="<decorator:getProperty property='body.id'/>">
  • Inheritance. With Tiles, you could extend page definitions and override attributes. This feature seems to be completely lacking in SiteMesh. I don't know how you could implement it, but it would be nice to have something where you could specify the parent - for instance, to use the same <head> content.
  • Error page decoration. SiteMesh seems to be incapable of decorating error pages (i.e. 404) in Tomcat 5.0.x (even if I add <dispatcher>ERROR</dispatcher> to the filter-mapping). A workaround is to use wrap the error page with a <page:applyDecorator> tag. This works, but if you specify elements in <head>, they will end up in the body of page, rather than in the decorator's header.
  • SiteMesh simplifies. Switching from Tiles to SiteMesh allowed me to delete somewhere around 8 JSPs. AppFuse has 34 after committing everything. Most of these were JSPs that sat in the root folder and had a one-liner to pull in a Tiles definition. However, it also eliminated 11 JSPs from the Spring MVC install - allowing reduction of duplication. The Spring MVC install now has 17 JSPs.

So there you have it. AppFuse now uses SiteMesh instead of Tiles! I'm sure the implementation will get cleaner and more refined as more folks use it. I'm looking forward to deleting some chunks out of AppFuse's tutorials because SiteMesh makes page development so much easier. The hardest part of SiteMesh is setting up the infrastructure. Once you're got that done, you hardly ever touch it again.

Next task: WebWork integration.

Posted in Java at Aug 21 2004, 11:50:50 PM MDT 14 Comments

One thing's for sure

The Java Community certainly does care about JSF. Regardless of whether folks like it or hate it - there's definitely a lot of opinions! Who woulda thunk a simple blog entry would get so much traffic? Wierd.

You know it's a late night when Erik posts before you go to bed...

Posted in Java at Aug 20 2004, 04:52:09 AM MDT 10 Comments

FindBugs

I ran FindBugs on AppFuse last night and found/fixed a number of issues as a result. I'm now down to only a handful left - most of them being "Class is Serializable, but doesn't define serialVersionUID". I tried to generate one using serialver, but I couldn't it to work after numerous attempts. My issues seemed to be classpath related: it wanted the servlet api in my classpath, and once I'd add that, it could find my class. I'll have to try the SerialVer Ant Tasks. Fixing this issue would be nice, but I doubt it's really affecting appfuse-based applications. The other bug is "Inconsistent synchronization" in UserCounterListener.contextInitialized() method. Any tips on solving this one are appreciated.

Posted in Java at Aug 19 2004, 09:46:50 AM MDT 15 Comments

Should I ditch Tiles in AppFuse?

I've haven't been developing applications with AppFuse since May. Instead, I've been using Equinox. One of the main things in Equinox I've grown to love is SiteMesh. It's worked in all the webapps I've written, which utilize frameworks like Struts, Spring MVC, WebWork, Tapestry and JSF. Tiles will only work in 3 of those.

I think it's time to make an executive decision on AppFuse and ditch Tiles in place of SiteMesh. It's faster and easier to develop with, and it doesn't get in your way. In fact, I didn't have to change a single line of SiteMesh-related code to support any of the aforementioned frameworks. Furthermore, using SiteMesh would also greatly reduce the duplicate between frameworks. I've thought about keeping Tiles around, but it's a pain in the ass to maintain parallel sets of documentation.

Whaddya think - any reason you can think of to keep Tiles? I can't. In fact, I think I'd cringe if I had to start my next AppFuse-based project w/o SiteMesh.

Posted in Java at Aug 18 2004, 10:11:56 AM MDT 33 Comments

Denver JUG gets a makeover

I just noticed tonight that the DJUG website got another makeover - and it looks great. Nice work Renee! Not only that, but the line-up of speakers and topics for the coming months is awesome: Dion, Mike, Bruce and yours truly. I actually enjoy DJUG meetings more than I do conference sessions. The speaker is not fixed to a certain time (though they are encouraged to be under an hour) and you get to have beers with them afterwards.

Posted in Java at Aug 17 2004, 10:59:19 PM MDT 6 Comments

Why Java Desktop apps are better

Since I've been spending so much time with Microsoft Word lately, I decided to upgrade to the latest versions yesterday. Here's where products like IDEA really shine. If I buy a copy of IDEA, I get a copy for Windows, Linux and OS X. It's written in Java, so it's easy to create versions for different operating systems. I imagine it's just a matter of packaging each install differently.

So I went to CompUSA and had to buy 2 copies of Word - one for Windows and one for OS X. That's bullshit - I should only have to buy one software package. Oh well, it's already paying off since Word on Windows hasn't crashed yet.

Posted in Java at Aug 16 2004, 10:47:58 PM MDT 11 Comments

log.debug vs. logger.debug - which do you prefer?

This is probably a bit of a religious debate, but it can't hurt to ask. Do you prefer to use log.debug() or logger.debug() in your Java classes? A fair amount of open source projects use Commons Logging and many of them seem to use logger. Personally, I prefer log (esp. b/c it's shorter), but I'm willing to change based on what the community (particularly AppFuse users) prefer.

Here's another tip I learned today. I typically declare a log variable for each class, such as this one in BaseAction.java:

    protected static Log log = LogFactory.getLog(BaseAction.class);

A better design can be found in Spring's DaoSupport classes. They have a logger variable that all its subclasses can use - eliminating the need to initialize a log variable in each class.

    protected final Log logger = LogFactory.getLog(getClass());

Obviously this is cleaner than AppFuse's current design - so I'll be changing it for 1.6. Any reasons why I shouldn't?

Posted in Java at Aug 16 2004, 09:47:58 PM MDT 21 Comments

[DJUG] The Google Guys

I'm sitting at the Denver JUG meeting and Joshua Bloch and Neal Gafter just finished a talk on "Java Puzzlers". I didn't show up until halfway through - but it was still a great half hour. They had a bunch of slides with problems that had seemingly easy answers. They'd both have a good dialog about their proposed answers - and then asked the crowd what they thought. The problems were mostly due to dumb (but real world mistakes) - the kind of thing you'd slap your fellow programmer for writing. These guys are definitely fun to listen to - next up is Tiger and what's new in 1.5 (I thought it was 5.0?). Boy, it's a full room tonight - I'd bet there's around 120-150 people here.

Taming the Tiger

Major theme of "JDK 5" is ease of development with features like generics, for-each loop, autoboxing/unboxing, enums, varargs, static imports and annotations. It's designed to make programs clearer, shorter and safer by providing linguistic support for commong idioms. Sidenote: Joshua said that Neal wrote the compiler - and they've basically made it more rigorous so it writes the boilerplate code for you. New features do no sacrifice compatibility or compromise the spirit of the language. Neal has been using these features for a couple of years now and he says he's really enjoyed them.

Goal of this talk is to make it easy for us to understand JDK 5 so we can start using it in our development. Let's look at the different features of 5.0.

Generics, For-Each and Autoboxing/unboxing

Generics allow you to specify the element type of collection. Rather than specifying a List - you specify it's contents - i.e. String. It's basically stronger typing with less typing which enforces the specification at compile time. For example, the following code using the new for-each syntax to iterate through a list of TimerTasks in a collection. Notice the lack of casting and easy-to-read loop syntax.

void cancellAll(Collection<TimerTask> c) {
    for (TimerTask task : c) {
        task.cancel();
    }
}

Bytecode is the same as it is in 1.4 - 5.0 merely converts the code for you. One question that these guys have heard a lot is why ":" rather than "in". The answer is twofold - because "in" is already a keyword (for example, System.in) and they didn't want to introduce a new keyword. Because 'in' is an identifier that is already in widespread use, and thus they could not make it a keyword without serious impact. Only new keyword in JDK 5 is enum.

The Collection Interface has been Generified. All existing code should still work, but you can also use the new stuff if you like. I haven't listened much to what's new in 5.0 - but this is wicked cool. You might say it sucks because now you end up with strongly typed stuff, but at least you won't have any more ClassCastExceptions.

  • autoboxing: automatic conversion from int to Integer (or from double to Double, etc.)
  • unboxing: automatic conversion from Integer to int

For example, you can now easily do the following:

Integer i = new Integer(5);
Map map = new HashMap();
map.put("result", i+1);

Notice that the Integer type is converted to an int for the addition, and then back to an Integer when it gets put into the Map. Cool, huh?

JDK 5 also simplifies reflection. Class Class has been generified - Class literal Foo.class is of type Class<Foo>. This enables compile-time type-safe reflection w/o casting. The following used to return an Object and required casting.

Foo foo = Foo.class.newInstance();

This enables strongly typed static factories. I wonder if this can be used with Spring so you don't have to cast a bean when grabbing it from the ApplicationContext?

When should you use Generics? Any time you can - unless you need to run on a pre-5.0 VM. The extra effor in generifying code is worth it - especially b/c of increased clarity and type safety.

When to use for-each loop? Any time you can b/c it really beautifies code and makes it much easier to write. It's probably the smallest new feature in 5.0, but likely to be a favorite. You can't use for-each for these cases:

  • Removing elements as you traverse a collection (b/c there's no iterator)
  • Modifying the current slot in an array or list (b/c the index is hidden)
  • Iterating over multiple collections or arrays

The lack of an index seems to rub the crowd wrong. Joshua and Neal's response is they tried to design something very simple that would capture 80% of usage. If you need an index, just use the old for loop - it ain't that hard; we've been doing it for years!

If you want to use for-each in your APIs - i.e. if you're writing a framework, a class should implement the new Iterable class.

When should you use autoboxing? When there is an impedance mismatch b/w reference types and primitives. Not appropriate for scientific computing. An Integer is not a substitute for an int. It simply hides the distinction between wrappers and primitives. A null unboxes by returning a NullPointerException. They did consider setting it to the primitive's default, but the community voted 50-1 to for NPE.

Enums

JDK 5 includes linguistic support for enumerated types. Advanced OO features include the ability to add methods and fields to enums. Much clearer, safer, more powerful than existing alternatives (i.e. int enums).

enum Season { WINTER, SPRING, SUMMER, FALL }

I just noticed that it's boiling in here - A/C must be out again in the auditorium. It's 8:20 right now, I hope this is over soon, I can feel sweat beading on my forehead.

Enums are Comparable and Serializable. Enum constants should be named similar to constants. Enums are basically a new type of class. As far as I can tell, I have no use for Enums in my code. There's lots of gasps from the crowd as Joshua is describing the features of Enums (i.e. constant-specific methods). Sure it looks cool, but I still don't think I have a use for it. Maybe framework developers will find this useful. BTW, there's two high-performance collection classes: EnumSet (bit-vector) and EnumMap (array). EnumSet replaces traditional bit-flags: i.e. EnumSet.of(Style.BOLD, Style.ITALIC).

When should you use Enums?

  • Natural enumerated types: days of week, phases of moon, seasons
  • Other sets where you knkow all possible values: choices on menus, rounding modes, command line flags
  • As a replacement for flags (EnumSet)

Quote of the night: "It's extraordinarily rare that you'll need to cast when programming with JDK 5".

Varargs

A method that takes an arbitrary number of values requires you to create an array. Varargs automates and hides the process. James Gosling contributed the ... syntax. Varargs always has to be the last parameter. MessageFormat.format has been retrofitted with varargs in JDK 5:

public static String format(String pattern, Object... arguments);

String result = MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet "
                                     + "{0,number,integer}.", 7, new Date(),
                                     "a disturbance in the Force");

Reflection is now much easier with Varargs - so you can call c.getMethod("test").invoke(c.newInstance()) instead of c.getMethod("test", new Object[0]).invoke(c.newInstance(), new Object[0])).

When should you use Varargs?

  • If you're designing your own APIs - use it sparingly.
  • Only when the benefit is compelling. Don't overload a varargs method.
  • In clients, when the API supports them: reflection, message formatting, printf

Static Imports

Clients must qualify static members with class name (Math.PI). To avoid this, some programmers put constants in an interface and implement it. BAD - "Constant Interface Antipattern". They've made this mistake in the JDK - java.util.jar has this pattern. Static import allows unqualified access to static member w/o extending a type. All static fields, methods, etc. will be available for your class using static imports. For example:

import static java.lang.Math.*;
r = cos(PI * theta);

When should you use Static Imports?

  • Very sparingly - overuse makes programs unreadable.
  • Only use it when tempted to abuse inheritence.

Metadata

Decorates programs with additional information. Annotations don't directly affect program semantics. They *can* affect treatment by tools and libraries. Can be read from: source, class files, or reflectively. Ad hoc examples: transient, @deprecated. Tiger provides a general purpose metadata facility.

Why Metadata?

  • Many APIs require a fair amount of boilerplate - i.e. JAX-RPC.
  • Many APIs require "side files" to be maintained. Examples: BeanInfo class, deployment descriptor.
  • Many APIs use naming patterns, i.e. JUnit.

Metadata encourages a declarative programming style - tell a computer what to do, now how to do it. Annotation Type Declarations are similar to interface declarations. Special kinds of annotations include Marker annotations and Single-element annotations. The main reason for annotations is for tools providers.

Neal thought that JDK 5 Beta 3 or Release Candidate was available at http://java.sun.com/j2se/1.5.0, but it looks like Beta 2 is the latest release. The fact that he said that implies that a new release should be available shortly. Neal also mentioned that JDK 5 (final) would be shipping soon.

Random fact: Google uses a lot of Java - entire Ads front-end is done in Java.

This was a great talk about all the new features of JDK 5 - I can't wait to start using them. It might be awhile before I can convert AppFuse to JSP 2.0 and JDK 5, but it'll be a good day when I can write my apps using these technologies. Tonight was the best overview of JDK 5 that I've seen so far - in print or person.

Update: Presentations PDFs have been published: Programming Puzzles and Taming the Tiger.

Posted in Java at Aug 12 2004, 01:01:48 AM MDT 5 Comments

David Geary - the JSF guy?

I wonder if this David Geary is the JSF Geary. I hope so, it'd be great if he started blogging. I've seen David speak before and he's definitely good. Regardless of my recent experience with JSF, it's a technology that's likely to succeed. David is a JSF expert - so hopefully he'll have some tips and tricks for us.

Posted in Java at Aug 08 2004, 02:31:54 PM MDT 4 Comments