Java Deep

Pure Java, what else

Monthly Archives: August 2013

How to instantiate utility class

In a previous blog we had a look how to protect utility classes to be instantiated. We finally got to this class:

public final class YouJustCanNotInstantiate {
    private YouJustCanNotInstantiate() {
        throw new RuntimeException("You just can not instantiate this class.");
    }
}

Seems to be a tough guy. Still there are ways to get an instance of this class:

Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
YouJustCanNotInstantiate s1 = (YouJustCanNotInstantiate) unsafe.allocateInstance(YouJustCanNotInstantiate.class);

It works fine on ORACLE JVM, but be aware that this is not standard and may not work on other JVMs. Actually there is no guaranteed Java way that always works. However there is a project called Objenesis that does the trick and works on Android, Rockit, Gcj and Perc JVM in addition to the “standard” ORACLE JVM. Have a look at it! It is an interesting project at least to learn from.

WARNING: if a class was not meant to be instantiated and was protected from that the way above, then you will deserve what you get following this pattern. You have been warned.

Credit: Yuriy Fuksenko, and Norbert Madarász for pointing out these solutions on LinkedIn

How to instantiate the system class

This question is raised many times by novices. I have seen it many times on different forums and yesterday it came in front of me on LinkedIn. There are numerous answers to this questions, and we can learn a bit from the different answers.

The question itself is triggered by the fact that the System class is a utility class that has only static fields and methods and is not meant to be instantiated. Because it is not meant to be instantiated it has an explicit private, argument-less constructor and there is no factory method inside the class calling this constructor. Because of this you just can not write

System system = new System();

without getting compilation error.

Answer#1, use reflection

Constructor<System> constructor = System.class.getDeclaredConstructor(null);
constructor.setAccessible(true);
System system = (System) constructor.newInstance(null);

This is a very straightforward answer and you can get a kick start and motivation to learn reflection. On the other hand it does not give much to your java knowledge development in addition to waking your curiosity.

People wanting to educate usually give another answer

Answer#2 You Shall Not

Why do you want to instantiate the System class? There is no use of it and it was designed not to be instantiated. It was designed not to be instantiated and engineers at SUN did all measures to prevent you to do that.

Really? All measures?

Well, not really. All measures that are on economic level. There can be more things to do. And here comes the next topic in the chain of thoughts:

How to protect utility classes

The System class is protected the way it is and we will return at the end of this article why it is not protected more. If there are more ways to protect a utility class to be instantiated is another question. The possibilities are the following:

  1. Document the class and clearly express that the user of the class is not expected to instantiate the class. This helps a lot, but the user may still accidentally instantiate the class not fully understanding the documentation and the intended use of the class. This happens quite often, therefore using more technology to prevent this is easy to justify.
  2. Have an argument less private constructor. This will prevent the casual user to instantiate the class. Even if the user was sloppy or hard understanding the documentation language he or she will face the fact that the compiler will not compile the code that contains new UtilityClass. On the other hand the users still can use reflection. Do we care? For now, yes.
  3. Do not call this private constructor from you static methods. Obviously this would just ruin all your efforts you invested making the constructor private.
  4. Make the class final. Why does it help? It will not prevent the direct user of the class to use reflection but will prevent anyone to create a library that extends the utility class and makes it instantiable using special tricks. The next user using the extending class may fall into a trap without wrong intention getting an instance of your class through the extended class.
  5. To prevent reflection initiating the class throw a run-time exception from the constructor of the class. Even if you catch this exception in the code that uses reflection, you can not get access to the created objects being half way initialized, since the assignment to a variable or any use of the object the operator new returns would execute after the constructor returns. And the constructor just does not return.

These are the tools to make a utility class safe. There may be some more tricks that one can apply, but I strongly believe that this is already more than enough. SUN engineers made the class final and the constructor private. They believed that anything else is overkill, and I tend to agree with them.

Bonus question for the not faint of hearts:

How can you still get access to an instance of a class that was created using all the above (1-5) preventive measures? I will tell you on this blog in the next article, apprx in a week.

We do not use UML, we are agile

I have heard many times the sentence(s) in the title and I can not argue with that. These are two independent statements, and it is out of my scope to disagree. Your group does not use UML. Fact. You are working agile: again: fact. What to argue about? The problem usually is the implied “because” between the two statements. If you say “We do not use uml BECAUSE we are agile.” then there is a problem. Not a life threatening issue, but still something to think about again and perhaps get things better. After all agile is all about constant improvement.

UML is a tool that can be used different level, different purposes and there may be some place to use it even when you are working agile. There are several reasons why not to use and also why to use UML. My experience for the reasoning why not to use uml lists the same reasons as the article referenced above. You can see yourself that these argument are also very lame. All of them can be summarized as: “I do not know it, therefore I do not use it.” All other words are just psychological self-confirmation to push aside the bad feeling for the poor decision not to learn the right tool. Learning new topics is hard and people are inherently lazy to learn new things. Very true. But this is what makes us, experts having good job. Are you an expert?

This is even worse when people learn new things (this time this is about UML) but learn it half-way and do not take the pain to use it properly. Here I list a few examples of extremely bad UML use that you have to avoid by all cost. I personally have seen examples of each.

Intimidate customer BA using UML

Once I met a software company who created vast amount of UML diagrams and presented the architecture to the technical people of the customer in this form. This alone was not a problem. The issue with this was that the technical people were aware of UML as such but were now knowledgeable. They just could not read UML and were afraid to admit it. They were afraid to ask, complain about flaws in the design and the architecture documents went approved without significant feedback. This made the architect’s life easier for the time, but caused significant headache for the company on the long run. Even though the architecture design is the responsibility of the vendor it is not without reason they are to be approved by the customer. After all: this is a cake baked by the vendor but is eaten by the customer.

Creating UML for the obvious

This was very similar to the first one: UML was used to impress the customer. There was an UML model created for each and every class, even the simple utility classes, component, communication models and everything. Then the UML tool created hundreds of pages, redundant PDF documents with all the diagrams that were imaginable generated from the model. Fortunately the PDF was never printed killing trees.

Diagrams UML like

I have seen many times diagrams that looked like UML diagrams at the first view. On the second glance you spot some strange notations and then you realize that different diagram elements are mixed in a single diagram, and they are used in totally wrong ways. I have seen many times class diagram elements used to depict relations between modules. What seemed to be inheritance by the notation turned to be a communication from one component denoted as a class to the other by the intention of the designer. The complaint was: “our drawing tool does not support component diagrams”. OMG! Use a different tool then! Pencil and paper version 1.0 ?

We know UML

“We know UML.” The problem was that the members of the team knew UML differently. They sketched something on the white board discussing the architecture but instead of doing the effective work, soon they fiercely argued on a specific line if that is composition, aggregation or a simple relation. C’mon: focus on the real issue.

Conclusion

I do not tell you have to use UML. I do recommend though. Learn it a bit. But do not learn it to the extreme. Learn it to use it and not for knowing all the bits of it. (This is true for almost anything.) Do not be shy admitting if you do not understand something. Ask for clarification. If you lack UML knowledge and you are the customer, ask the vendor to setup a workshop for you and explain the notation. If they say: “hey, this is UML” you can bravely say: “Hey, I am the customer.”

Do not generate UML documentation, huge, many page PDF files. Whenever you create a document ask yourself the question: who will read it and what is the purpose to read it? If you are the customer, be strict and limit the size of the documentation you are willing to accept and read.

It may happen you use UML “like” drawings, but do not be happy getting drowned into that mud. Learn and strive for the correct use. Other professionals will understand your diagrams if it means what it is meant to mean.

And last, but not least: use UML as a tool and focus on the work to be done. Use UML and be agile.

Should I write a new unit test?

Recently in a project a method was altered from private to be public. The functionality that was used only inside the class was needed from outside and the without any other change the method got into the interface the class implemented and the keyword private was changed to public. To do that this was a task. We estimated the effort. How much was it? 2 hours. Although the 2-hour time is not a huge one in a project, project management was not happy with that and practicing control they asked, what does it take so long to replace private to public in a Java source file. The discussion was something like this:

  • Why is it two hours to replace the word private to public?
  • We also have to write unit test for the method.
  • But there are already unit tests for the class, not?
  • Yes, but we do not test private methods in unit tests and thus there are no unit tests testing this method.
  • I assume that the coverage of the unit tests is 100%
  • Yes it is.
  • Then this method is also covered by unit tests 100%. Right?
  • Well, yes… as long as code coverage. But functional coverage…

This is a situation where functional coverage and code coverage has significant differences. When we create unit tests we are interested in functional coverage. If the methods of a class can perform all the functions they have to, and this is tested by the unit tests, then the class has 100% functional coverage in unit tests. If running unit tests executes each and every line at least once, and all possible branches of code execution is executed both way (part after the then and also after the else) then the code coverage is 100%.

We usually measure the code coverage for the practical reason that we can measure that cheaply. Functional coverage can not be measured so easily. We need a formal definition of the functions and some test versus functionality matching and coverage estimation that is hard if not impossible to automate. On the other hand code coverage is a good measure and we can get very far measuring that even though we know it is not perfect.

There are four different cases:

cF
code coverage < 100%
functional coverage 100%
CF
code coverage 100%
functional coverage 100%
Cf
code coverage 100%
functional coverage < 100%
cf
code coverage < 100%
functional coverage < 100%

CF is the ideal case, when both functional and code coverage is 100%. We may never reach that state, but that is what we aim for. The problem is you can never prove or know how close you got there.

cf is the usual case when we do not have enough unit tests and thus neither code nor functional coverage is 100%.

Cf is also very frequent. This is the case in most projects. The code is covered by unit tests, still there can be some cases not tested. If you look at the simple sample method:

double div(double a, double b){ return a/b; }

A simple test dividing 2.0 by 1.0 will result 100% code coverage, still we did not test the case when b is zero.

The tricky combination is cF. Juniors usually say that this is not possible. They are right in the sense that there is very limited practical value in this case. It happens rarely. But sometimes it does and it means that there is dead code. If all the functions can be executed without ever touching a certain line, than that line is superfluous.

So what does it have to do with the situation making a private method public? The code did not change thus it will not change C to c in code coverage, but functionality changed implicitly.

The functionality of a private method is limited by the use of the method inside the class. The contract between the private method and their clients is very informal, and since they are tightly coupled there is no too much room for worries caring about special argument values. If the method in the example above is called ensuring in the caller that b is never zero then this is fine. There is no JavaDoc, there is no checking. If the method becomes public then the contract changes. The general part does not change, but the fine prints do.

You have to declare that argument b should never be zero, and you have to define what happens if some client happens to call it that way. This is a new functionality that just emerged without any new code just making the method public. New functionality deserves new unit tests.

Summary

If you change a private method to be public and you promote it to be part of the interface the class implements do not assume that this is only a keyword change. Create the appropriate tests that double check the functionality.