Notes of a (Java) developer

Software engineering (category)

Software developer Programmer

I once saw an online content explaining that software engineering is not engineering because it is not innovative, at least in most cases (sorry for the missing hyperlink but I don't find the reference). This is probably true, and a right software developer should not try to be excessively innovative just to prove he is an engineer. Making things simple is really important. At first glance, this is a kind of paradox. When it comes to software, things tends to be perceived as complex. But this is a misconception: indeed, software involve very large sets of components. Each one is individually rarely sophisticated.

This introduction does not mean that software engineering is not central: only that the term is perhaps inappropriate. The elements are key concepts of software and should always come before code. I think that programming is more about what is called software engineering than about code. Not because of any kind of complexity, because of the numerous tenants involved.

Compile-time checking in Java

Software developer Programmer

In a previous post I wrote about code quality: in a few words, I believe in static-checking. Static means without executing the program. In a software process point of view, this would imply before runtime, in other words at compile-time. For a developer, it can be very useful to have such a verification simply with a compilation, without executing a specific tool (by the way, some very interesting software of that kind are available, just Findbugs for example).

Here is the point: how would it be possible to proceed that kind of control without rewriting a compiler from scratch ?

The Java platform provides a very interesting feature to perform such operations: annotations (JSR 175). These are metadata defined as java types. Annotations have been introduced in the Java language starting with Java SE 5. Annotations can be processed at compile-time or runtime.

The Sun Java SE distribution provided from the starting point a facility for annotation processing at compile-time called APT (for Annotation Processing Tool). This was a vendor-specific feature (in Sun packages) executed in a specific and eponymous command line tool.

Since Java 6, that function is part of the platform with JSR 269 (javax.annotation.processing package, reference implementation part of the Java SE distribution). The contributed processing can be executed along compilation. With Java SE 8, the historical APT packaging and specific tool is removed (after deprecation in Java SE 7).

If the topic seems basic for the Java platform, there is a lack of exhaustive documentation for annotation processors development. I found some precious informations in , a blog post by . The Eclipse platform provide very precious functions with the JDT-APT project.

A very interesting by and from develops many important points about compile-time checking: what could be done with annotation processors and what requires more. For example, the processor does not provide the structure of the AST and thereby does not allow flow analysis.

A processor must implement the javax.annotation.processing.Processor interface. The implementation should be specified to the platform using the SPI system. An abstract class AbstractProcessor is provided to help implementations.

In a details the implementation of a compile-time processor for the @Transactional annotation of the spring framework .

History of computing: information processing and transactions

Software developer Programmer

"Computer science is no more about computers than astronomy is about telescopes" said Edsger Dijkstra.

I have always been interested in the two sides of computing:

  • Calculus
  • Information processing

In the early ages of computing, we tend to focus on the first machines and their calculus properties. inventions are famous.

But in the early 19th century, the pioneer was also interested in information processing and transactions. Reading an article I discovered he described the processes involving bank transactions in one of his works: On the Economy of Machinery and Manufactures.

Point of view: MVC frameworks

Software developer Programmer

After some (bad) experiences, I am quite sceptical about MVC frameworks. The hall of fame has accepted a few names: Struts, Play, Wicket... And then ?

Each period has its champion. Struts, as one of the elders, had a long period. So many developers had to use it. But what about software maintenance and evolutions ? Software dependencies between the model, the view and the controller can make moves very challenging. Struts 1 upgrade to version 2 ? What about moving to another technology ?

Quite a nightmare, it is sometimes easier to rewrite completely the application. In my point of view, long term solutions rely directly on the Java platform. The classic Servlet / JSP tandem is not an MVC implementation but is plain and simple and evolutions are easy. I understand JSF enthusiasts. The solution is modern and interesting on a productivity point of view. I have a personal problem with JSF (and others share my opinion) : JSF and JSP are bad companions. What a shame for two specifications...

While the RESTful architectural style is trendy, the idea of integrating JAX-RS and JSPs is interesting (part of Jersey). Hope it will be part of the core specification someday.

Edit (2014-08-21) : the JAX-RS / MVC integration was part of the JSR 339 initial request but was dismissed in the final specification. A recent message on the specification list let me have some hope...

Design by contract, assertions and exceptions

Software developer Programmer

Understanding design by contract is, I think, important for software quality in OOP because the principles are clear and efficient.

introduced the idea in 1988. It takes advantage of assertions as defined by (1969), the seminal work of an eponymous logic.

Assertions are associated to an object method and qualified in one of three categories :

  • Preconditions are assertions true before executing the method
  • Postconditions are assertions true after executing the method
  • Invariants are assertions true before and after executing the method

In practice...

includes his idea in the programming language : the assertions are checked in a static way (at compile time).

If the Java programming language provides support for assertions, these are checked only in a dynamic way (at runtime) and disabled by default. Because of runtime checking, exceptions are largely used instead of assertions. In Java, a proper use of exceptions can be more meaningful to the programmer than a proper use of assertions because it provides more details about the malfunction conditions (the stack trace). At first glance, assertions (in the design by contract way) seem to be very far from exceptions. This is to some extent a paradox: I think the developer should consider assertions concepts every time he uses exceptions.

In Effective Java , defines checked exceptions as recoverable conditions and runtime exceptions as programming errors.

In an non-Java context, says an exception is a situation where preconditions are satisfied but postconditions can not be satisfied.

I think that, to respect Bloch terms,

  • Runtime exceptions should be used for checking preconditions
  • Checked exceptions should be used when preconditions are true but postconditions can not be satisfied, assuming that the method is correct (e.g. the network connection is broken). 

If a runtime exception is raised, the calling method should be bugged (or its preconditions are not properly checked).

Some extensions to the Java platform provide support for static testing (assertions checking at compile time). For example, JML takes advantage of Java comments: this is interesting for traditional compiling compliance.

Point of view: Packaging

Software developer Programmer

According to The Unified Modeling Language User Guide, object-oriented software elements belong to one of these four categories:

  • Structural things
  • Behavioral things
  • Grouping things
  • Notational things

Obviously, classes are structural elements. According to this same book, packaging is the act of grouping classes.

Something is bothering me about packaging. All programs I have been working on, and all courses I have been following, share a single vision of the way these groups should be considered.

In this single vision, classes are grouped on structural criteria. In a same package, we will find objects assuming a single role: DAOs with DAOs, entities with entities, controllers with controllers. To be honest, this helps designing interesting class diagrams. This has a real interest for building effective heritage hierarchies.

But in my point of view, we let apart behavioral criteria. One DAO object usually interacts only with a single entity class and a few services. This means, if we design sequence, activity or state diagrams, the involved objects will belong to different packages. This would be very helpful to help software maintenance: in a single set we have all the relevant elements.

Here is a summary:
  1. Usually, package elements grouping is based on classes roles to help software design
  2. Package elements grouping should also be based on classes interactions to help software maintenance

If we would like to design really modular applications, I think we should consider these two axes while packaging. On a pure design point of view, a class should belong to two packages : one structural (1) and one behavioral (2). This could be possible because one class usually has interactions with a few classes.

In Java, one solution to help set up this second kind of packages could be annotations. But the problem would be in class loading. This wouldn't be a real problem if we all time use to write APIs.

A pragmatic solution would be to change the packaging in the development process. Once the software has been designed building interesting heritage hierarchies based on roles, packaging should be modified to follow classes interactions in order to help software maintenance.