Eben Hewitt on Java

Eben Hewitt writes about Java, Service-Oriented Architecture, and general enterprise software development practices.

Orange-Bacon Lentils with Goat Cheese

This delicious dish is not hard to make, and is very healthy. The bacon gets a lot of the fat trimmed, but still adds terrific flavor and texture. It makes a nice lunch or a light dinner, and the Medditeranean flavors work especially well in the summer.

Ingredients
Juice of 3 oranges
1/2 cup fresh sage
1/2 cup fresh rosemary
1/4 cup mustard
3 1/2 cups organic chicken stock
8 slices bacon
1/2 white onion, finely chopped
6 baby new potatoes, skin on
1 cup lentils
1/2 cup quinoa
1 tbsp white balsamic vinegar or lemon juice
4 tbsp goat cheese (lavendar goat cheese is ideal)
1 tbsp fresh ground black pepper

Add juice, sage, and rosemary to a microwave-safe bowl. Microwave for 2 minutes. Let sit for 10 minutes. Strain the mixture into a Pyrex measuring bowl.

Add mustard and stir with a fork. Add chicken stock. You should have 2 cups total liquid.

Cook bacon slices. Pat dry with paper towels to remove any excess grease, then remove fat with cooking shears.

Put the bacon in a stock pan and add onion. Slice the potatoes and add to pot. Simmer until potatoes are done, 10-15 minutes. If it gets too dry, add stock.

Rinse the lentils and add to the pot. Add 2 cups stock and black pepper to taste. After several minutes, rinse and add the quinoa to the pot as it will cook first. Boil gently util the lentils are done, about 20-30 minutes total.

Turn off the heat. Stir in white balsamic vinegar. Serve warm. Just before serving, add a dollop of goat cheese to the top of each serving.

Serves 4 for lunch.

July 11, 2007 in Recipes | Permalink | Comments (0)

Using Microsoft SQL Server with Apache jUDDI

jUDDI is an implementation of the UDDI version 2 spec that stores metadata on web services. We're using it for a private registry, and JBoss is rolling it into their product. The strange thing about it is that a Release Candidate was published in 2005, but never graduated to a full 1.0 release.

I have jUDDI running on MySQL v5, which is one of the several databases it is compliant with out of the box. But we programmers aren't the only people in IT, and it would be polite to those at the other end of our floor to do what we can to not introduce additional platforms if we can help it. So I made a perfunctory pass at getting jUDDI to work with MS SQL Server 2000, with unhappy results.

In order to use Microsoft SQL Server 2000 with jUDDI, you need to make some source changes and recompile. That's because MS SQL Server disallows the definition of two TIMESTAMP typed columns within a single table.

But if you really want to make it work, the obvious thing is to modify the jUDDI set up script to use DATETIME when setting up the AUTH_TOKEN table instead of TIMESTAMP, because you can define an arbitrary number of those within a single table). But Microsoft states that DATETIME is not supported as an equivalent. Moreover, once you attempt to access your registry, you'll get the following error:

2007-07-09 10:42:16,742 [http-8080-Processor25] ERROR org.apache.juddi.function.SaveBusinessFunction  - java.sql.SQLException: Disallowed implicit conversion from data type datetime to data type timestamp, table 'uddi.uddiuser.BUSINESS_ENTITY', column 'LAST_UPDATE'. Use the CONVERT function to run this query.

So you'd need to get the jUDDI Java source to convert your TIMESTAMP calls to create a DATETIME just for accessing the AUTH_TOKEN table, modify the data accessor, recompile, and redeploy. The obvious downside here is that you'll have to do extra work to ensure you're stil compatible with MySQL. The trade off isn't great here. So the question becomes one of long-term maintenance. I think we'll quietly stick with MySQL for this.

July 09, 2007 in Tech Notes | Permalink | Comments (0)

Frozen Toasted Almond

I first learned the standard form of this dessert drink when I tended bar on MacDougall street in the Village. I have evolved it somewhat since then. The addition of coffee to the recipe gives the drink more depth, and the vodka gives it a necessary high note. It is thick, rich and creamy, both cooling and warming. It's a professional's drink that's really easy to make at home.

I've made this dozens of times, and I can honestly say that I've never served this to anyone whose eyes didn't swoon shut in delight as they tasted it for the first time. You can actually see their eyes fall from pleasure, as if birds dropping hard to earth, having been pierced midflight with a frozen toasted almond arrow.

Frozen Toasted Almond

Ingedients
1 shot cream
1 shot cooled French roast coffee
1 shot Kahlua
1 shot vodka
1 shot amaretto
1 shot godiva

3 generous scoops French vanilla ice cream

1 handful ice

Brew the coffee and put it in the fridge an hour or so until cool. Add all ingedients to a blender and blend until luscious.

Serves 2

July 09, 2007 in Recipes | Permalink | Comments (0)

Making Spiked Melon Foam at Home

Two restaurants we've been to recently feature foam in their dishes: Binkley's and Per Se. Kevin Binkley came up through The French Laundry, so the link is not surprising. But at both restaurants (among our all-time favorites) Alison and I have enjoyed a variety of foams served as a delightful accompaniment to meat dishes. The foam is airy, superlight, and has a very concentrated flavor. A little touch of foam is different and exciting and fun. I stumbled upon this recipe by accident while making a cocktail, and we enjoyed it so much that we forgot about the drinks and sat down with utensils to eat spoonful after spoonful of this delicious spiked melon foam.

Ever since ordering an appetizer of "Surf and Turf" at Binkley's, which was wittily accompanied with a little foam to punch up the "surf" metonymy, I have been intrigued. I figured I lacked the knowledge to make foam (I did, er, do), and decided that even if it was a simple recipe, there must be some tool or technique that would keep something as dazzling, as spectacular, as de troupe as foam out of the home kitchen. But following my serendipitous encounter with an Emeril "cooler" recipe, it turns out to be fairly simple, fun to make, and an absolute knockout. You can use the foam in this recipe in place you might otherwise use whipped cream. Alison and I will use it on our raspberry fool, which recipe I'll record later. Perhaps we will call it a "Drunken Fool"...

Spiked Melon Foam

Ingredients
1/2 small round watermelon (2 cups)
1/2 cantaloupe (2 cups)
1/2 honeydew (1 cup)
3 tablespoons honey
1 cup vodka

Cube the melons and place in a freezer bag for 1.5 hours.

Put the frozen melon cubes, honey, and vodka in a blender. Blend on high speed for a couple of minutes. You want to pulverize the stuff.

Place a sieve atop a bowl or other container (we used a Pyrex measuring glass) and pour the blended mixture through the sieve. It will drip slowly from the sieve; the process will take several minutes.

The foam will gather in the sieve. Scoop it out with a regular spoon for desert topping. Drink what ends up in the container.

Serves 6-8.

July 04, 2007 in Recipes | Permalink | Comments (0)

Orecchietta in Buffalo Arrabiata Sauce

This is a recipe for a simple little pasta dish with a spicy twist. Buffalo has lower fat, lower cholesterol, lower calories, and higher protein and iron content when compared to beef. It also has a lovely texture and distinctive flavor that isn't overpowering. Orecchietta is used because the shape holds the sauce well and its flavor balances the sharpness of the sauce.

1 lb ground buffalo
1 tbsp plus 1 tsp extra virgin olive oil
1 28oz can whole tomatoes
1 1/2 tbsp tomato paste
2 fresh tomatoes
8 sprigs thyme
4 cloves garlic
1/2 medium white onion
2 tsp hot sauce, such as Arizona Gunslinger
1 tbsp dijon mustard
1/4 cup merlot
1/2 tsp cayenne pepper
1/2 tsp red pepper flakes
1 tbsp kosher salt
1 tbsp freshly ground black pepper

Directions
Put on the water for the pasta and salt it. Bring to a boil as you're working on the rest. You can make the sauce in the time it takes for the water to come up and the pasta to cook.

Heat one tbsp of the olive oil in a medium heavy sauce pan. Add the buffalo and brown, breaking it up with a wooden spoon. Add salt and pepper as it browns.

Add the can of tomatoes. Break them up with your spoon. Chop the garlic and add to the sauce along with the remaining olive oil.

Chop the onion; don't dice it. Add to the sauce.

Add the red pepper flakes, the hot sauce, the cayenne, and the mustard, stirring well. Let this simmer for a couple of minutes.

Chunk the fresh tomatoes. Add them and the tomato paste.

Add the thyme all at once in a bunch, laying it on top of the sauce. Cover and turn up the
heat for a couple of minutes. Uncover and remove and discard the thyme.

Add the merlot.

Let sauce simmer on medium-low, stirring occasionally while the orecchietta boils for 11 minutes. The sauce should be ready when the pasta is done.

Cooking the sauce in this way is not only easy and quick, it layers the flavors so you really taste the sauce in waves.

Serve with a light, bright, crisp salad.

June 15, 2007 in Recipes | Permalink | Comments (0)

Discovering which JAR file Contains a Class you're Looking For

Did you ever have a build complain that you don't have a class on your classpath that you need and although you'd be delighted to comply and put the class on your classpath, you don't know what JAR it's in? Here is a way to find the needle in the haystack.

Here we'll use an example involving Glassfish, because this seems to happen on server-side projects that involve a great number of different JARs (web services requires JAXB, XJC, WSImport, JUnit, the Ant tasks that go with them, and so forth, for example). You want only the JARs that you actually need on your cp, not hundreds of modified bundled versions of things on your cp that may or may not be in use--which is what some IDEs do.

If your build doesn't work because, say, an Ant task that wraps some program such as XJC complains that it can't find a class like "com/sun/enterprise/cli/framework/InputsAndOutputs.class" you need to find that class. You can tell from the name that it's provided by Sun, and can look in the Glassfish lib directory and just use the brute-force method of opening JARs one by one and eyeballing it. But if you open the lib directory of Glassfish (or WebLogic 10 or Spring or anything these days), there are dozens of JARs in there! It can be really boring and time-consuming to determine which JAR has the class you want.

You don't know what this class does. You don't even care about this class at all. You just need your XJC Ant task to work and apparently some class in there needs some other class that needs this one.

But it's not a good practice to throw all of the JARs in there on your cp--it is slow and misleading and doesn't help learn you about what's happening under the hood. And in my view it is not good to be dependent on the IDE whatsoever. You should be able to execute ant from the command line and your build should still work. I can't tell you how many Ant scripts I've seen whose authors claim that their projects will run outside of their IDE, and they don't because they have conflated the IDEs paths with their Ant paths. That drives me nuts.

So, on a Linux system, the following command will examine all of the Jar files in the current directory and print their contents to a file called "tmp".

find . -name "*.jar" -print -exec jar -tvf {} \; > tmp

The resulting file looks like this:

./appserv-deployment-client.jar
     0 Tue Apr 24 07:21:00 MST 2007 META-INF/
   449 Tue Apr 24 07:20:58 MST 2007 META-INF/MANIFEST.MF
     0 Tue Apr 24 06:45:36 MST 2007 com/
     0 Tue Apr 24 06:45:34 MST 2007 com/sun/
     0 Tue Apr 24 06:45:34 MST 2007 com/sun/enterprise/
     0 Tue Apr 24 06:45:42 MST 2007 com/sun/enterprise/admin/
     0 Tue Apr 24 06:45:42 MST 2007 com/sun/enterprise/admin/common/
     0 Tue Apr 24 06:45:38 MST 2007 com/sun/enterprise/admin/common/exception/
   645 Tue Apr 24 06:45:28 MST 2007 com/sun/enterprise/admin/common/exception/AFException.class
     0 Tue Apr 24 06:45:42 MST 2007 com/sun/enterprise/admin/util/
  1821 Tue Apr 24 06:45:28 MST 2007 com/sun/enterprise/admin/util/HostAndPort.class

...and so on.  Each JAR will be named, followed by all of the packages and classes in it. So you can then use the "less" tool to find your guy.

Within the "less" tool, type:
> /InputsAndOutputs

to search down the contents for the "InputsAndOutputs" class. This will find and highlight that text (as long as the JAR that contains your class actually was in the directory you ran this command from).

Now all that's left is to search up the file for the first instance of ".jar" and that will be the name of the JAR file containing your class:

>?.jar

This highlights "./admin-cli.jar", which is indeed the Glassfish JAR file containing InputsAndOutputs.class. So now I can drop that on my classpath and get on with my build.

If you don't know what JAR file contains a class you're looking for, this is an easy way to deal with it on Linux. Don't forget to delete the "tmp" file if you don't want to leave it around for another time.




June 07, 2007 in Tech Notes | Permalink | Comments (2)

Dealing with the "Unable to create JAXBContext due to the security restriction" error in Glassfish.

My colleague Kevin and I are working on the Service Oriented Architecture team at our retail employer. The idea is to pilot a project to get us going for real down the SOA road. We're evaluating tools like Aqua Logic, WebLogic 10, and Sun's Glassfish, and working with the new APIs in Java SE 6 and Java EE 5, including JAXB 2.0, JAX-WS to build services, and so forth. So I thought I would post some of our fidings here every once in a while that might be useful to others working with similiar technologies.

We have a WebService that accepts a complex custom type, and returns a String. The service is an EJB 3 Stateless Session Bean, and we're using simple Java models for a "Start from Java" development process. We're agreed that we won't add annotations or anything to the classpath that isn't absolutely necessary. We don't even have an interface for our EJB, because you don't need it (let alone leaking the implementation out to the interface with @Local or @Remote, rendering the presence of the interface itself totally redundant and useless qua interface).

We decided to wrap the String that our operation returns in more useful custom type (called BinInfo), and suddenly our Ant deployment task (for Glassfish b47) died with the following error:

The exception message is: CLI171 Command deploy failed : Deploying application in domain failed; Unable to create JAXBContext due to the security restriction

It seemed our WebService could somehow accept a custom type, but not return one. What was the problem? Looking on the Glassfish forum revealed that other users had a similar problem, but their solutions didn't work for us. Posts there indicate that 1) you need to have a default no-arg constructor in custom types you use as parameters or return types in your web service operations, including Sun-provided classes like Locale and 2) that the deploy-time exception does not get reported properly by Glassfish. So if your class does, as ours does, really have a default no-arg constructor, you could be flummoxed. This is all standard XML marshalling stuff, so what to do?

There are two ways to deal with this situation. If your problem is the no-arg constructor situation, you can add one and see if that clears it up. There are obvious design reasons not to  blindly go that route, however.

Second way: if that's your problem but it's not in a class you wrote or can change or want to change, you can use the standard Java SE 6 annotation @XmlJavaTypeAdapter(YourAdapterImpl.class) to indicate to the marshaller exactly how it should deal with this absence. There is a concise and helpful article on the subject here, so I won't go into it:

http://weblogs.java.net/blog/kohsuke/archive/2005/09/using_jaxb_20s.html

But what if you do, as we do, actually have a default no-arg constructor, have an object simple enough that creating a new class to implement @XmlJavaTypeAdapter is overkill (not to mention misleading for future maintainers of the code and does not address the root of the problem) and the error message is hidden from you? Directly use the tool that Glassfish uses under the hood: schemagen.

If the Java tools in the JDK bin directory are on your path (they should be) then you can open a prompt, type "schemagen" and use that tool to generate your XML schema representation. Navigate to the directory with the Java source file that is giving you problems. For us it was BinInfo.java.

Here was our class:

public class BinInfo {

    public String chargeType;

    public BinInfo() { }

    public void setChargeType(String chargeType) {
        this.chargeType = chargeType;
    }

    public String getChargeType() {
        return chargeType;
    }   
}

A perfectly normal, simple bean, right?

Running schemagen BinfInfo.java produced the following error:

[ehewitt@dtc20266w domain]$ schemagen BinInfo.java
error: Class has two properties of the same name "chargeType"
        this problem is related to the following location:
                at mypackage.BinInfo.getChargeType(BinInfo.java:28)
                at mypackage.BinInfo(BinInfo.java:16)
        this problem is related to the following location:
                at mypackage.BinInfo.chargeType(BinInfo.java:18)
                at mypackage.BinInfo(BinInfo.java:16)
1 error

This reveals that the field was accidentally typed to be "public", and schemagen thinks that the field itself and the getter method for it are the same. I changed the visibility of the field to private and everything worked fine.

While hopefully your typing skills are better than mine, this post is meant to illustrate that you can use schemagen to get a clear picture of what the deployment tools are doing, and highlight mistakes in your code. This is important because Glassfish isn't percolating nested exceptions up at this time, and the error messages are misleading at best ("the security restriction"???) .

May 30, 2007 in Tech Notes | Permalink | Comments (6)

WebLogic 10 License Bug Prevents Startup

If you are getting an error like this:

java.lang.RuntimeException: There were errors initializing your configuration: com.solarmetric.license.LicenseException: Your license key "376D-896F-8B43-BE3D-3D00" expired on "5/14/07 5:00 PM". Please contact sales@bea.com for purchase or evaluation information.

...this is a known bug. This will affect you only if you downloaded WebLogic 10 before May 14, as I did. You need to get the patch from BEA or you'll never be able to start WebLogic. Just go through the process of getting the evaluation copy again, and they'll give you some options. Hopefully this saves a few headaches.

May 16, 2007 in Tech Notes | Permalink | Comments (1)

WebLogic 10 Ant Tasks Location

I frequently see people asking about where the JAR is that has the Ant tasks defined for WebLogic, such as weblogic.ant.taskdefs.management.WLDeploy

If you get an Ant error like this:
taskdef class weblogic.ant.taskdefs.management.WLDeploy cannot be found
here is how to fix it.

If you installed WebLogic in the default location, then the location of this and many other useful JARs to have on your classpath is /root/bea/wlserver_10.0/server/lib

If your "Deploy to WebLogic" Ant tasks (or like that) are failing, you can put this in Ant's classpath. On Eclipse you do that this way: Window > Preferences > Ant > Runtime > Classpath > Global Entries then Add External JARs.

If you run a jar -tf weblogic.jar | less, you can browse through them, but this is a lot of items, so you can also  just output the contents to a file:

> jar -tf weblogic.jar > /home/ehewitt/WEBLOGICJAR.txt

But that  is a huge file. Limit the output to listing only the Ant task definitions in  that  weblgoic.jar:

> jar -tf weblogic.jar | grep "weblogic/ant/taskdefs*" > /home/ehewitt/WeblogicJarAntTasks.txt

That produces 93 items for WebLogic 10.0, including our WLDeploy.class.









May 03, 2007 | Permalink | Comments (4)

Superbowl Steak Sandwich

This is a recipe Alison and I made one dreary Saturday and it was just fantastic. This is an open-faced steak sandwich--a sort of French version of a Philly Cheesesteak with a spicy white remoulade based on Emeril's recipe.

Superbowl Steak Sandwich
(serves 3-4 for dinner, 6 for lunch)

Preparation time: 25 minutes
Equipment: Food processor, 2 saute pans
Warnings: Uses raw egg.

Ingredients:
1.5 lbs Choice Ribeye Roast (half pound per person)
Ground Natural Rock Salt
Fresh Ground Black Pepper
2 small white onions or 1 big one
3 12" French baguettes (half-loaves, one per person, or cut long baguettes into 12" sizes)
1 cup plus 5 tblsp Canola oil
5 tblsp very sharp Wisconsin cheddar cheese, aged 7 years

For the Remoulade:
1 cage free egg
4 cloves finely chopped garlic
1 tblsp horseradish mustard (we use a brand called Blue Crab Bay Co.)
1 tblsp prepared horseradish (extra hot)
Juice of 1 lemon

Prepare the Remoulade:
Mix all remoulade ingredients in food processor.
Once they are mixed thoroughly, stream in the 1 cup of oil into the processor, mixing until sauce is thick.
Cover in a bowl and put in fridge until the rest is ready.

Prepare the Onions:
Heat 2 tblsp oil in saute pan on low heat.
Chop (don't dice) onions, saute in oil until soft but not brown (about 20 minutes). Grind a little salt and pepper over onions.
Stir onions ocassionally, preparing the steak as they cook.
When the onions are done, pat lightly with paper towel to remove excess oil. Turn off heat. Cover.

Prepare the Steak:
With very sharp butcher's knife, cut the roast into very thin slices, removing fat. It is very hard to cut the slices as thin as you'll want them. Use the side of the knife and your fist to pound each slice flat as paper.
Heat to medium 2 tblsp oil in a second saute pan. Place steak into pan, browning both sides in batches. Generously grind salt and pepper onto both sides of steak as it cooks. Use the remaining 1 tblsp of oil as necessary.
Transfer browned steak into the onion pan, and stir together. Turn heat back on to low just to heat through before serving. Cover.

Prepare Baguette:
Grate the cheese.
Slice the bread lengthwise.
Get the remoulade from the fridge and generously spread on all slices of baguette.
Transfer steak and onion mixture onto baguettes, sprinkle cheese. There won't be much cheese per sandwich and it won't melt; this is desireable.
Serve open faced with knife and fork, though you probably won't use them.

January 21, 2007 in Recipes | Permalink | Comments (0)

Jubilate Java, or, Why I Like Java

Writer Christopher Smart, as he was losing his mind in 1762, wrote a lengthy poem called the “Jubilate Agno”, which includes a shorter piece enumerating the many diverse things he loved about his cat Geoffry. You can read it here: http://www.cs.rice.edu/~ssiyer/minstrels/poems/661.html

Thursday last, someone asked me what I liked about Java. I was surprised to hear my own answer, and, not feeling particularly satisfied with what I had said, I thought that I might spell out here some of the things I was thinking at the time, but did not say. What is my relation to this language that I use every day?

So with my apologies to Christopher Smart, to whose wonderful poem I here pay homage, I thought I would spell out some of the reasons I love Java, even in 2007, to clarify.

For I will consider my language Java.

For Java is open source. The code can be read and freely modified. This is obviously true of a remarkable number of languages.

For Java is not a vehicle for viruses. It is as safe as was advertised. However, the whole “portability” advertisement is really a bit of an exaggeration. By which I mean that the same bytecode does not always run exactly the same on different JREs (volatile keyword implementations stand out). No one would suggest that a J2EE application written to run in WebLogic that uses JAAS for authentication and authorization, and contains EJBs is portable to JBoss without not only recompilation but revision (and the revisions get more extensive depending on what you are doing in your code, and you may not even know what aspects of your code will behave differently, requiring regression testing). For example, the same Filter implementation dealing with HTTP Sessions is executed totally differently in Tomcat than on WebLogic. Depending on the work you’re doing in your filter, this could be very problematic, and is not something one would just expect.

For there shall be little likelihood of buffer overflow.

For Java is strongly typed. Even though I often spend a good deal of time taking care of strong typing, and love weakly typed languages too.

For Java allows for many ways to achieve the same or similar goals. This allows for creativity of expression, and a sense of beauty and mystery.

For Java has many libraries that make it easy to use, and it is easy to extend. If you don’t like the way Calendar are Date are implemented (silly ints), you can use Joda (http://joda-time.sourceforge.net/). You have your choice of numerous XML parsing methods.

For Java implements many design patterns. Borders and JTable components are Flyweights, the XML libraries use Factories and Composite, the Collections give us Singleton wrappers.

For Java sometimes takes its cues from the community. Developers loved Hibernate, they get on the committee and we get the Persistence API; developers loved XDoclet, they get on the committee and we get EJB 3 annotations.

For Java SE 6 contains the Compiler API, which opens the doors wider to generative programming, and the Scripting API, which is fantastic for J2EE developers like me.

For Java has checked exceptions, which are clearer than in C#, and more powerful that the lack of exception handling facilities in VB.

For in Java, whitespace is not meaningful.

For in Java, multithreading is built-in, not added on, and is relatively simple.

For Java is both compiled and interpreted.

For Java has anonymous inner classes, integers are always 32 bits, Unicode is supported, and automatic garbage collection is a really nice thing to have.

For Java stands on the shoulders of giants.

For in Java one can tweak any number of aspects of how your application is compiled and runs. I am thinking of heap allocation, gc hints, assertions, configurable security policies, custom classloaders, and so on.

For Java has always been network ready, and features JNLP/WebStart, Jini, JXTA, and JavaSpaces.

For JMS is a beautiful thing.

For Java code can match, remarkably closely, the real world that one is emulating in a program. This is largely a feature of OO, and not Java itself, but I think Java wants us to adhere to good OO principles more assertively than other OO languages. The “primitives aren’t objects” argument sort of went away with autoboxing. While one can certainly write an 800-line fully procedural program or method in Java, the Java programmer of any experience in that case will have an eerily present feeling that he’s doing it wrong.

For Java provides Generics, and although the type erasure constraint demanded by backward compatibility makes it less powerful than one might hope, it is lovely.

For the Java Virtual Machine is a deceptively simple application of one of the fundamental directives of computer science, that we can eventually bridge to anywhere with another layer of indirection.

For in Java, the keywords are few, and while it may be verbose, it is not verbose where it needn’t be. The Python phrase “def do_work(self):” is longer and tells us less than “void doWork(){“. The “def” is implicit in Java, as is the “self”.

For Java is not pompous or loud or rude or showy or full of itself or standoffish or intimidating, and the tools we have for it, like Eclipse and IntelliJ, are like loving friends.

For Java is faster than its reputation suggests.

For Java is free.

For Java has annotations, which appeals to the meta-person in me who watches.

For Java makes me happy, as it is fun to write, and its programs contain dramatic structure.


While there are any number of these items that are true of other languages, and while in Ruby on Rails you can put together a complete CRUD web app for your 172 table relational database in under 11 seconds, I love Java.

January 14, 2007 in Articles | Permalink | Comments (0)

Query for Finding A String in Your MS SQL Stored Procedures

Here is a query that you can execute in MS SQL Server's Query Analyzer to find some text string in any stored procedure defined in your database. This is very useful if you change the name of a table or something like that, and need to know what procedures to udpate.

declare @textToFind varchar(300)
set @textToFind = 'Store'

SELECT ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%' + @textToFind + '%' AND ROUTINE_TYPE='PROCEDURE'

It returns a list of the names of all stored procedures that contain your text string.

January 12, 2007 in Tech Notes | Permalink | Comments (0)

Annotation for Java Code Reviews and Stripes

I wrote this annotation to assist our team in keeping track of our many ongoing code reviews, and just made it part of my new Java file template in Eclipse. It is not a big deal, but I have found it sort of useful as time goes on. Just compile it and include in your Java source files like this:

@Reviewed(stage=Reviewed.Stage.Passed, date="1/2/07", reviewers={"BM,MM"}) public class Foo {}

I love annotations in Java, and have recently become interested in the Stripes project, which is a Web framework that is very lightweight and not as intrusive as something like Struts:

http://stripes.mc4j.org/confluence/display/stripes/Home

I mention it because Stripes makes extensive use of annotations. Sorry for the low-cohesion of this post. :)

package com....;

import static com....Reviewed.Stage.New;

import java.lang.annotation.*;

/**
* Used at the class level to indicate that a Java source file has been
* undergone code review, or needs to. This serves a few purposes:
* <ol>
* <li>It allows readers of the source to guage the level of quality that they
* might be able to expect from the code
* <li>It allows code reviewers to know what classes have already been reviewed
* so that they can review new code next time.
* <li>It allows supervisors to guage the level of review coverage in the
* repository.
* <li>It allows tools to search the repository to generate reports.
* <p>
* Because the Documented annotation is used, code with this annotation will
* appear in JavaDocs generated for source that uses it.
* <p>
* The obivous downside to using this is that it requires projects to either 1)
* acquire a possibly unnecessary dependency on the Shared project or 2)
* duplicate the code for this annotation in their own project.
*
* @author Eben Hewitt
* @since 1.0
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Reviewed {

/**
  * Indicates through what point in the progression through code reviews this
  * Java source code has successfully moved.
  *
  * @author Eben Hewitt
  * @since 1.0
  */
public enum Stage {
 
  /**
   * This code has not yet been reviewed, and should be; this is the
   * default value if none supplied.
   */
  New,
 
  /**
   * This code has been reviewed, and needs some tuning, which should
   * be underway.
   */
  Revising,

  /**
   * This code has been reviewed, and the reviewers indicated in
   * {@link #reviewers} find this code of highest quality.
   */
  Passed};

/**
  * The current stage that this source code has passed in the review process.
  * @return the default value is {@link Stage#New}.
  */
public Stage stage() default New;
 
/**
  * The String date of when this code was last reviewed, which is not a Date
  * object because that is an illegal type in annotation parameters.
  * @return the date this code was reviewed.
  */
public String date();

/**
  * The names of the supervisors or members of the development team who have
  * reviewed this code.
  * @return the names or initials of the team members who have reviewed this
  * code.
  */
public String[] reviewers();
}

January 11, 2007 in Tech Notes | Permalink | Comments (1)

Java Web App Debugger

An new tool for Java EE developers, called JWAD, is available from Downloads.com at http://www.download.com/JWAD-Java-Web-App-Debugger-/3000-2417_4-10617972.html?tag=emailThis

My friend Barney Marispini has done a great job with this tool, which shows you all of the values available in any scope in a web request. The UI is very slick and installation is easy. The download size is small (46k). I would highly recommend trying this tool out.

January 02, 2007 in Tech Notes | Permalink | Comments (0)

Ant 1.7 Available

The new, 1.7 version of the Apache Ant Java build automation tool was released Tuesday with a new resource framework. This allows standard Ant functions to understand and deal with .zip files, .tar files, directory structures and other common UNIX items. Also added to version 1.7 is preliminary support for some Java SE 6 functions. Ant is open source and available under the Apache Software License, and can be downloaded at http://ant.apache.org/bindownload.cgi.

December 22, 2006 in Tech Notes | Permalink | Comments (0)

VarArgs as parameters to public EJB Methods on BEA WebLogic 9.2

WebLogic's EJB 9.2 compiler rejects public method definitions using varargs. It does so in a very weird way: it complains that "transient" is not allowed as a method modifier, which of course it isn't.

It is possible that there is something that XDoclet 1.2.3 is generating that confuses WebLogic, but that was not the case with parameterized types in WebLogic 9.0 or 9.1, so my money is on WebLogic as the culprit.

I wrote this method in my EJB:

public void recordRecalculateMarketPricingEvent(

RecalculateMarketPricingEvent event, AuditRecordAction...actions)

And this was the result at deploy time (XDoclet didn't mind it):

<Oct 12, 2006 2:46:19 PM MST> <Debug> <EjbCompilation> <000000> <[EJBCompiler] Compiling EJB sources>

/tmp/appcgen_pricing.ear/appcgen_pricing-ejb.jar/com/dte/pricing/ejb/AuditService_ibl70p_Intf.java:21: modifier transient not allowed here

public transient void recordRecalculateMarketPricingEvent(com.dte.pricing.events.RecalculateMarketPricingEvent arg0, com.dte.pricing.events.AuditRecordAction[] arg1)

Looking at the source that is indeed what WebLogic generated for the public Local Interface:

/**


* This code was automatically generated at 3:07:24 PM on Oct 12, 2006
* by weblogic.ejb.container.ejbc.Ejb2Rmi -- do not edit.
*
* @version WebLogic Server 9.2 Fri Jun 23 20:47:26 EDT 2006 783464
* @author Copyright (c) 2006 by BEA Systems, Inc. All Rights Reserved.
*/

package com.dte.pricing.ejb;

import weblogic.ejb.container.interfaces.WLEnterpriseBean;
public interface AuditService_ibl70p_Intf
extends WLEnterpriseBean
{


public void ejbActivate();
public void ejbCreate();
public void ejbPassivate();
public void ejbRemove();
public transient void recordRecalculateMarketPricingEvent(com.dte.pricing.events.RecalculateMarketPricingEvent arg0, com.dte.pricing.events.AuditRecordAction[] arg1)
throws com.dte.shared.persist.PersistenceException;

public void setSessionContext(javax.ejb.SessionContext arg0);

Somehow WebLogic knows that it is a varargs method and translates it to an array. But for some bizarre reason, it puts transient in front of my method definition, and the AppC compiler rejects it.

Changing my method to this is my only current workaround:

public void recordRecalculateMarketPricingEvent(

RecalculateMarketPricingEvent event, AuditRecordAction[] actions)

WebLogic has no problem with private vararg methods however, presumably because it doesn't touch them. Which means JRockit has no problem with it. This works:

private void printArgs(AuditRecordAction...actions)

This is frustrating. With WebLogic 9.0 and even in 9.1 defining methods with parameterized types as arguments in an EJB would get rejected by the compiler. That is, this would not work:

public void work(List<Product> products)

But this would work:

public void work(List products)

That was finally fixed in WebLogic 9.2. And what was weird about that issue was that you could return parameterized types from a public EJB method in WebLogic 9.0 and 9.1. So this worked fine:

public List<Product> work(String something)

Is the idea that we get more or less one implementation of a new feature in Java 5 with every release of WL? I wonder if we get covariant returns...

October 12, 2006 in Tech Notes | Permalink | Comments (0)

Swing GUI Design for the SCJD, or, Honey, I’m Just in the Mood to Use Some Software

This is about designing software user interfaces. I am leading a study group on successfully completing the Sun Certified Java Developer project, and we’re talking about UI design this week. So here are some thoughts.

Abstract the GUI to hide how the system works (user should be spared the details).

Think of successful user interfaces in the real world and what is great about them.

-Steering Wheels. They are amazingly simple, hide complexity and implementation. It is simple because you aren’t tied directly to controlling each individual wheel. It could be a truck with 12 wheels or a 4 wheel drive or a front wheel drive and the interface is identical.
-Telephones. Old telephones used to require you speak into the phone base, and hold the receiver to your ear. Modern phones accomplish the same task but afford greater freedom by combining the two in one handset. The UI is roughly the same whether it is a cell phone or a desktop phone. The newest phones free your hands altogether.

Rule #1: Write Use Case Diagrams before doing your GUI.

Even if you are being "agile".

Dr Horstmann is the author of Core Java, and offers Violet as a free UML editor.
You can use Violet via WebStart at
www.horstmann.com/violet

-Keep it abstract and separate from implementation.
-You are required to use a Jtable.
-What components can you use to

Remember that there are three distinct processes to keep in mind—don’t let them spill into one another, though they are obviously complementary:

1. What the system does (what goals can be accomplished with it)
2. How the system does what it does under the hood.
3. What the user has to do to accomplish a goal.

Rule #2: Sketch your GUI on Paper First

After you’ve written use case diagrams, sketch your GUI on paper.
-It is the fastest way possible
-Changes are a breeze.
-You can show colleagues easily
-You can show your mother, or someone who is not a programmer or necessarily interested in your system and use that to help you determine if your UI is easy to use.
-Shoot for 5th grade level. That is, a 12 year old product of standard American public school system education should be able to immediately use your UI without asking any questions, without reading any documentation, and without having been told what the system is even for.

Once you are happy with your GUI layout, make a few Xerox copies of it. Then use a pencil to break up your sketch according to the panels you will need to break it up into. Remember that nesting panels is a good idea. This is like the process of breaking up a Photoshop layout for a web page into HTML tables or divs. Once you are happy with how it is broken up, then the layout managers you need should be clearer. This will also help you work over your GUI design from a different perspective, and maybe notice flaws in it. Only now should you start coding your GUI.

Group your user interface items logically. Duh. Consider the “File” menu that organizes Open, Save, New operations.

Be disciplined about what aspects of your GUI should allow creative flourishes. The order in which your menus appear in your menu bar is NOT one of them. That is, it would be entirely indefensible to organize it like this:

Help Tools File Edit

There is one obvious, conventional way of doing this:

File Edit Tools Help

Which brings us to…

Rule #3: Users do NOT read.
They feel their way across a layout, based on conventions. Users often will click a button without reading the label because they see in their peripheral vision a gray box that they figure is about the size of a button and is located on the UI at the bottom right hand corner of the form, and they guess based on that information that that’s the “Save Changes” button and click it. I am not exaggerating and if you have developed user-facing software for any amount of time you know it’s true.

Rule #4: Software should be so transparent, so invisible, so achingly thin that users forget they are using it.
That’s because users use software to do their real job, accomplish some other goal, which is what they care about. No one in the world cares about software in itself. No one in the world would simply starting using some random piece of software, in order that they might have the pleasure it affords in its own right. No one says to her husband, “Honey, I think I’m going to go use some software now. Any old program will do. I’m just in the mood to use some software”. They say, “I am going to write a letter to the theater downtown in order to voice my objections regarding the lack of Mexican wedding cakes sold at the intermission.” Then they sit down to their laptop and open Word.

Make a Prototype
Once you have your GUI sketched, make a prototype based on it. Stub your data, just print out to the console in your action listener.

Do NOT use editors in Eclipse or Matisse in NetBeans to do your dirty work for you. Not only is this highly questionable and suspect with respect to the rules of the exam, you will rob yourself of the joy of learning GridBadLayout, one of the simple pleasures left in modern life.

If you don’t know any Swing, now is the time to dig in. Do the Sun tutorial and read the code. Read lots of it:

http://java.sun.com/docs/tutorial/uiswing

Rule #5: Don’t forget the keyboard.
Think of how you use software. Do you drag the mouse all the way up to File > Save? No way. You hit Ctrl + S every few seconds as you’re typing. It’s part of the flow that helps you get your work done quickly. Make sure your GUI has all of the keyboard mnemonics that you yourself would expect.

This is not the time to get inventive, either. Do not make Alt + S be the shortcut to Save. Or Ctrl + V. Save is Ctrl + S, forever and always, and if you violate this rule I think that Dante has a special circle of Hell reserved just for people like you.

Rule #6: Use the MVC Pattern or Observer Pattern
If you don’t know the MVC Pattern, now is the time to learn. Once you have your GUI Sketched and prototyped, apply MVC to it.

Check out these resources:

MVC
http://en.wikipedia.org/wiki/Model-view-controller
http://c2.com/cgi/wiki?ModelViewController
http://www.purpletech.com/articles/mvc/refactoring-to-mvc.html

Observer
http://c2.com/cgi/wiki?ObserverPattern
http://www.dofactory.com/Patterns/PatternObserver.aspx

See also java.util.Observer

Rule #7: Combine Layout Managers
Don’t inspect the layout managers and decide that Spring Layout is for you and that’s all you use. They can and should be combined in order to achieve the best control and fluidity and clarity of purpose.

Test your layouts under many conditions: different size screens with different resolutions and on different platforms. Some of the Swing stuff is just not the same on a Mac as on a PC. Aside from the obvious differences, as an example, colored backgrounds on Jtable headers simply did not work in JDK 1.4 on the Mac. Make sure that when you resize your window it fluidly reorganizes all of your components. Users will do this and should be allowed to, and if your UI tumbles apart when its resized, you did it wrong.

Here are a few final points to help you make sure it is production-ready, and encourage you to use finishing touches.

  • Use keyboard shortcuts, as discussed above. Accelerators give power users keyboard shortcuts to bypass menus, while Mnemonics let you navigate with the keyboard (http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html#mnemonic).
  • Select icons and use them on your menus and throughout your app. You can use Sun’s icons from here: http://java.sun.com/developer/techDocs/hi/repository/ They aren’t beautiful or even very good. But you should use them because Sun thinks they are good enough, they are complete and clear, and it is a waste of time to create your own for this project.
  • Set Tool Tips for everything. Consider whether or not you need to use the Accessibility API (http://java.sun.com/docs/books/tutorial/uiswing/misc/access.html). Defend your choice in your choices.txt.
  • Consider using the Preferences API introduced in JDK 1.4 to have your app remember the previous location of the window the last time it was closed.
  • Put borders on your panels to logically separate areas of your UI using BorderFactory.
  • Use JScroll pane. Just because your database only has 25 records doesn’t mean your UI should only handle 25 records.
  • Consider using a JToolbar in addition to Menus.
  • Put labels at the top of your pages so your user knows where he is.
  • If you have a wizard, tell the user what step she is on (“Step 3 of 5”).
  • Consider your server—do you need a GUI for that?
  • Use status messages.
  • Use a Shutdown Hook to clean up any objects and exit safely.
  • Center your window on the screen.
  • Build in logging using the Logging API introduced in JDK 1.4 now. Do not wait. Log absolutely EVERYTHING. Then modify your Handler to tune out the noise as necessary—don’t remove logging statements.
  • Don’t go crazy. You are trying to make the best UI possible. That is assuredly not the UI that shows off how you can cram the greatest number and variety of components into a single panel.
  • Use confirmation dialogues as apporpriate.
  • Note that your requirements mean that you need a dialog on start up to allow the user to specify a few options. You have some choices to make here.
  • Use JFormattedTextField to validate data. Users are guaranteed to type any ridiculous thing, out of negligence, ignorance, and pure spite. Don’t get suckered in.
  • Use the Ocean Look and Feel. It is nice looking, and it is available on all Platforms. Windows LNF is not. Your grader will almost certainly be using a Solaris OE box.

Rule #8: Use common sense!
I have seen this on real UIs, unbelieveable as it is: a pair of check boxes grouped together—one that says “Yes” and one that says “No”. Know what kinds of situations controls are intended for and use them only as intended.

Rule #9: Make the workflow obvious—don’t confuse choices with options.
Users need to be set on a path where they can’t wander away and lose their place and screw up what they were doing and lose their work. But they need to be allowed to change their minds (Cancel). This is a fine line. Make your UI so they can change their minds without killing themselves, but don’t make them think. You just have to feel your way through that one.

Check out
http://www.useit.com/ for more info.

October 05, 2006 in Articles | Permalink | Comments (1)

JavaDoc with Java 5, including Generic Type Parameters, Package comments, and Overview

JavaDoc has changed in a couple of ways, and I thought I would highlight some of those changes. This post also includes a couple of things that aren't changes, but that are probably a good idea to do in your docs.

How to Document Generic Type Parameters
In order to avoid the hassle of introducing a new keyword into Java, Sun chose to use the @param tag to identify generic type parameters for classes
and methods. Here is an example of a class with a class-level type parameter:

/**
* The interface that RulesEngines must adhere to.
*
* @param <T> Indicates that for this instantiation of the engine, the type
* of Rule implementation we want to execute. Because there can be lists of
* different implementations floating around, we want to not force clients
* to cast or extract the kernel rule to be evaluated from their wrapper
* (say, a
{@link UserDefinedRule} or any application-specific wrapper). This
* way, they can specify the type parameter and we at least know that the
* engine can reliably fire the rules.
*
* @author E Hewitt
* @see com.dte.rules.engine.SimpleRulesEngine
* @see com.dte.rules.engine.EventHistory
* @since 1.0
*/
public interface RulesEngine<T extends Rule> {

//...

It works the same way for methods:

/**
  * Puts a Rule into the Engine, to be extecuted in this session. Every rule
  * that has been added to the Engine will be inspected for each object in
  * the engine to find matches, unless some directive indicating otherwise
  * is returned with the execution result.
  *
  * @param rule the rule implementation to add. A UserDefinedRule is
  * typically the sort of object an end-user would create and save to a
  * database for execution later.
  * @return a Handle on the Rule so you can get it out later if necessary.
  */
RuleHandle addRule(T rule);

Eclipse automatically inserts these with Ctrl + Space, and NetBeans probably does too, but I don't know.

Changes to Package.html
Package.html is a file used to write general comments about the purpose of a package. While package.html still works in Java 5, there is a new and preferred way to do it now. Instead of writing an HTML file, write a Java source file. Here's how:

1. In the package you want to document, create a file called package-info.java.
2. Use regular Javadoc comments to comment the single line of Java code in the file--the package declaration.

Translate your package.html file to package-info.java files. Here is an example.

package.html:

<html>
<head>
  <title>com.dte.rules</title>
</head>
<body>
  <p>
   Provides the classes that client applications will use in
   creating rules of their own.
  </p>
  <p>
   Look at
{@link com.dte.rules.Rule}, {@link com.dte.rules.Consequence},
   and
{@link com.dte.rules.Salience} to get started.
  </p>

  @since 1.0 

</body>
</html>

Here is the same file as package-info.java:

/**
* Provides the classes that client applications will use in creating rules
* of their own.
* <p>
* Look at
{@link com.dte.rules.Rule}, {@link com.dte.rules.Consequence},
* and
{@link com.dte.rules.Salience} to get started.
*
* @since 1.0
*/
package com.dte.rules;

Note that Eclipse doesn't want you to create a source file with that name, so just create it as a regular File with a .java extension.

Overview.html
Overview.html, like package.html, is used to illustrate the purpose of your project, and provide a starting place to point to further documentation. This actually did not change in Java 5, but not many of our projects here appear to use overview.html, and it is a good idea to use it. So here is how, since we're on the topic:

1. Create a file called overview.html. This should probably be in a directory called "docs" under your project.
The HTML should be simple, and include the name of your project and a brief description of what your project does. Like this:

<html>
<head></head>
<body>
<h1>Rules Engine</h1>

<b>The Rules Engine Project</b> defines and implements an engine capable
of executing a set of business Rules on a set of Facts in order to find
matches, and execute a Consequence on matches, much like an Expert System
such as JESS or a Rules Engine such as JBoss Rules.
</body>
</html>

2. In your Ant task to generate your JavaDoc, add the "overview" attribute to point to your overview.html file. Like this:

  <javadoc packagenames="com.*" serialwarn="false"
   windowtitle="${javadoc.window.title}" classpathref="docsCp"
   sourcepathref="srcs.path" destdir="${javadoc.dir}" author="true"
   version="true" verbose="true"
   overview="${overview.file}"
   use="true" private="true">
   <bottom>
    <![CDATA[<em>Copyright ©2006 - Eben Hewitt, All Rights Reserved.</em>]]>
   </bottom>
   <link href="${java.api.link}" />
  </javadoc>

The result is that the overview text will be included in the index page of your JavaDoc, above your package listings.

InheritDoc
Also, in case you did not know, you can inherit documentation. If you have a base class or an interface that defines a method that is well commented, you don't have to copy the comments into every implementation. You just just do this:

/**
  *
{@inheritDoc}
  */

And the complete text of the JavaDoc from the interface or parent class will end up where it should, with the addition of something like this at the end of your comment:

Specified by:
setGlobalContext in interface RulesEngine<T extends Rule>

If you want to add something to the inherited comment that is particular to your implementation, you can do so:

/**
  *
{@inheritDoc}
  * <p>
  * This implementation throws a RuleException if you call it a second time
  * before the engine has been released.
  */
public void setGlobalContext(GlobalContext context) {
            //....
        }

And you'll get both the original comment and your addition.

Including Multiple Projects' JavaDocs in a Single Doc Instance
You may work on large projects that are dependent on totally seperate, external projects. You can include dependent projects' JavaDocs in your main project if you like. I do this for example in the RPM project, which depends on both the Shared project and the Rules Engine project. Just use the group element nested within the javadoc task, like this:

  <javadoc packagenames="com.*" classpathref="cp"
   sourcepathref="srcs.path" destdir="${javadoc.dir}"
   author="true" overview="${overview.file}"
   version="true" verbose="true"
   windowtitle="${javadoc.window.title}"
   use="true" private="true">
   
   <bottom>
    <![CDATA[<em>Copyright ©2006 - Eben Hewitt, All Rights Reserved.</em>]]>
   </bottom>
   <link href="${java.api.link}" />
   <group title="Regional Pricing Maintenance"
    packages="com.dte.pricing.*" />
   <group title="Shared"
    packages="com.dte.shared.*" />
   <group title="Rules Engine"
    packages="com.dte.rules.*" />
  </javadoc>

Then ALL of the docs are included in the RPM docs, as if they were in the same project. You don't even lose your subproject's Overviews!

For more information, see http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html

September 26, 2006 in Tech Notes | Permalink | Comments (0)

The Tao of Development: From Programmer to Developer

I recently began a course mentoring some colleagues in Java development. They have passed the SCJP and are beginning the SCJD project. The question of the difference between a Programmer and a Developer came up, and has been a question floating around the web for some time. Erik Sink has written about the difference here, for example: http://www.ericsink.com/No_Programmers.html

I had some thoughts on the matter, and while the terminology itself is not interesting, it proves useful as a function. So here is what I have come up with:

Programmers specialize in writing code. Developers contribute in multiple, diverse ways to a project’s success. Developers write documentation and specs, perform analysis, and work comfortably throughout the tiers of complex applications.

Programmers make programs that compile and run. Developers make programs that are elegant. Developers make it elegant because beautiful is better than ugly. Because creating a beautiful thing is personally meaningful. Because elegance means "succinctly yet completely expressive". That makes elegant code easier to understand for the programmer who will inherit our code. Because programs that use a small amount of intuitive code to great effect are superior to programs that use a large amount of code that is difficult to understand to achieve the same effect. Because elegance is useful theoretically. Because elegant is inviting. Because elegance means unusually effective and simple. Because in Western culture, elegant means consistent, and focused on the basic qualities, and those are viewed as beautiful. Beautiful is desirable for no reason.

Developers know the difference between complicated and complex, and reject complication.

Programmers want to show everyone their activity. Developers know that it is only progress that matters.

Programmers run their code to find out if it works. Developers write automated test cases to make sure that it works. Developers regression test when code changes.

Programmers rely on QA to find out what is wrong with their code. Developers rely on QA as a sanity check to ensure that their code works equally well in unexpected circumstances.

Developers participate actively in Code Reviews as both the Coder and the Reviewer. Developers know that you often learn as much by teaching as you do by learning. Developers mentor every chance they get.

Programmers hire other programmers and worry they will be outshone. They like to be the best. Developers see everyone’s strengths, and surround themselves with more skilled people than themselves.

Programmers consider only their current algorithm, or method, or class. Or perhaps their current use case. Developers consider their entire system, and consider their system as a small piece of a universe of systems that will all have to live together. Developers consider how their system impacts that universe. Programmers think locally. Developers think globally and act locally.

Developers read to push the boundaries of their craft because they understand that they are not just making a program, but adding to the complexity of the entire IT ecosystem that includes other systems, hardware, networks, and more. They are not satisfied being good coders. They must be good IT citizens.

Developers demand to always and only tell the truth in their design, no matter what. That means that their code reflects the real world—not a part of the real world that is modified to work in some program’s use case. Developers do not view the programming problem before them as fixed. Developers know it is fluid, and they are not afraid to change the programming problem if it is necessary in order to tell the truth.

A Programmer’s program is a private language; it uses every bit of the language, and is rigid. It cannot be translated. You can translate a Developer’s program to plain English, and it reads like a children’s book.

Programmers are afraid of what will break in their program when the business rules change. Developers know that when the business rules change, their program will absorb it, because their program tells the truth about the world, and the world makes sense. Extending their program is no more strange or difficult than adding a hobby to your life.

Developers know when code becomes legacy code—the moment it is committed to the repository. Legacy doesn’t mean old—it means existing in the world, so someone will have to determine what is true about it—what it does, doesn’t do, how it works, why it exists, how it relates to other things. Developers are very careful to make legacy code, because they know how expensive it is.

Developers write clear, concise, helpful, correct, updated, cross-referencing documentation. They feel silly doing it, because their code is so simple, expressive, and only ever does one thing—the one thing for which it is named.

Programmers do what the customer asks for. A programmer is a passive receptacle for the customer’s "requirements". Developers refuse to accept a passive role in the customer relationship. Developers know that customers typically describe solutions when they think that they are describing requirements. Developers are brave enough to design the program, and not allow the customer to do what he is not qualified to do.

Programmers listen to what the customer says and believe they are doing their job to simply make what is described. Developers refuse this, because they know it hurts the customer. The Developer hears what the customer says, and also hears what they don’t say. The Developer gets the customer to divulge the problem, not the solution. The Developer does this by knowing the right questions to ask. Only in this way can the Developer get the customer to talk less and say more.

The Programmer is a mirror for the customer’s text. The Developer provides the solution based on true active listening. The Developer interprets the customer’s script, and directs a film.

The Programmer enjoys gathering requirements, because they are finding out what they get to make. They feel their power as they think of ways to implement the requirements. The process excites the customer, because everyone enjoys expressing his desires. The Developer knows nothing is more boring than requirements. The Developer knows his role in the process is to break down everything the customer says until there are no more assumptions, but only many hundreds or thousands of tiny, raw, simple, undeniably true statements about the world. Each of these statements is as interesting as the entries in a phone book.

Programmers feel that they are smart, and focus on programming the customer’s solution exactly as outlined. Developers forget what they have to program. They work hard to maintain only a foggy idea about the business rules. Programmers work in photographs. Developers work in rough chalk sketches. Developers actively do their best to remain dumb about the business rules, and continually express gratitude for the patience of those working with them. Developers stay dumb about the rules in order to stay general. Developers know that rules are at once like commandments—the most important thing, the only thing, the law—and yet also as worthless as gossip on the most trivial breeze. Developers at once respect the rules simultaneously as law and as gossip. The Programmer cares too much for the rules, and he will write a world where the rules are the only true things. The Developer stays dumb about the rules, and so he will write a world where the rules can be true. Because he knows he cannot remember and understand them all, they must be adhered to with utmost precision. But only indirectly. The Developer understands there is a paradox in free will. He does not make mistakes about causation.

The Programmer writes a program that represents the business solution. He loves his solution because he is married to it, and he must guard it jealously from change. The Developer writes a world that the solution inhabits. The Developer knows that his solution is incidental, and has no particular feeling for it. He admires its beauty, because it is something in the world that is pretty, like a leaf.

The Programmer’s program is a room. He cares deeply about the walls, the ornaments, the flooring, the treatments, the colors, the dimensions, and everything about the room. He is delighted when his customers see it. He wants his customers to use what he has made, to feel the textures of the rich fabrics. He will be praised for such richness. The Developer wants the customer to achieve her goal. He knows that his program is successful when it is invisible. He knows it is not the walls and floors and windows that the customer lives in, but the empty space in the room that the customer lives in. He will not be praised, because the customer will believe that the Developer has done nothing--the software appears to have been there all along.

Programmers only ever see one choice before them. Developers have many choices before them. They know they have found the right choice when it comes to appear as if they only ever had one choice all along.

Programmers like programming, and will accept programming work in order to have the pleasure of making a program. Developers ask what interest the program serves. Developers know they are always serving an interest, and their pleasure derives from being in the service of that interest. A Developer knows that it is the interest that matters, and not the program. The fact that he happens to be the person who writes the code is interesting only to him, and is not interesting to anyone else, and is not intrinsically interesting. Developers like complex problems, and are not interested in uninteresting things, such as the fact that they are developers.

Programmers are hired for a job. Developers cannot be hired. Developers must be trained to be Developers from the inside.

Programmers like it that people think they are smart. Developers like it when they know they have been useful. They know they are no smarter than a painter or a cat.

Programmers care intensely about their view of a project. They are agreeable and flexible, and change their views as the business appears to require. Developers know that their view of a project is not interesting to anyone but them. Yet they never compromise on what is required to make the project successful, even if it is unpopular. They do not have to compromise, because they cannot be hurt.

Programmers do not ask questions, because they are afraid of revealing what they do not know. Developers ask questions because they are in love with learning.

Programmers know everything. Developers know they don’t know anything at all. You become a Developer when you give away to others everything you know and everything you do not know.

September 08, 2006 in Articles | Permalink | Comments (0)

Sun Certified Enterprise Architect Cram Notes

I passed the first test in the SCEA exam today. So I thought I would post some notes that I made as a last minute reminder. These are just meant as cram notes, to look at while you're waiting in the lobby or something right before the test, and are not intended as study notes.

EJB
The EJB specifies how many instances to pool at deploy time.

Valid lifecycle for Entity: Does Not Exist, Pooled, Ready

Finder methods of Entities return either Remote Reference or Enumeration

Entity Beans can NOT use BMT.

Only SFSB can implement SessionSynchronization interface.

Application Exceptions do not cause transactions to rollback.

Create method is optional in Entity home.

EJB Life Cycles:

SLSB:Does Not Exist, Ready

SFSB: Does Not Exist, Ready, Passive

Entity: Does Not Exist, Pooled, Ready

Primary Key:
Must override equals and hashcode
Can be compound or single field
Can be undefined until deployment
All fields must be public
When using CMP, a no-arg constructor is required
Bean class provides implementations of

1) Home interface methods 2) Remote interface methods 3) EJB callbacks

EJB CONTAINER MODEL

Acts as a Decorator.

The bean pool acts as a Flyweight pattern implementation.

EJBObject and EJBHome are examples of Decorators because they provide transactions and security.

Container Adds: Life cycle mgmt, Naming, Object Distribution, Persistence, Security, Transactions, Concurrency

TRANSACTION ATTRIBUTES

Never: requires that no transaction already exists. Throws RemoteException if one does.

Not Supported: Transaction will be suspended if one exists.

Supports: uses the client transaction context if it exists, or no transaction context otherwise.

Mandatory: requires an existing transaction. Throws TransactionRequiredException if one does not exist.

Required: causes the enterprise bean to use existing transactional context if it exists, or to create one otherwise.

Requires New: always creates a new transaction context before the method call, and commits or rolls back after the method call. Any existing client transaction context will be suspended until the method call returns.

Enterprise beans that implement interface SessionSynchronization must have either the Required, RequiresNew, or Mandatory transaction attribute. Implement SessionSynchronization in your Stateful Session Beans if you need to be aware of transactional events. For CMT ONLY. With bean-managed, you’re demarcating the transactions so you already know when these events occur.

ACID

Atomic: transaction must execute completely or not at all.

Consistent: the database must be in a legal state when the transaction begins and when it ends. This means that a transaction can't break the rules, or integrity constraints, of the database.

Isolatable: Transaction must execute without interference from other processes or transactions.

Durable: Data must be written to the data store before the transaction completes.

TRANSACTION ISOLATION LEVELS

Serlizable: all transactions occur in a completely isolated fashion; i.e., as if all transactions in the system had executed serially, one after the other. The DBMS may execute two or more transactions at the same time only if the illusion of serial execution can be maintained. At this isolation level, phantom reads cannot occur

Repeatable Read: All data records retrieved by a SELECT statement cannot be changed; however, if the SELECT statement contains any ranged where clauses, phantom reads may occur.

Read Committed: Data records retrieved by a query are not prevented from modification by some other transaction.

Read Uncommitted: In this isolation level, dirty reads are allowed. One transaction may see uncommitted changes made by some other transaction.

TRANSACTION TERMS

Phantom Read: occurs when, during a transaction, two identical queries are executed, and the collection of rows returned by the second query is different from the first.

Non-Repeatable Read: non-repeatable reads may occur when read locks are not acquired when performing a SELECT.

Dirty Read: A dirty read occurs when a transaction reads modified data from a row that has been modified by another transaction, but not yet committed.

COMMON ARCHITECTURES

Non-Functional Requirements

Performance, Scalability, Reliability, Availability, Extensibility, Maintainability, Security, Manageability

PROTOCOLS

HTTP 80
HTTPS 443
FTP 21
JRMP 1099
IIOP 535
Telnet 23

SSL Protocol runs below HTTP and above TCP/IP

DESIGN PATTERNS

Abstract Factory: Provide an interface for creating families of related or dependent objects without specifying their implementations.

Builder: Separate the construction of a complex object from its representation so that the same construction process can create different representations.

Factory Method: Define an interface for creating an object, but let subclasses decide which class to instantiate.

Prototype: Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.

Singleton: Ensure a class has only one instance with global access.

Adapter: Convert the interface of a class into another interface clients expect so they can work together.

Bridge: Decouple an abstraction from its implementation so the two can vary independently.

Composite: Compose objects into tree structures to represent part-whole hierarchies so that clients can treat individual objects and compositions uniformly.

Decorator: Attach additional responsibilities to an object dynamically.

Facade: Provide a unified interface to a set of classes in a subsystem to make it easier to use.

Flyweight: Use sharing to support large numbers of fine-grained objects efficiently.

Chain of Responsibility: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.

Command: Encapsulate a request as an object to support undo operations, queue or log requests.

Interpreter: Given a language, define its grammar and an interpreter of sentences in that grammar.

Iterator: Access elements of an aggregate object sequentially.

Mediator: Define an object that encapsulates how a set of colleague objects interact so they don't have to refer to each other explicitly.

Memento: Capture an object's internal state without violating encapsulation so that it can be restored to this state later.

Observer: When one object changes state, its listeners are notified and updated automatically.

State: Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

Strategy: Define a family of algorithms, encapsulate each one, and make them interchangeable.

Template Method: Define the skeleton of an algorithm, deferring some steps to subclasses.

Visitor: Represent a new operation without changing the classes on which it operates.

MESSAGING

Pub/Sub: Topics. Push.
P2P: Queues. Pull. (send and forget)

I18N

Items subject to I18N:
Languages for Messages
Formats of Dates, Numbers
Sort Order (Collation)
Currency symbol & position
Tax and other legal rules
Cultural Preferences

Java Supports I18N:
Properties, Resource Bundle, Locale, Unicode, java.text package, InputStreamWriter/OutputStreamReader

Collator: abstract base class for performing locale-specific String comparisons. Subclasses implement different comparison algorithms. RuleBasedCollator (provided with JDK) is a concrete subclass that provides simple, data-driven, table collator.

CollationElementIterator: used as an iterator to walk through each character of an international String.

CollationKey: represents a String to compare when using Collator. Comparing two of these returns the relative order of the strings they represent. Using this is faster than actual String comparisons.

BreakIterator: contains methods for finding boundaries of line breaks, sentences, words, and characters in text.

CharacterIterator: defines protocol for bi-directional iteration over a set of Unicode characters. Methods return either the index or the character value. Classes implement this interface to provide this functionality for various sequences of characters.

StringIterator: provides this functionality for iterating over a string.

SECURITY

A VPN is a trusted network running over a non-trusted network.

Unsigned applets run in the sandbox. Signed applets with a public key by trusted parties have full access. For example, a signed applet can connect to arbitrary hosts. If a policy file is created with grant privileges, an applet will be restricted to the grants in the file, regardless of signing.

A java.security.MessageDigest only provides proof that a piece of code has not been altered.

In SSL handshake, 1) Server is validated to client 2) client and server choose

a crypto algorithm.

After signing a JAR file, files could be added to it later without necessarily invalidating the signature.

Asymmetric cryptography means a separate key for encrypting and decrypting.

Even if applet code is signed, the browser’s policy may prevent it from certain things. The policy file will need to explicitly grant permissions for what it wants to do, ie, read local files.

FIREWALL

Packet Filter Firewall: Looks at the information related to IP address of a packet, types of connections, etc. and then provides filtering based on that. Uses this to decide which packets to let through and which to deny. IP spoofing may fool it.

Application-Level Proxies: Work at the application level to provide proxy services. Allows more specific inspection of the packets. Can use application level knowledge to decide what to filter. Usually requires separate proxy for each type of application you want to filter.

Stateful Packet Inspection Firewall: Examines and remembers outgoing packets so that when incoming packets come in, that information will be used to determine whether or not to let the incoming packets through. For example, if any outgoing packets didn’t request an incoming packet, it will be filtered.

Java sandbox consists of following elements:

Byte code verifier, Access controller, Security manager

Class loader (applet class loader, url class loader, rmi class loader, default internal class loader, custom built class loaders)

Security package (security provider interface, message digests, keys, certificates, digital signatures, encryption)

July 18, 2006 in Tech Notes | Permalink | Comments (2)

« | »
My Photo

Recent Posts

  • My Upcoming Speaking Schedule
  • Service Design Review Checklist for SOA Governance
  • 10 Ways to Beat Writer's Block
  • Moving Main Blog to Cassandra Guide
  • A Literary Life: Our Book Reorganization Project
  • Talk Abstracts for Business & Technology Summit 2009 in Bangalore, India
  • 97 Things Every Software Architect Should Know on Kindle, iPhone, in Japanese
  • Using SOAP Faults and Exceptions in Java JAX-WS Web Services
  • Recipe for the Perfect Margarita
  • Towards a Rhizomatic Software Architecture
Subscribe to this blog's feed

Reading

  • Robert Hanmer: Patterns for Fault Tolerant Software (Wiley Software Patterns Series)

    Robert Hanmer: Patterns for Fault Tolerant Software (Wiley Software Patterns Series)

  • Kerrie Holley: 100 SOA Questions: Asked and Answered

    Kerrie Holley: 100 SOA Questions: Asked and Answered

  • Haralambos Marmanis: Algorithms of the Intelligent Web

    Haralambos Marmanis: Algorithms of the Intelligent Web

  • John Hebeler: Semantic Web Programming

    John Hebeler: Semantic Web Programming

  • Steven Bird: Natural Language Processing with Python

    Steven Bird: Natural Language Processing with Python

Categories

  • Articles
  • Books
  • Food and Drink
  • Recipes
  • Tech Notes
See More

July 2010

Sun Mon Tue Wed Thu Fri Sat
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Twitter Updates

    follow me on Twitter