Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Thursday, 23 May 2013

Calling methods from Constructors, a definitive explanation by Dr Heinz M. Kabutz

I am a huge fan of Dr. Kabutz and have been following his Java Specialists newsletter for many years.

In the latest issue he explains and demonstrates the pitfalls of calling methods from within constructors.

Now I have always been a proponent of "don't put logic other than simple initialisation in constructors", in fact I have always introduced this as a "Golden Rule" when helping other developers.
I knew about most of the things that Dr. Kabutz explains here but never really found the time to really get into it and write things down. Now that Dr. Kabutz has done so I don't need to.

The majority of my work involves JSF/CDI/EJB/JPA. I still see many code examples which places significant code in the constructors of CDI Beans even from sources that claim to know better.
If you are in the habit of doing so you really need to read the newsletter and get into the habit of using @PostConstruct annotations in your code as well as adding lazy loading/evaluation to setter/getter methods.

Tuesday, 23 April 2013

A tale of detached Entities, identity and equals with JPA

I was asked to do update an old project of mine in order to accommodate some new requirements for a web application which manages manufacturing cycle times. Data about the resulting cycles is stored in a Database for analysis through another system.

The existing project was specifically designed with Cathode Dip Painting plants in mind and wasn't suitable for generic assembly line monitoring. In particular a requirement that the current cycle and production lot state be persisted through Web Application downtimes/restarts was new.

A majority of the new requirements were cosmetic and easily added without having to reach into the plumbing of the asynchronous progress state monitoring.

Yesterday however I added the cycle start persistence and suddenly everything broke. Granted I had things like telephone calls breaking my concentration but still I was flummoxed about why the Production Lot data was not being processed as expected.

Basically a Production Lot has a maxCycles and a currentCycle property.
When the currrent cycle completes, the currentCycle property is decremented. If this value is < 1, the current production lot is deleted and the next one is retrieved via JPA. The next cycle is then started.

So, being the optimist that I was and between phone calls I simply added a merge(ProductionLot entity).
This one line of code broke the app such that Production Lots were not being processed correctly.

After 2 hours bashing my head against the telephone I went home hoping that today would bring a fresh head and ideas to the problem.

This morning all sorts of light bulbs were lit up. In what way can an entity merge cause a problem like this... Consult the literature... lo and behold

The merge method of an EntityManager is used when you want to either update an Entity persistently OR when you want to attach the Entity to the current Persistent Context. It will also create a new Entity for the current Persistent Context if one does not exist (essentially equivalent to a persist method call). It also returns the Entity you merged. But, and this is what was causing me the problems, it returns the attached version of the entity and not the original.

Somewhere in my code I was checking for equality between the current Production Lot and one returned by the ProductionLot Stateless Session EJB. This worked before because the Production Lot only changed when the current one was exhausted and new one returned. In merging the current Production Lot I broke the semantics because the equals semantic was no longer strong enough.

So currentProductionLot != nextProductionLot && currentProductionLot.equals(nextProductionLot) need to be added.

This is something that is normally bread and butter to me but I still made the elemental mistake. Why?

Was it the telephone calls or the desire to leave before 19:00? No, actually it was a lack of preparation made when changing the actual semantics of the system.

On the face of things: never take for granted that a one line change will not profoundly change things. They will and the possibility should always be taken into consideration when making them.

Thursday, 7 February 2013

Bad (programming) habits instilled in me

What can happen when enforced terrible coding style practices become ingrained!


A company I used to work for had a "Style Sergeant" [ref: The Code Warriors] of the worst kind.
This person was allowed to enforce coding style rules on the rest of us as long as they could justify them.
In this case a stye rule for method local variable names was introduced on the premise that it shortened build times considerably.

The rule was simple, the names of the variables had to be as short as possible to remain unique with the accepted case being an abbreviation of what the variable was.

Now I am not going to get into the obvious fallacies here.
Build times went up because the code base was growing anyway.
Code readability went down the toilet. Mr Code Sergeant spent too much time refactoring existing code and committing it rendering existing code unreadable too.
Number of bugs introduced in new or changed code went up (it was expected that it would take time to get used to the new naming convention)

I was reviewing and refactoring some code I wrote a while back and was horrified that it took me so long to unravel what was going on. There was also a bug in the code that had the potential to cause a mountain of database orphans that was really hard to spot which was caused by the local names I was in the habit of using back then.

Here is the original code after refactoring for Java 7.

public PlantProperties replicate( PlantProperties toReplicate ) {
        Replicator<PlantProperties> rp = new Replicator<>();
        PlantProperties cpp = rp.replicate(toReplicate);
        PlantTypes pt = toReplicate.getTypeID();
        Replicator<PlantTypes> rpt = new Replicator<>();
        List<ProductionLot> lpl = toReplicate.getProductionLotList();
        if( lpl != null ) {
            try {
                List<ProductionLot> clpl = lpl.getClass().newInstance();
                Replicator<ProductionLot> rpl = new Replicator<>();
                for (ProductionLot productionLot : clpl) {
                    ProductionLot cpl = rpl.replicate( productionLot);
                    cpl.setPlantID(cpp);
                    clpl.add( cpl );
                }
            } catch (InstantiationException | IllegalAccessException ex) {
                Logger.getLogger(PlantPropertiesReplicator.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        cpp.setProductionLotList(clpl);
        return cpp;
    }

Absolutely unreadable after 2 hours never mind 2 years.

This is the code after a refactor including the bug, the bug should become apparent almost immediately, at least it did to me.

public PlantProperties replicate( PlantProperties toReplicate ) {
        Replicator<PlantProperties> toReplicateReplicator = new Replicator<>();
        PlantProperties replicatedPlantProperties = toReplicateReplicator.replicate(toReplicate);
        List<ProductionLot> plantLotList = toReplicate.getProductionLotList();

        if( plantLotList != null ) {
            try {
                List<ProductionLot> copyOfPlantLotList = plantLotList.getClass().newInstance();
                Replicator<ProductionLot> plantLotReplicator = new Replicator<>();

                for (ProductionLot productionLot : copyOfPlantLotList) {
                    ProductionLot replicatedPlantLot = plantLotReplicator.replicate( productionLot);
                    replicatedPlantLot.setPlantID(replicatedPlantProperties);
                    copyOfPlantLotList.add( replicatedPlantLot );
                }

                replicatedPlantProperties.setProductionLotList(copyOfPlantLotList);
            } catch (InstantiationException | IllegalAccessException ex) {
                Logger.getLogger(PlantPropertiesReplicator.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return replicatedPlantProperties;
    }

In the for loop it turned out I was replicating the copy of the PlantLot list instead of the original PlantLot list.
By the way, the NetBeans <CTRL>+R refactoring of current selection makes this sort of thing trivial and was what led me to spotting the bug immediately.

The bug was that if the replicated version of the instance in question was used as a template for a potential Deletion Strategy then the PlantLot instances in the list would not be deleted as well.

Four things here


  1. If you are responsible for code style rules make sure they make sense. Good style means others like to look at what is created. Other reasons you can find here and here.
    You should have refused the responsibility anyway, this sort of thing is so totally bureaucratic and counter-productive
  2. Even though I have been free from the tyranny of the Style Sergeant, Nero and the others in my old dev team (yes, the blog I linked evoked some powerful memories) I STILL FIND MYSELF WRITING CODE USING THOSE UTTERLY AWFUL RULES!!!
  3. Protest vigorously if someone tried to oppress or repress you in this manner.
  4. This is not a rant against naming conventions which are very important but can also end up leading to a bureaucratic mess when overzealously applied. The Style Sergeant was applying the rule for coding style not as a naming convention. Not that it makes any difference, it is still utterly terrible.
The creepy thing is I only write like this when in the office. At home my code is (hopefully) self-documenting and more like the second example and I was compelled to do this refactoring while in the comfort and safety of my own living room!

Thursday, 29 November 2012

Worlds apart but not that different

One the face of things: a philosophical monologue.

I have been brushing up on my ASP.Net skills prior to the start of a rather large Sharepoint based project and during the last week have been comparing the JEE6 (Java Enterprise 6) stack to the ASP.Net stack.

Luckily I don't have to wallow in the mud with VB, the language of choice here is C# so the jump between the 2 languages, Java and C#, is not so great. Mind you the syntax of a programming language, especially when they have such close roots, should never be anything other than a trivial exercise for you.

Not a clash of ideologies here

There have been so many flame wars, rants and idealists fighting about .Net vs Java that I am not attempting to fan the flames again.
If you consider the 2 platforms, as you should be doing, then .Net and Java are really worlds apart but still not that different... really!

Adam Bien posted some while ago: JAVA EE OR .NET - AN ALMOST UNBIASED OPINION
I agree with a lot of what was said there and a lot of the comments, trolls notwithstanding, have kind of kept the material up to date. What I don't agree with is LINQ for SQL.
I have been playing with LINQ for SQL and it under pressure it cracks. With even moderate amounts of data things like paged data access becomes slower and slower and memory leaks all over the place.
LINQ is still excellent for queries on generic collections and especially XML though.

The thing is that the Java vs .Net arguments live because people are way too married to the favorite language or platform and are missing the point in the abstract. Can I use either platform to provide solutions in software which fulfill the customer's requirements without having to reinvent the wheel doing it?
The answer is a resounding yes because so much of the progress made on design ideologies, eg. Patterns and development practices, eg. Agile, are applicable to any application platform in general use. Not only that but the tools available use the results of such progress regardless of which platform.

What am I waffling on about? The Backend!

As I do most of my work in the Java World I was looking for a decent all purpose ORM tool seeing as the MS one is, well, only good for the MS World and still not very good at that either.

A colleague of mine pointed me in the direction of NHibernate, a project I was already aware of.
Yes, this is similar to Hibernate from the Java World. It does suffer a lot from "A Sea of XML  Configuration" though, similar to old style EJB.
It does have a lot of advantages though

  • Database agnostic with the caveat that a driver and possibly dialect exists for it
  • It is very well supported and is used in a lot of Projects.
  • There are a lot of similarities with Hibernate and JPA and for me the jump from JPA to NHibernate was not that wide.
If it weren't for all the XML though...
Enter ActiveRecord.
  • Uses NHibernate
  • Domain objects are classes which determine the structure in the backend.
    I find it easier to do the domain at the Object level and have the engine build the car as it were, ie have the ability to create or modify the Database Schema via changes to my domain classes and their relations.
  • The only XML you really ever need is for configuring the connection, this is a snap
  • Is really, really, easy to Unit Test, I have not seen the need to mock anything yet, I can test against a real DB. You can still mock things up really easily though.
The makers of ActiveRecord, Castle, also have other goodies. I have been using their Proxy tool for quite a while now.

I am almost fanatical about the Java Platform and I do really believe that it is the best general server platform in terms of cost, reliability, performance and freedom of choice. Having said that I am able to do my thing, developing middle tier components, in either environment, and only have to deal with the differences at the surface. With .Net you just have to work a little bit harder on the backend, with Java on the UI.

Now, when are PrimeFaces going to give me all their wonderful UI Components working under ASP.Net?