Thursday, August 30, 2012

Java Certification Boot Camp - Advanced Class Design - Module 02

This is the second presentation for Java Certification Boot Camp to Java.net and to Scribd for anyone who is interested in the presentation. Module 02 - Advanced Class Design

Java Certification Boot Camp - Java Class Design - Module 01

I uploaded my first presentation for Java Certification Boot Camp to Java.net and to Scribd for anyone who is interested in the presentation. Module 01 - Java Class Design

Wednesday, August 22, 2012

Computing Time in a Method Call

Background

I was trying to do some comparisons on how fast a particular algorithm was calculating Checksum values. In my case, I have Adler32, CRC32, and PureCrc32 (Apache Hadoop) to check. This is my particular case, but in general this question comes up for a number of cases; performance optimization being one of them. Since we are calculating the Checksum on files, the problem is complicated by I/O considerations. File caching, and operating system constraints (resources) being the big ones. So how do most people do it?


The Ugly Truth

The general methodology that most developers use is to wrap the method call of interest with start and end time variables, and calculate the difference. They may repeat the process a couple of times, and average it. If they are fancy, they may randomly execute the method to provide some variance. This pseudo randomness gives the feel of more objective results.

Does it work?

The truth is about precision. This will give you a rough time frame. Perhaps that is all you need. My college mathematics profession, Dr. Alden Monberg, always talked about scale and precision. A tolerance of ± 25mm may work on a ship section weighing a 50 MT., but the same value on a pacemaker, or heart value would be unacceptable. A precision of ± 10nm would work for the heart value, but would be impossible for the ship.

Getting nanometer precision (or nanosecond in our case)

The results from the calculations above will give "thumb in the air" results, but is too imprecise to be useful when you may be calculating 10,000 file, or 10,000,000 files. The overhead of the method call is lost in the I/O, but it still there. The greater the number of files, the more optimized the algorithm, the less time it consumes. We can't control the I/O per se, so lets control our algorithm.

Take a different approach

We still want to do the calculation, but we want to do it on the void update(byte[] b, int off, int len) method which is the root of our algorithm being called. I decided to try to use AOP, and try to wrap the method invocation. I know there are some folks who use Spring, but I do not. I wanted to use an AOP framework directly instead of using it wrapped in Spring. I tried a number of frameworks to see which one I thought would be the least invasive and easiest to use.
After trying all of them, I found that Guice was the easiest to use. I was not able to use it directly out of the box though. The "preferred" method for Guice is to annotate the classes you want to test. In my case, I can not annotate the JDK, nor Hadoop classes. So I had to use another methodology which I will detail.

How do you do it?

I had not originally considered Guice until I found this blog post: Guice Tutorial – part 2: method interception which details performing method interception. This was the jackpot find that got me on track. The example code on that tutorial has the methodology which I used. However, it falls a little short because Guice does not have method matcher which matches on the method name. A little more searching came up with an issue/enhancement posted in Issue tracker for Guice. Issue #164 method name matcher enhancement. The issue is closed as a WONTFIX, but the submitter (Aaron Whiteside) proposed some code to do it. I modified the code slightly, but it was a near perfect fit. Google Groups has an explanation why Bob Lee thinks it is a bad idea: Guice/AOP - intercepting a method thanks to its name. I disagree, but that is his choice. The code Aaron mostly works, and my code below does work. So be it. OK, so we now have most of the pieces in place. The cool thing about this method is that we can use it anywhere. I am going to use it on a JUnit test like the tutorial in my code, but it is very general. So here is what I needed:
  1. A MethodInterceptor implementation
  2. A Matcher implementation
  3. An AbstractModule implementation
  4. A JUnit test

Code

TimingInterceptor.java


MethodCalledMatcher.java


AbstractModuleImpl.java


ChecksumTest.java


Results

However one test does not tell the whole story. When I actually ran this as a more general performance calculation. The results were on curves. On small files like the 10MB one in my test, the Adler32 was fastest. The PureCrc32 code performed the best as the file sizes got larger. Please don't accept the output here as a performance test without considering other factors. It is cool though that we got more precise results rather than brute force attempting it.

Friday, August 17, 2012

Oracle Certified Professional Java SE 7 Programmer Boot Camp

We had our first meeting last night of the boot camp for the Greenville Java Users Group (GreenJUG) for Oracle Certified Professional Java SE 7 Programmer certification. This is based on the work we have done for the SCJP for Java SE 6 which was very successful. We have run three previous boot camps with great success. Although a number of people attend the boot camp, not very many take the exams. We do have a great success rate for those who attempt it: 11/11 (100%).  We hope to be able to continue the same streak going forward.

Last night we covered Chapter 10 - Development from the SCJP Sun Certified Programmer for Java 6 Exam 310-065 book. I have not found any published books on SE 7 certification so we are using this book in the interim. Additionally, we are adding material to cover the gaps including material from Preparation for Java Programmer Language Certification.

Over the next few weeks I will publish our code to the Java Boot Camp project on Java.net. I will also publish my slides with a CC license. All coding modules going forward will be done using Apache Maven and are developed on NetBeans. Current Java code in the bootcamp was developed with NetBeans, but are not Apache Maven projects.

Exam Tip

Here are some quick rules for code questions on the exam.
  • Does the code compile?
  • Does the code run?
  • What is the output?

If you can answer these questions before looking at the answers, you have the code portion of the exam beat! Here is an example from last night. Please note that it is obfuscated for a reason, and does not represent good coding practices. So when you examine the code, see if you can answer the questions above. This will likely be harder than anything you can expect on an exam.

Wednesday, August 15, 2012

JSF 2.1 Tip of the Day: PrimeFaces Dialog <p:dialog/>

We have been doing a lot of work lately with PrimeFaces. A common set of questions comes up about displaying <p:dialog/> boxes on a page.
  1. How do I update elements on the page outside of the dialog?
  2. How do I include information from external pages?
  3. Can I nest forms and dialogs?
The last one is the easiest to answer: NO. You may get away with it in some cases, but the HTML specification does not allow <form> tags to be nested inside other forms. So your dialog can contain a form, but should be outside of the form that opens it.

Some components do not need to live inside a <form> to work. For example <h:button /> tags do not need to be inside a <form>. You can update <h:outputText /> elements outside a <form> with AJAX.

The second question is also easy. Using <ui:include /> you may add other JSF content to your dialog. You could also use a <ui:decorate />, <ui:component />, <ui:define />, or <ui:composition />. I personally like <ui:include />

The first question is best answered with some code. I have some interesting tidbits of code in here including using String concatenation in Expression Language (EL). The key to updating elements on the page comes from the update attribute on the <p:commandButton /> elements.

The project and code I have included below were developed using NetBeans 7.2 IDE on GlassFish 3.1.2.2, and PrimeFaces 3.3.1.

The code can be downloaded here: primefaces-dialog-examples.zip


IndexBean.java


Wednesday, August 01, 2012

What Makes Bad Programmers Different?

I just re-read the article by Andrew Binstock from InformationWeek by the same title. I found myself reading the article and nodding my head. Andrew's article was written as if he had read my mind on the subject.
Bad programmers are often comfortable within the constraints of their narrow skill sets.
This quote is so true. I often see programmers who started their careers off in COBOL, or FORTRAN, and apply the same skills to a language like Java, or Ruby. The top down approach to programming is evident in everything they do. OO concepts are limited to a class with thousands of lines of code often codified in one giant method.
They have very superficial knowledge of their problem domain, and their tools.
A great example is using a great IDE like NetBeans along with JPA. That is the project they are working on has JPA. They can not get the ORM concept down, and instead write SQL to get what they from the database. Finally, they use their native queries inside JPA, and struggle to map the results to objects. Rather than take advantage of the IDE to generate the code for them, or learn a little more about JPA, they solve the problem with what they "know" and complain that JPA, or the tooling is bad.
... they view the quest for alternative ways of doing things as the kind of folderol that's more of a personal programming indulgence than a productive activity.
The corollary to this is that they will spend hours trying to undermine the new technology to find new ways of doing the same thing with which they are familiar. It is the snake swallowing its own tail.
What they don't appreciate, though, is just how much work and effort they shift to the rest of the team. And if this information is communicated to them, they're initially surprised, then incredulous, but ultimately unfazed.
Been there done that... and this is so true. I am usually the bad guy. Imagine that.
Personally, I believe that the only way to sufficiently communicate their shortcomings to them and make their cost clear to management is through the diligent use of code reviews.
This is true, but I think it is important to stress that a code review should be done on all code which is part of a multi-developer, and multinational project. However, I think that doing the code review in a blind code review with their peers will stress the point to them initially that the quality of their work is not up to par. If the blind review fails, then a public review where they defend their design decisions should be done. This gives them a chance to reform, and puts them on notice.

Andrew seems to believe from his article that they are already long gone, and should be ultimately fired. I want to believe that people can make changes to become productive. It is fundamental to me to believe in people. However, in practice it has ultimately resulted in the bad programmer being fired, or moving on to another company to continue their damaging activities.

JSF Tip of the Day: Adding Javascript to a Custom Component

I was looking through the JSF API and Implementation code, and found a gem that really demonstrates how to add a Javascript framework, or custom Javascript code to your custom JSF component.

It requires more than writing the code out to the page using a ResponseWriter. For example, you must determine if the script is already on the page.

The code I found was part of the com.sun.faces.renderkit.RenderKitUtils in a method called renderJsfJs. This is part of the JSF RI Implementation (jsf-impl). It is dual licensed with GPLv2, or CDDL so please check the license out from the original source.

Here is the abbreviated code for the method. It is well done and demonstrates not only how to add the Javascript, but architecturally how to check if it is already rendered, and installed. It also demonstrates how to use a ResourceHandler and Resource. This is by no means the only way, but it does provide a good example.



 public static void renderJsfJs(FacesContext context) throws IOException {


        if (hasScriptBeenRendered(context)) {
            // Already included, return
            return;
        }

        final String name = "jsf.js";
        final String library = "javax.faces";

        if (hasResourceBeenInstalled(context, name, library)) {
            setScriptAsRendered(context);
            return;
        }
        // Since we've now determined that it's not in the page, we need to add it.

        ResourceHandler handler = context.getApplication().getResourceHandler();
        Resource resource = handler.createResource(name, library);
        ResponseWriter writer = context.getResponseWriter();
        writer.write('\n');
        writer.startElement("script", null);
        writer.writeAttribute("type", "text/javascript", null);
        writer.writeAttribute("src", ((resource != null) ? resource.getRequestPath() : ""), null);
        writer.endElement("script");
        writer.append('\r');
        writer.append('\n');

        // Set the context to record script as included
        setScriptAsRendered(context);
    }

The code to determine if the code is installed is just as important as rendering it.

public static boolean hasResourceBeenInstalled(FacesContext ctx,
                                                   String name,
                                                   String library) {

        UIViewRoot viewRoot = ctx.getViewRoot();
        ListIterator iter = (viewRoot.getComponentResources(ctx, "head")).listIterator();
        while (iter.hasNext()) {
            UIComponent resource = (UIComponent)iter.next();
            String rname = (String)resource.getAttributes().get("name");
            String rlibrary = (String)resource.getAttributes().get("library");
            if (name.equals(rname) && library.equals(rlibrary)) {
                // Set the context to record script as included
                return true;
            }
        }
        iter = (viewRoot.getComponentResources(ctx, "body")).listIterator();
        while (iter.hasNext()) {
            UIComponent resource = (UIComponent)iter.next();
            String rname = (String)resource.getAttributes().get("name");
            String rlibrary = (String)resource.getAttributes().get("library");
            if (name.equals(rname) && library.equals(rlibrary)) {
                // Set the context to record script as included
                return true;
            }
        }
        iter = (viewRoot.getComponentResources(ctx, "form")).listIterator();
        while (iter.hasNext()) {
            UIComponent resource = (UIComponent)iter.next();
            String rname = (String)resource.getAttributes().get("name");
            String rlibrary = (String)resource.getAttributes().get("library");
            if (name.equals(rname) && library.equals(rlibrary)) {
                // Set the context to record script as included
                return true;
            }
        }

        return false;

    }

Popular Posts