Rick Hightower's Sleepless Night in Tucson
Default style (Cherry Eve). Switch styles (Capricorn). XML Feed Calendar
All | technology | misc | jsf | maven | hibernate | spring
ArcMind: JSF, Spring, and/or Hibernate Training, Consulting.  
20060208 Wednesday February 08, 2006

Eating out, not as much enjoyment

Because I travel a lot, eating out is a lot less fun than it used to be. I just don't enjoy the restaurant food like I use to. Now that I have been going to cooking school, it is even less enjoyable.

I just had a peppered steak tonight in a mushroom sauce, and all I could think it that I could do this so much better. Granted this was not an expensive restuarant, but my standards are higher. This also happened to me last weekend too. I went to a trendy new restaurant in Tucson and it was horrible. The meat was tough.

There are still dishes I like at my normal haunts.

We (me and my wife) made this awesome steak in a brandy sauce. It came out better than it did in class. We made it last week, and it was really good. She made it in class, and I made it at home (with some help from her).

The last time I cooked at home, I heated the pan too much. When I put the butter in the pan, the butter immediatly ignited. It was a bit scarry.

I don't think I can have a steak at a normal restuarant anymore.

Feb 08 2006, 10:17:05 PM MST Permalink

Add a Comment

Clover code coverage (Eclipse plugin)... found two bugs

I started using the Clover code coverage Eclipse plugin to improve my test coverage more rapidly. I've used code coverage before, but not the Eclipse plugin. It took me a few minutes to configure it. (A few longer than it should have b/c I am using perforce and the .project and its ilk were read-only.... the plugin in silently failed with read-only files).

So I am doing code coverage, trying to improve my percentage of coverage, which to some seems futile (even to me at times). I found two unknown bugs by seeing code blocks that were never called (it was assumed that they were). I prefer the IDE based feedback to the HTML reports; it feels more real time. This caused me to improve the tests and fix the as of yet unknown bugs.

It's odd finding bugs in code you know people are using and have not been found yet. I rather find them this way and fix them before someone else finds them.

The net effect, I am more of a code coverage believer than before. These were not new bugs. They were at least three weeks old.

When do you do code coverage? Always? Periodically?

To me it usually depends on where I am working and how important it is to the client. I see its value for sure, but there are tradeoffs. It seems with the Eclipse plugin, the tradeoffs are minimized and it is more transparent.

So I spent a lot of time today taking a very important class from 35% code coverage to 96% code coverage. It the end it was worth the effort (b/c of finding and fixing the bugs and improving the tests). I like the feedback that the Clover code coverage plugin provides. I want to use it more often.

Feb 08 2006, 08:05:22 PM MST Permalink

Add a Comment
20060203 Friday February 03, 2006

Hibernate Query: getting rid of duplicates when sorting

I have an Hibernate query that uses quite a few criterias and specifies sort options. The probem is that the query returns duplicates. Now usually, I just wrap a query result in a HashSet, which is then wrapped into an ArrayList to get rid of duplicates, which although not ideal, is needed and documented in the Hiberante docs. But now, I want to get rid of the duplicates and maintain the sort order.

I am using Hibernate pagination so I don't expect to have more than 10 results at a time.

Here is the initial solution.

    /* This removes duplicates from the returned list */
    private List uniqueList(Criteria criteria) {
        List list = criteria.list();
        Set idSet = new HashSet(list.size());
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            Object entity = (Object) iter.next();
            Object id = getId(entity);
            if (idSet.contains(id)) {
                iter.remove();
            } else {
                idSet.add(id);
            }
        }
        return list;
    }

Another problem is that since I am using Hibernate pagination, the list will be shorter than I expect.

 

                /* Specify values for pagination. */
                criteria.setFirstResult(startRecord);
                criteria.setMaxResults(numRecord);
                return uniqueList(criteria);

Before this method gets called, I execute the above. What I need is a way to only return distinct objects and have pagination work.

 

BTW for other reasons I am using the Criteria API. I think I might have found the solution.

    /* This removes duplicates from the returned list */
    private List uniqueList(Criteria criteria) {
       
        criteria.setProjection(Projections.distinct(Projections.id()));
        return criteria.list();

    }

The problem is that Projections.id() does not seem to exist in my version of Hibernate, but is in the JavaDocs under http://www.hibernate.org/hib_docs/v3/api/.

I am using the following Hibernate:

<dependency>

    <groupId>hibernate</groupId>

    <artifactId>hibernate</artifactId>

    <version>3.0.5</version>

    <scope>compile</scope>

    <type>jar</type>

</dependency>


I wonder what the current release is. Hopefully this is in the 3.1.2 release and hopefully it does the trick.

It seems Hibernate 3.1.2 is not in the ibiblio Maven 2 repo. (Earlier today, neither was the Spring 2.0 M2 release.)

The query worked like charm except now it returns ids instead of objects. Not what I wanted. I should of seen that one coming... I've used projections before.

There seems to be no way to do distinct.

You can specify                         criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
but that seems to have nasty consequences in that it does not seem to work with pagination.

The issues is that the pagination happens in the db, but the result transform happens in Java. In otherwords, the horse left the barn and urinated on the flowers already. I really need a distinct option. I realize that this is a db performance hit, but without it I'll need to hit the db a few times before I can get all of the objects I need.

It seems Hibernate pagination is unusable if there are duplicates in the results. You need a way to specify the id is distinct on the database server. This is allowed for Projections. It should be allowed for Restrictions.

Feb 03 2006, 03:47:16 PM MST Permalink

1 Comment

Managed Beans in Spring application context

I held out for a while. I resisted the temptation to switch to Spring 2.0. I can resist no longer.

I am downloding Spring 2.0 M2, which was just released this week so I can get its scoping support.

I've promised the project manager that I would not use any new features except the scoping support, and assured him that the bulk of the framework did not change (as reported in Florida and the Spring conference).

I'll let you know how it goes.

________________________________________

Update:

So far not so good....

It seems they no longer include JSF support in the spring.jar file.

I get this when I first start up the app with the Spring 2.0 M2 jar file.

 

javax.faces.FacesException: java.lang.ClassNotFoundException: org.springframework.web.jsf.DelegatingVariableResolver

at org.apache.myfaces.util.ClassUtils.simpleClassForName(ClassUtils.java:162)

at org.apache.myfaces.config.FacesConfigurator.getApplicationObject(FacesConfigurator.java:506)

at org.apache.myfaces.config.FacesConfigurator.configureApplication(FacesConfigurator.java:446)

at org.apache.myfaces.config.FacesConfigurator.configure(FacesConfigurator.java:130)

...

I think I remember Colin telling me they were going to split out the support. It seems

  • the JSF support is now in a jar file called spring-web.jar
  • and the hibernate support is in a jar file called spring-hibernate3.jar
  • and the dao support is in a jar file called spring-dao.jar

I understand why they did this, but it still is a pain for now. I wonder if the above is all I will need.

____________________________________________

Seems I was wrong. JSF support is in the spring.jar file as well as DAO support. But it seems Hibernate support is not, but for some reason iBatis is. (I forgot to refresh eclipse after I ran the maven command to copy the jar files to WEB-INF/lib).

I added the following to my pom.xml:

<dependency>

    <groupId>springframework</groupId>

    <artifactId>spring</artifactId>

    <version>2.0-m2</version>

    <scope>compile</scope>

    <type>jar</type>

</dependency>

<dependency>

    <groupId>springframework</groupId>

    <artifactId>spring-hibernate3</artifactId>

    <version>2.0-m2</version>

    <scope>compile</scope>

    <type>jar</type>

</dependency>

a Feb 03 2006, 01:05:19 PM MST Permalink

1 Comment
20060131 Tuesday January 31, 2006

My response to Bob Lee's comments on Spring

I'd like to start off. I truly feel Bob Lee is brilliant. Call it what you want, but I honestly respect Bob's opinion very much. Anyone who responds to his post with personal attacks about his lack of techncial prowess is misled.

I've been using Spring for 2.5 years, and I enjoy using it.

Problems stated:
Many of the complaints you make about Spring are fixed in the 2.0 release. Some of the fixes, I don't agree with, but that is off topic.

No problem using Spring IoC container:
I don't see the problem putting course grained objects in the application context file (Spring IoC container if you will).

First the objects do not have to go in one large file. You can have a file per logical area or divide them up in any way that makes sense.

Second, objects defined in this file can be decorated with Aspects (even introductions) and add behavior that the client object and the object itself don't know about. This is very extensible. I have used this feature, and it is a real effort saver, and with autoproxies, it can be done very succinctly. How would you do this w/o Spring? Roll your own?

AspectJ you say. Well okay, but AspectJ has its own pluses and minuses. I'll leave my thoughts on AspectJ for another day.

Third, you can change the implementation you are injecting. For some client frameworks and application this may not be a big deal for others it is. And yes, sometimes you do want to do this. Take Acegi for example, you can use Spring IoC to configure Acegi. You can inject different authentication mechanisms. You can have a development version of Acegi perhaps using mock authentication, and you can also have an integration environment where you use SiteMinder, CAS, etc. (hopefully one day a production env. and don't forget the QA env.). Acegi is very extensible and by simply reading the easy-to-read Spring app context, you can see its extension points. I have used this feature and it is a real effort saver. How do you suggest accomplishing this w/o Spring? Let me guess roll your own.

Fourth, the Spring application context file is about the easiest thing I know of to read. It is really intuitive. You act as if uses Latin for elements. <etherialize-instantiation> or something. To me, it is the very definition of intuitive.

I feel very strongly that the Spring framework promotes the use of IoC and AOP. Can it be improved? Sure. But, it is the best implementation that I know of. Certainly the most popular as well.

Spring does promote good practices and it is lighter weight than J2EE.

I wrote this white paper that is geared toward developers who are learning about Spring IoC and Spring AOP for the first time. In the paper, I state all of the reasons I feel developers should consider using Spring. I will not repeat them here.

Many of the principles and practices in JEE 5 are very similar to what is practiced in Spring. And Spring, is a lot more elegant, evolvable implementation of these principles and practice. If you know of a better framework, let hear about it.

This is officially my 2 cents...

Now I should go back to billable hours or spend some time with the family.

I've fresh French bread to make.

In other news, my French bread came out perfect.

Jan 31 2006, 06:37:42 PM MST Permalink

2 Comments

Spring under attack?

Spring is not exactly the framework that everyone loves to hate. It seems Bob Lee, a brilliant developer in his own right, does not agree with the implementation of Spring IoC mechanism, and now Spring is under attack by two classes of people: folks who think they are too smart for Spring (misinformed though they are), and people who never really understood the value of Spring, and never took the time to figure it out.

There is nothing you can do about the first group. For the second group, I created this white paper: http://www.arc-mind.com/whitepapers/SpringIntroduction.pdf. The paper is more about the why of IoC, AOP and Spring templates.

Btw Bob Lee is not against IoC or AOP, two foundations of Spring. His point of view is that you should create your own IoC container, and those in-the-know know that he created his own widely unsuccessful AOP framework (which was one of the first and way ahead of its time).

After studying Spring, I could write my own IoC, but why would I want to? Spring does what I need an IoC container to do.

I am not a Spring die hard fanboy see my comments on the JBoss microcontainer, but I do like and use Spring. So maybe Bob is right and Spring IoC could use some overhaul. I am certainly not convinced of this per se.

The parade of misinformation about Spring is shocking. In short, IoC and AOP are good things (Bob of all people acknowledges this.). Spring is the most successful implemetation of those important concepts (IoC and AOP).

Even if Spring were merely an IoC/AOP container, it would be worthy of consideration; however, Spring goes beyond just being an IoC container or an AOP framework. Spring goes one step further than the other containers which support IoX and AOP by building a framework to simplify J2EE development.

Please investigate Spring and make your own decisions.

Jan 31 2006, 04:50:31 PM MST Permalink

5 Comments

Fun, Food, Wine, Friends and Family... the joy of cooking

We had our second big dinner party since we have been going to cooking school. It turned out well. The meat was a little undercooked and we had to put it back in the oven that was the only snag. We were not used to cooking a roast that big.

 

We had 19 people over for dinner. We served four different wines. One wine served before dinner, one during dinner and one after dinner. The other was a

cooking wine. I drank it while I was cooking (it was also used in the French Onion Soup).

 

The wine from Spain stole the show. It was a vintage bottle given to me by a friend. This was my first Spanish red. It was very good. I don't know much about

Spanish wine, but I am going to learn. I served a Riesling with desert and a Pinento (sp?, Italian Sparkling Sweet Red) before dinner, which was good but too sweet for some (not me). The Riesling was perfect not too sweet but sweet. The Spanish red was dry yet fruity with deep currents taste (even a bit plumy) so it left some folks behind (those that don't enjoy a dry wine). The Spanish wine seemed to complement the meal. The cooking wine was a Chardonnay that was also part of the French Onion Soup. Those that stayed later helped me polish off the Chardonnay.

 

We had/made French Onion Soup (with homemade beef stock and homemade croutons with Swiss cheese), salad with homemade Blue Cheese Dressing, roast in Gorgonzola sauce, homemade Peach Cobbler, and lemon tarts. The only thing we didn't make from scratch was the bread. (I took a class on bread making last night so next time there will be some fresh French bread).

 

The preparations were a lot of fun. My wife focused on the deserts, and I focused on the soup, meat, and dressing. We helped each other (she helped me out a lot, I did not help her with the deserts very much). I was planning on doing a chocolate mousse, but scratched the plan due to time. She planned on two lemon tarts, but one of the crusts burnt so she whipped up a Peach Cobbler from scratch without missing a beat. We had lemon tarts and Peach Cobbler for desert. She is amazing.

 

The beef stock was made a few nights before. We made both chicken stock and beef stock. This was my first beef stock and it seemed to turn out well. (I made the beef and she made the chicken stock. It is time to make more beef stock.)

 

The dinner turned out well. We got rave reviews. We decided no more big dinner parties until we finish remodeling the kitchen. It was too hard trying to get everything done and serve it hot. We are getting a double oven and some warming drawers. Also, we need to do more planning ahead of time. Some of the dishes we could have made earlier. Also with the warming drawers, we could possibly eat with our guests instead of eating on the run (at least a few courses).

 

My wife and I have a new hobby.

 

The guests stayed and we talked until late. The talking was the best part. After, the guests left, we loaded up two more loads of dishes and went to bed. I think there are several more loads of dishes to do.

 

Six years ago if you told me that I would love wine and cooking, I'd tell you that you were crazy. I started liking wine about six months ago. I started taking an interest in cooking about a month ago. I started loving good food in 2000 when I went to France for the first time. This is all rather new to me so it is still exciting.

Jan 31 2006, 01:21:13 PM MST Permalink

1 Comment
20060128 Saturday January 28, 2006

It's been a busy week

I was just working on my new Facelets article. I really dig Facelets. It seems to make using JSF a lot simpler.

I did a presentation on Facelets at our Developer Forum this week. Someone else canceled, and I filled in. It was a just-in-time presentation. It was good that we have been doing a lot of cool things with Facelets.

It has been a productive week. Dave and I added a bunch of new features to Presto (our internal CRUD-L based on Hibernate, Spring, JSF, Facelets, etc.) framework. It is really starting to shape up. Currently, you get an CRUD listing with pagination support (managed by Hibernate on the back end not putting the whole list in HttpSession crap), filtering, and sorting. I implemented the relationship filtering today so you can filter on any property of a relationship as well as any property (the initial version uses the Hibernate Criteria API). You get all of this by spending about 15 minutes setting up the listing. Dave and I also worked on creating a master/detail page, just to show that it can be done. Seems there were some problems with the custom navigation handler when running under JetSpeed. Luckily, are next few projects are Portal free, but there is a project in the pipe that will use Presto and Portlet so we will have to fix the navigation handler before then.

I ran into a snag while writing the Facelets article....

There were some minor bugs with the version of facelets that I was attempting to use.

I upgrade, but then it was incompatible with the version of myfaces that I was using. 

I switched to the latest build of facelets and a nightly build of myfaces.

Then I drilled a hole in my head and filled it with broken glass after draining my brain. 

Then things started to work.

I have the first example running. 

I have just one more example to write.

Then the step by step instructions?. 

All is well again, but I lost some time.

Jan 28 2006, 02:24:32 AM MST Permalink

20060117 Tuesday January 17, 2006

Update: Logging into Acegi from a JSF action

Tony Kerz pointed this link out to me. http://jroller.com/page/fairTrade?entry=integrating_acegi_and_jsf_revisited

It is a more detailed (step by step) way to integrate JSF and Acegi.

The above link, makes the rest of this a bit out dated.

Well, I found the code example I was lookign for at: http://w.kazed.net:8080/nowhere/space/java/jsf

 

JSF Integration with Acegi

"Acegi is a security toolkit created to be used with Spring. You could use the basic authentication or login form method of authentication. The standard login form authentication requires you to submit a form with the username and password fields to an Acegi URL. This problem with this is that it doesn't integrate well with JSF. You can also use the authentication machinery of Acegi in your own JSF backing bean and perform the authentication." --koert

Koert provides this code example:

public String loginUser()
{
    String result = null;
    Authentication authReq = new UsernamePasswordAuthenticationToken(userName, password);
    Authentication auth = null;
    try {
        auth = authenticationManager.authenticate(authReq);
    } catch (AuthenticationException e) {
        String exceptionMessage = null;
        if (e instanceof AuthenticationServiceException) {
            exceptionMessage = "AUTHENTICATION_SERVICE_EXCEPTION";
        } if (e instanceof BadCredentialsException) {
            exceptionMessage = "BAD_CREDENTIALS_EXCEPTION";
        } if (e instanceof DisabledException) {
            exceptionMessage = "DISABLED_EXCEPTION";
        } if (e instanceof LockedException) {
            exceptionMessage = "LOCKED_EXCEPTION";
        } if (e instanceof ProxyUntrustedException) {
            exceptionMessage = "PROXY_UNTRUSTED_EXCEPTION";
        }
        // Add msg to JSF context
        FacesMessage msg = new FacesMessage(exceptionMessage);
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        FacesContext.getCurrentInstance().addMessage(null, msg);           
        // Set ACEGI vars
        Map sessionMap = getExternalContext().getSessionMap();
        sessionMap.put(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, e);
    }

if (auth != null) { result = "success"; } else { FacesContext facesContext = FacesContext.getCurrentInstance(); FacesMessage facesMessage = new FacesMessage("You have entered an invalid user name and/or password"); facesContext.addMessage("loginForm", facesMessage); result = "failure"; } return result; }

"The Acegi AuthenticationProvider will store the authentication in a ThreadLocal SecureContext object, so that other services could check if the user is authenticated or not." --koert

Jan 17 2006, 11:55:22 PM MST Permalink

2 Comments

Life log: wine, wallpaper, food, weight loss, exercise

We hired some folks to remove some wallpaper from a house we are selling. They did not work out. They said they were working when they did not work.

The house was suppose to close this Friday. I spent Saturday (about 2 hours), Sunday (about 6 hours), and Monday (about 3 hours) removing wallpaper.

The last time I remember being this sore was after my first wrestling match in the 9th grade.

The ladder was too big to fit in the Garden tub so I had to set it close and brace myself from the ladder to the wall with one arm while I removed wallpaper with the other arm. I woke up on Monday and every muscle in my legs and chest were hurting.

sore. Sore. SORE!

I've lost 15 pounds since the new year. No special diet.... just eating lighter and exercising my... well you know... off. I've been swimming, tread milling and weight lifting. My wife and I just signed up for tennis lessons (with the older kids as well).

Andy B., Jennifer B., my wife and I went out last Saturday night. We went to 58 degrees. Andy and Jennifer know a lot more about wine than most people (a lot more than me). It was fun learning how to prononce wine names that I have only read and wine tasting at 58 degrees. I seem to prefer German and Italian wines (more details on another post).

My wife and I signed up for a 9 week cooking course. It is on Monday nights. I'll let you know how it goes.

 

Jan 17 2006, 11:37:19 PM MST Permalink