Thursday, March 14, 2013

Java code - correctness and consistency

It has taken nearly a month to cleanup most of the data access code (DAO classes) mainly produced by a consultant.  I will say that some of the changes are "nice to have" items but there were plenty of "must fix" items with a few of those still remaining.  The fact that there is lots of client code, little documentation and a lack of coherent conventions drove me to start looking for ways to get things in better order and keep them that way.

The initial steps in the cleanup of the "must fix" items:
  • Implement the interface java.lang.AutoClosable in the base class of all the DAO code.
  • Provide a factory type instance into the DAO instances which acquire DB connections instead only when absolutely needed (which isn't 100% of time in these "DAO" classes).
  • Replace the previous DAO connection close() logic (which was never in try/final blocks)  with the Java 7 try-with-resource constructs everywhere.
So at this point, we have reduced the amount of DB connections being tied up needlessly and have plugged all the known potential DB connection leaks. 

Some other changes involved conversion from one cache solution to JBoss Infinispan 5.x and a different method of handling cache keys for the DAO data.  I ended up with a somewhat more complex solution for this to help reduce the chance of keys being duplicated and used for different data items.  The Java enum type is great for this and being able to implement interfaces on them provides a lot of flexibility.

The next problem was how to sort out data flow, mutability and nullness consistency.  I try fairly hard to keep a certain consistency in what I return from DAO methods.  I find that returning null tends to produce more errors through forgetting to check for it in all cases.  This can be mitigated by not returning nulls whenever it makes sense.

I find this most useful when dealing with collections - return Collections.emptyList() (or use similar methods for sets and maps) instead of returning a null where there was no data to return.  This works when you return something the client doesn't mutate.  Other use cases might be handled by returning a new mutable empty list (but only if truly needed), requiring the client to make a copy of the object or possibly having the caller provide the collection.  Wrappers and immutable collections are quite useful to prevent modification to the returned object when there is content in collection.  Consistency is helpful to fellow developers who may not know the application or frameworks as well as the original developers.

One deficiency of Java is that it is impossible or nearly so using just the core language itself to fully define mutability constraints and expectations.  Most of the time this must be done via Java doc with the hope that it is actually correct.  The current project I am trying to sort out lacks usable Java doc or comments on what the best constraints should be.  I am starting to work with an annotation framework to help document, report and enforce various constraints (mainly nullability and mutability).

      http://types.cs.washington.edu/checker-framework/

I am trying to utilize it via an Eclipse plug-in with some success (but not complete).  I think the nullability checks are working but I am running into problems with the mutability annotations.  I know there are some limitations using Java 7 which should be removed or minimized with Java 8.  It could also simply be related to the Eclipse plug-in or the use of Eclipse 4.2.  The embedding of the annotations in Java comments has both good and bad aspects. I like not having to worry about the build server having the annotation jars, etc but I would like Eclipse to tell me when I make an obvious mistake well before I try to generate and analyze results.

If I am able to get this working correctly for my main cases, it has the potential to provide a much higher static gurantee that object instances are only being used in the way I intended them.

Other useful references are:
JSR 308: Annotations on Java Types
JSR 305: Annotations for Software Defect Detection
Java Modeling Language (JML)

Once I am able to get a more rigorous definition of how the DAO data is used in the current application, we can either further improve the plain JDBC based solution, move to an internal framework which uses Apache DBUtils or possibly move to Hibernate.

I am slightly leaning toward Hibernate because I think it will reduce our custom code, remove/reduce the need for the manual caching of data, possibly improve performance and generally reduce the number of sources of problems.  I only say "leaning" until I gather enough info and prototype & evaluate some partial solutions for comparison.

Wednesday, February 27, 2013

Java / Struts2 I18N and DB backed ResourceBundle

I am a strong believer in deployment processes which don't involve making a patchwork of changes to a previously deployed WAR file in a production environment.  The downside to that is things like minor changes to properties files require a full deployment (and across a number of servers in this case).  The time consumed by this combined with the fact that the normal maintenance window is at a time I would rather spend with the family drove me to look for other solution.  After some searching, it seemed that the most reasonable solution fitting our needs involved moving the data to the database and writing some code to leverage the ResourceBundle framework.  It was hoped that struts would seamlessly work with this.  That didn't turn out quite true.

For the moment, I ended up having to force the pre-load of the Resource bundles (English and Spanish) before they seemed to be found fairly reliably. There is some odd behavior when working with our custom ResourceBundle.Control which could be a root cause.  There are still some problems where some application areas seem to not pickup the Spanish data and this may be an issue with struts.  Further debugging is required - hopefully this can be resolved fully even if no optimal solution is found.

I truly wish that DB backed ResourceBundles were supported directly by struts 2.  I believe some other newer frameworks support this - maybe it is time to revisit framework decisions.

[2015/11/8] Notes added below..

My current use of this works by pre-loading the bundle from the DB before the first real need. After that point, the cached bundle is returned during request from struts, etc.  I am using the Spring framework to initialize/load the ResourceBundles early in the web application startup - thereby getting the bundles cached.

Link(s) I think I found/used regarding DB backed resource bundles originally.
DB backed resource bundle reference 1

Potential Issues:
For ResourceBundle.Control the Java doc for the "needsReload" method says
"The calling ResourceBundle.getBundle factory method calls this method on the ResourceBundle.Control instance used for its current invocation, not on the instance used in the invocation that originally loaded the resource bundle. "  
and the "getTimeToLive" method Java doc says
"All cached resource bundles are subject to removal from the cache due to memory constraints of the runtime environment. "
This seems to leave the possibility that a bundle could be dropped from the cache and would not reload properly since it wouldn't access the correct ResourceBundle.Control instance which is only used during the application initialization.  I ran into something that acted like this (but without memory pressure that I am aware of) with the result of getting resource not found exceptions. I'll be looking into this at some point.

I would really like to propose some Java change that would prevent the above potential issue but some aspects of the JCP membership agreement and my employer make that difficult.  I had also considered that maybe a change at the JSF2 (my current focus) layer could work but have not looked into it any further.

[2016/05/19] New info.
I ran across something useful and likely better than my original design.  It is facilitated by the new as of JDK 8 ResourceBundleControlProvider interface.  See the Oracle docs here. When time permits or the need arises (which might be soon) I will give this method a shot.

As an alternative, I have considered creating a ListResourceBundle that still uses a database for the data.  The downside of this is still the need of a class per bundle because resolving a bundle is done by looking for a class name reflecting the bundle name and locale. A superclass could probably be created which does all/most of the heavy lifting and sub-classes would exist mainly for Java logic performing the bundle to class resolution..

The more I think about it, the more I think the ResourceBundleControlProvider is probably the better way.  It will be more complex - without further research I am concerned about getting the database connectivity into provider early enough to be useful and without having class loader issues.  Much of my DB connectivity uses Spring based configuration and involves a number of dependencies.  I'd hate to create a new configuration method to get connections into the provider but it could be needed.  I'll have to prototype it to verify.

Friday, December 28, 2012

Medical records data - HL7

I keep thinking about a career adjustment - basically converting from more general applications development to more specialized applications.  I had considered going back to college for a masters degree in bioinformatics and trying to start over from there.  I decided that was too much disruption to my family mainly for just my benefit - at least while my kids are young.  I have considered trying to learn HL7 (mainly v3) and look for an appropriate job opportunity.  That is by the fact that my current employment takes more time than I care to admit and to the detriment of my family as well some days. 

[Update] I decided that it is more practical to look into career paths more inline with my existing eduction and some other interests.  I still find it useful to understand the technology as you never know when it will come in handy in some way.

I have looking into HL7 for a year or 2.  This was challenging since there was little freely available information/tools.  In the meantime, some of basic information is now more freely available along with a few tools.  The only other major hurdle is that I would likely learn using freely available Java resources whereas it seems, based on job postings, that most jobs are doing .NET solutions (or mainframe).  Learning .NET (versus just C/C++ on Windows from years ago) is on my list to do but time consuming as well.  My current job will likely require an increasing amount of .NET work so given time.. but this is off topic a bit.

I'm trying to keep a list of potentially useful resources (with a majority of focus on freely available resources) to learn/utilize.  I have not reviewed any of these in more than passing at this time.
  • http://en.wikipedia.org/wiki/Health_Level_7
  • http://www.hl7.org/participate/toolsandresources.cfm
  • http://sourceforge.net/projects/hl7inspector/
  • http://www.openehealth.org/display/ipf2/Home
I would have liked to join in some free webinars related to HL7 but so far they have always occurred at times when I was not able to take off from work (nor could I really justify it during my normal work day since it is not really related to my current employment).

Finding realistic sample data to learn from may be challenging.  Anyways, even if this doesn't lead to a job change, I think it is still a worthwhile to stretch my knowledge into other areas.  I find it quite amazing when some seemingly unrelated information helps me with a current difficult task.

 I'll hopefully add more interesting and useful content related to this over time.