Tuesday, 31 December 2013

In Our Day...

Introduction


Another year gone! When I look at young people, I do feel old sometimes.

A colleague at work is trying to get rid of some old books. One such is about "The Internet", written in 1996.

Some of the things in there, boggle the mind of people who have not lived in that day and age.

Here're some thoughts on "When I was young...", "Back in our day...", things that you young whippersnappers have no clue about.

Let me know if you have more.

The Telephone



Back in our day, if we wanted to receive telephone calls, we had to stay at home! Because that's where the phone was. You couldn't take it with you, as it was attached to a telephonecord. That's right, your conversation went over a wire. And that is all the phone could do, make phone calls and receive phone calls, nothing else. You couldn't even send short text messages with it! As a matter of fact, you had to remember somebodies phonenumber or have it written down somewhere! The telephone was split into two parts, the part you could listen and talk to, and which was connected to the second part that you used to dial numbers. It had this circle with holes in it near the rim. Every hole was a number. If you wanted to dial a telephone number, you'd put your finger in the correct (first) hole, and turn this circle round until you couldn't anymore. Then you let go. The circle would turn back, and you could repeat this with the next number.

Ofcourse, we did have something called a "phonebooth", small compartments of glass and metal, that were put out in the street. Just big enough for one man to stand in, and it had a phone, that you could put quarters (money) in so you could call someone.

Some rich folk had a "car"phone (a mobile phone), which basically was shaped like a brick, with the same weight, and attached to a freakin' suitcase to carry the batteries and assorted technical crap around in.

Back in our day...


Back in our day, when you were lost, you were basically screwed. You could either ask some stranger or read the signs. If neither were here, and you were in the middle of ff-ing nowhere, you were simply out of luck. We got lost a lot, but, if it is any consolation, we always found the way again. Sometimes you'd bring a map along if you'd never been to the place before. It's kind of like a navigation system, only it's printed on paper, doesn't talk, is non-interactive, and doesn't automatically tell you where you are.

Back in our day, when we went to the supermarket, we'd have to pay for our groceries with cold, hard cash! At that time we had our own Dutch money, the Guilder (Gulden). None of this Euro stuff.

Back in our day, if we wanted to use the Internet, we'd use the telephonecord with a device called a modem. It would translate internet by making beeping sounds and sending that over the phoneline, to another computer that was listening to the beeping sounds to understand what you wanted.

Back in our day, we could write something called a letter on paper by hand, put it in an envelope, seal it and put a postage stamp on the envelope. We'd bring that letter to a post office and they had mailmen that would deliver these letters. It took at least two/three days for a letter to arrive. That was called mail.

Back in our day, if we wanted something calculated, we'd have to get a pen and paper and do it ourselves. Sure, shopkeepers had big bulky cash registers, but these were impractical for home use. My mom always told the story, that when she had her first calculator, she'd use it, and then, recalculate everything by hand, just to make sure.

Back in our day, when we wanted to change the channel on the television, we'd have to get up, off the couch, walk to television set, press the button on the television set for the other channel, and then walk back and sit down again.

Back in our day, when I went on vacation with my parents, my mom carried a special wallet with her. It had four (color-coded!) compartments that contained money of the different European countries we would be passing through/staying in. She'd order this money before the vacation at the local bank/exchange. If you were abroad, and were in need of money, you could use something called Travellers Cheques, basically a piece of paper you took to a foreign bank and you scribbled on it how much you wanted.

Back in our day, our car didn't have seatbelts, nor airbags or deformable zones. The two people in front got seatbelts, and that was it.

Back in our day, if you showed us a cassette tape and a pencil, we knew exactly what to do. Kids nowadays would have a big question mark on their face.

Back in our day, we could hear when the batteries of our cassette tape player, called a "Walkman", were running low.

Back in our day, we could record "software" from a radio station onto cassette tape and load it up onto our computer. Because we didn't have Internet.

Back in our day, if we wanted to see the pictures we took with our cameras, we'd have to bring something called "a negative" to a "photo development shop" and he'd have the pictures ready "on paper" the next week. And if some of the pictures were crap, that's too bad, because we had to pay for those too!

Quote


For All Those Born in the 70's and 80's!

We are the last generation that learned to play in the street, we are the first who've played video games, see cartoons in color and went to amusement parks. We were the last to record songs of the radio on cassettes and we are the pioneers of walk-mans and chat-rooms... We learned how to program the VCR before anyone else, play with the Atari, Super... Nintendo and believed that the Internet would be a free world all on a 56kbit modem. Traveled in cars without seat belts or air-bags & lived without cell phones. Rode our bicycles down the road without brakes. We never had phones but still kept in touch. We did not have Play stations, 99 television stations, flat screens, surround sound, mp3s IPods computers and broadband...

but nevertheless we had a GREAT Time

Wednesday, 25 December 2013

IoT - Internet of Things

A nice post on what the Internet of Things is. (Don't ask me, it's relatively new to me).

How I explained the IoT to my parents.

Back in the old days, when I was still working at a big Telecom company, we'd often heard something like it. It mentioned querying your Refridgerator, to see if you had enough ingredients for making Chicken Cacciatore, or if you had to go shopping. This is apparently the same thing in a new name.

Sunday, 8 December 2013

JSR 305: Annotations for Software Defect Detection

The NullPointerException is the most prevalent exception thrown in Java programs known to man. Dealing with it has always caused a great deal of Null checks in my (and other peoples) code.

At work we've recently started using the special annotations from JSR 305[1].

There are basically two. Nullable to indicate that a result of variable can be Null, and Nonnull to indicate that a result or variable will never be null.

The JSR 305 annotations are primarily intended for compilers or other tools that read source code. However, they are usually retained in the byte code for the benefit of static analysis tools such as FindBugs that inspect byte code rather than source.

An added benefit is that it forces me to think about what a method should return.

Eclipse, our work environment, has its own versions of those annotations, which we do not use.
  • org.eclipse.jdt.annotation.Nullable
  • org.eclipse.jdt.annotation.NonNull
  • org.eclipse.jdt.annotation.NonNullByDefault

The originals from JSR 305[1] are:
  • javax.annotation.Nullable
  • javax.annotation.Nonnull
  • javax.annotation.ParametersAreNonnullByDefault

In order to get the proper annotations, we do have to include a jar file. We use "jsr305-2.0.1.jar".

At the start of using these annotations, I've turned "Errors" off, regarding the Null annotations, as I was getting far too many errors.

The Executive Committee voted to list this JSR as dormant in May 2012. But the implementation of JSR 305 [1] seems to work in several IDEs.

Eclipse problems and workarounds

The tooling in Eclipse is of course not perfect in detecting where a Null is a possible problem. There are ways to help Eclipse make the right decision. In the examples below, the part of the code that Eclipse will indicate as being faulty is red underlined.
  1. The following code shows up Faulty in Eclipse. Eclipse/FindBugs cannot determine that the check for null negates the second possible NullPointer.
    // Potential null pointer access: The method getItem() may return null
    if (order.getItem() == null
    {
        logger.debug("order has no item.");
        continue;
    }
    int price = compute(order.getItem());
    The workaround is as easy as making a temporary local variable.
    // no problem!
    Item item = order.getItem();
    if (item == null
    {
        logger.debug("order has no more items.");
        continue;
    }
    int price = compute(item);
  2. Warning in the second line. Eclipse is not clever enough to figure out that assertNotNull will take care of it. Eclipse is smart, but not psychic.
    assertNotNull(order.getItem());
    assertNotNull(order.getItem().getDescription());
    Replace it with another local variable and put some supressors on it.
    assertNotNull(order.getItem());
    @SuppressWarnings("null")
    @Nonnull
    Item item = order.getItem();
    assertNotNull(item.getDescription());
  3. NullChecks are not being used in the original Java API, causing potential warnings. In the example, without the SuppressWarnings on the method, the last return would be underlined.
    @SuppressWarnings("null")
    public @Nonnull Set<Item> getItems() 
    {
        if (items == null
        {
            return Collections.emptySet();
        }
        return Collections.unmodifiableSet(items);
    }
  4. I've encountered an issue with Enums. Why does this happen? I have no clue.
       boolean result = hasProperty(name, StateEnum.MANDATORY);
       return result;
    }

    private boolean hasProperty(@Nullable String name, @Nonnull StateEnum state)
    {
       ....
    I can solve it in the obvious way, but am unable to find the cause of the problem.
       @SuppressWarnings("null")
       boolean result = hasProperty(name, StateEnum.MANDATORY);
       return result;
    }

    private boolean hasProperty(@Nullable String name, @Nonnull StateEnum state)
    {
       ....
  5. If the Null constraint annotations are not used in the Interface (specifically method parameters... it seems method return values don't matter), you are not allowed to add them in your implementation. You will receive the error message from eclipse.
    Multiple markers at this line
    - Illegal redefinition of parameter myParam, inherited method from SomeInterface does not constrain this parameter
    - implements mrbear.some.SomeInterfaceImpl.myMethod
  6. You are better off not using @Nonnull at the Hibernate Entity Level, as that is going to cause problems in some cases. Notable when using "Examples" for searching.

Note: Of course, it is a code smell to have to change your production code, to help Eclipse tooling deal with Null. This is probably the main reason, why it doesn't have the expected uptake in my company.

Mushroom cloud


Changing your existing code base to make use of this new check, is quite a job. If you start at a specific point (the point, to be more specific, where you were changing your code initially), it tends to mushroom cloud outwards. Somewhere along the line, you have to decide how far you wish to take this.

It would have been a great deal simpler, to have added this functionality straight from the beginning. Alas, hindsight is always 20-20.

Frameworks


I've not discovered any frameworks that inherently are using the same JSR305, except for one. Google Guava.

Generics


Recently had the issue that I had a List, of which I knew that each member of that List was not NULL. But I had no way of annotating this with @Nonnull.

It appears it is possible to (among other things) annotate generics once JSR 308[3] is added to Java. It is scheduled for Java 8 for now.[4]

The Checker Framework[2] makes it possible right now, apparently.

The syntax would look something like this:
protected @Nonnull List<@Nonnull String> getNames() {

Updated: 10/12/2013 added chapter on Generics and a problem-case I encountered.

Updated: 20/02/2014 added a critical note at the end of the chapter of "Eclipse problems and workarounds".

References

[1] JSR 305: Annotations for Software Defect Detection
http://jcp.org/en/jsr/detail?id=305
Avoiding “!= null” statements in Java?
http://stackoverflow.com/questions/271526/avoiding-null-statements-in-java
The Open Road: javax.annotation.
https://today.java.net/pub/a/today/2008/09/11/jsr-305-annotations.html
[2] Checker Framework
http://types.cs.washington.edu/checker-framework/
[3] JSR 308: Annotations on Java Types
http://jcp.org/en/jsr/detail?id=308
[4] JSR 337: JavaTM SE 8 Release Contents
http://jcp.org/en/jsr/detail?id=337

Sunday, 1 December 2013

Oracle Timestamp vs. Date

Recently have been hitting a brick wall due to a bug at work.

Query doesn't return any results if the date is "2009-06-01 00:00:00:01". But for the date "2009-06-01 00:00:00:00" it works fine.

The table is as follows:

And contains:
ID CODE STARTDATE ENDDATE
103581900/01/01 00:00:00:000000(null)

/* Formatted on 28/11/2013 17:02:58 (QP5 v5.227.12220.39754) */
SELECT *
FROM MUNICIPAL municipal1_  
WHERE municipal1_.code='0358'
AND (TO_TIMESTAMP('2009/06/01:00:00:01:01''yyyy/mm/dd:hh24:mi:ss:FF2'BETWEEN municipal1_.startdate
AND NVL (municipal1_.enddate - 1, TO_TIMESTAMP('2009/06/01:00:00:01:01''yyyy/mm/dd:hh24:mi:ss:FF2')))
The query above returns no rows. Why?

Some notes:
  1. the (null) for enddate means the timeperiod reaches into the future
  2. the sql function BETWEEN[5] checks to see if a value is within a certain range. The boundaries are inclusive.
  3. The enddate is a timestamp(6)
  4. enddate - 1 is no longer a timestamp, but a common date. An implicit datatype conversion takes place.[4]
  5. date doesn't store anything smaller than seconds [2]
  6. we lose the milliseconds
  7. NVL tries, if the first argument is null, to cast the second argument to the same type as the first argument (a date) [3]
  8. even though enddate is null, the data conversion still takes place
  9. ergo, the timestamp used now falls outside the range, and no results are returned.

Solution

There is one good solution to this. Don't use BETWEEN with timestamps if the range is exclusive the enddate. Use greater than/equals (>=) and lesser than (<) instead.

If you do wish to change a TIMESTAMP, use INTERVAL instead of arithmetic. [4]

/* Formatted on 28/11/2013 17:02:58 (QP5 v5.227.12220.39754) */
SELECT *
FROM MUNICIPAL municipal1_  
WHERE municipal1_.code='0358'
AND (TO_TIMESTAMP('2009/06/01:00:00:01:01''yyyy/mm/dd:hh24:mi:ss:FF2') >= municipal1_.startdate
AND TO_TIMESTAMP('2009/06/01:00:00:01:01''yyyy/mm/dd:hh24:mi:ss:FF2') < nvl(municipal1_.enddate, 
                            TO_TIMESTAMP('2009/06/01:00:00:01:01''yyyy/mm/dd:hh24:mi:ss:FF2')))

Conclusion


Do NOT use Arithmetic with Timestamps! You will get an automatic conversion to datatype Date and lose millisecond precision!

It is quite ugly to substract a day from a DATE, just so that you could use BETWEEN and not worry about the last boundary being included.

I guess it is my own fault for appropriating a bit of SQL code that was originally designed for DATES instead.

References

[1] Timestamp
http://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html
[2] PL/SQL Data Type
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/datatypes.htm#CIHBCJEG
[3] NVL
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions105.htm
[4] Math with Timestamp
https://blogs.oracle.com/knutvatsendvik/entry/math_with_timestamp
[5] BETWEEN
http://docs.oracle.com/cd/B28359_01/server.111/b28286/conditions011.htm#SQLRF52147