Tuesday, 26 July 2011

Launch day

Finishing a project is an emotional experience.

At long last, we have put a major new version of our product, MA2, into production. Anyone involved in a project will recognise the mix of emotions I feel.

My first emotions are exhaustion and relief. Usually we change our software in small increments, about three weeks. This version has taken more than seven months, much longer than usual, and much longer than we expected. I did not realise how much it weighed on my mind until we finally put it live.

My second emotion is guilt. As regular readers know, I pontificate about the right way to run systems. But if I am honest, this is not as right as it should be. Some functions are not complete, user documentation and help files are not rewritten, there are loose end, and even a few bugs. But in the end, after testing the new version within existing users, we decided it was better to put it live than continue polishing it for even longer.

My third emotion is anxiety. I have spent the last seven months on engineering. This has its frustrations - it is a long haul, and I have worried about losing focus on our commercial activities. But despite that, there is something familiar and comforting about engineering.

Now I have to put that familiar and comforting engineering behind me. There will still be technical work, but I have to adjust to a new way of working, much more commercially focussed, and much more focussed on building solutions rather than deep engineering in the software.

My last emotion is excitement. In IT, because of our role in projects, we often think of the project as complete when we have done our bit and delivered the system. But the IT project is only the start of the business project.

If you are not excited when you put a new system in, then something is wrong. The only reason we write software and implement systems is to take the business forward, and we should always be more excited about that than we are about our own technical work.

Sadly, this excitement is often hidden in large companies, when you rarely get to see the results of all your hard work. But one of the great advantages of working in a small company and writing software to support your own business is that you are absolutely involved in the next stage.

And in our case, there are lots of reasons to be excited. If I were to conjure up a mechanical analogy for our software, we have built a machine that can make anything. It can even make machines that make other things. There is no limit to what it can do.

If you are at all engaged with your work, you are going to feel a mix of emotions like exhaustion, relief, guilt, anxiety and excitement when a project finishes. But this is only the start. All these emotions are nothing to the ups and downs we will experience as we take our new product to market.

© Copyright 2011 Minimal IT Ltd. See the Minimal IT website for the original newsletter and copyright information.

Tuesday, 19 July 2011

Add JavaScript to your application with Rhino

The Rhino JavaScript engine lets you add the flexibility of JavaScript to your Java application.

Most people are familiar with JavaScript running in web browsers, where it is used to improve the appearance and usability of web pages. JavaScript can also be used outside of a browser, for example running on a server. One powerful use of JavaScript is to embed JavaScript in a server-based application to let users (or at least power users) extend the functionality of the application.

Within our MA2 product, we use the Rhino JavaScript engine to do just that.

We knew we needed some user-defined capabilities, particularly for calculations for derived data. Rather than write this ourselves, we decided to use JavaScript, as this is widely-known and easy to use. We selected the Rhino JavaScript engine from Mozilla. It is written in Java, and so can integrate into our Java-based software. As well as being a leading implementation of JavaScript, it is open-source software which we can include in our product for free.

We have integrated JavaScript deeply within MA2, to provide a consistent mechanism for user-defined capabilities throughout the product. We use it for for data validation, calculating derived data, data triggers, and as a general scripting language including writing new web services. We also use it for user interface customisation, running JavaScript on the server to create web pages to send to the browser.

At its simplest, integrating Rhino into an application involves only a few lines of code. However, our requirements are relatively complicated:
  • Store JavaScript source in the database, with facilities to call one script from another script.

  • Integrate XML-based services, including reading and writing XML messages using strings or XPath statements.

  • Integrate into the general-purpose data structure within MA2.

  • Integrate into the user interface to create page content. This includes filtering generated page content to prevent dangerous content being output, and managing page redirects.

  • Management of credentials, allowing a script to switch user to perform data access requiring greater authority.

  • Most importantly, restricting JavaScript to access only a small number of safe Java classes.

We had originally intended to use JavaScript for user-defined calculations for derived data. However, the JavaScript support is so effective that we have ended up writing much of MA2's capability in JavaScript. Although I would be cautious of using it for performance-critical processing, it is perfectly adequate for "user speed" activities such as validating data entry. It works very well alongside the general-purpose data structure and user interface of MA2, letting us build new solutions very quickly.

Most business applications do not need the level of JavaScript integration that we have built into MA2. However, JavaScript is a good way of adding the sort of user-defined capabilities that many business applications do need, such as user-defined calculations. Embedding a JavaScript engine such as Rhino into your application is a much better option than attempting to write your own extension mechanism.

If you have a Java-based application, and need to add user-defined capabilities to it, look at Rhino.

© Copyright 2011 Minimal IT Ltd. See the Minimal IT website for the original newsletter and copyright information.

Tuesday, 12 July 2011

IT assets and transactions

We should consider documentation and program code as assets, not transactions.

Here is a piece of code I wrote last week. It is a real piece of code, not a contrived example. What does it mean?

/\(|\)|[^\(\)]*/g

Just in case you do not know, this is a regular expression, a pattern-matching instruction which can be used to search text. It means "find all the start brackets, find all the end brackets, and find all the sequences with no brackets in them".

Clever and succinct though it is, I am not proud of this code. Writing it was an act of desperation, as there is no other simple way in JavaScript to search text.

What I do not like about overly-concise code such as regular expressions is that it is almost impossible to read. You have to understand the syntax deeply and execute the code in your head to grasp what is going on. It is a maintenance nightmare.

More generally, code like this undervalues what we deliver. Program code is an asset that delivers value to the organisation. The asset needs to be maintained through time. The net value of the asset is higher if maintenance is less expensive and less risky. The primary requirement of code is to communicate how a program works to a support programmer.

The alternative is to see program code as a transaction, a one-off activity to create a new capability, where concise constructs are a valuable shorthand. Given the choice between a concise syntax that saves the original programmer a few keystrokes, and a verbose syntax that makes the program easier to read, I would always choose the verbose syntax.

This tendency to treat what we produce as transactions crops up throughout IT projects. We treat specifications as one-off instructions for the programmer, not a permanent, definitive description of the program. We treat analysis, design and tests as hurdles that we have to jump, rather than having a lasting worth that goes beyond the project.

Part of the problem is semantic. Project management calls everything "deliverables", but makes no distinction between asset deliverables that have value when the project is complete and transaction deliverables that are only there to support the project. Most project management deliverables, like project plans, are only transactions. Many of the minor and inevitably rushed deliverables, like test plans, are (or should be) assets. The smallest, least significant computer program that you deliver has more lasting value than all of your project plans, schedules, project reports and issue logs put together.

I suggest:

  • In project plans, distinguish between deliverables that are (or should be) lasting assets, and those that are only there as transactions. Transaction deliverables can be managed just in terms of time, quality, and fit to the next step of the project. Asset deliverables demand extra attention.
  • For asset deliverables, consider the qualities that will affect their value as assets, and produce the deliverables that you would hope to find when supporting and changing the system.
  • Do not waste time writing documents that only explain how to build the system. Spend your time on documents that explain how the system works.

Tuesday, 5 July 2011

Secure by design

Designing systems to be secure is never easy, but it is much easier than adding security to a system after it has been designed.

There are lots of factors that contribute to the security of IT systems: user awareness, processes and procedures, specialist advice, hardened infrastructure, and testing, to name but a few.

One of the most important factors is software design. However, we do not often think about security during design. Looking back over my professional education, I have had plenty of training in analysis, database design, online transaction processing, structured programming, and more, but none at all about how to design systems to be secure.

As a software designer, it is tempting to ignore security. Other people are responsible for security policy and infrastructure. You only need to change the design if problems happen, or if a security specialist kicks up a fuss. However, this reactive approach is a dereliction of your duty, and will never lead to a secure system.

Instead, you need to assume that, deliberately or inadvertently, all possible weaknesses in the system will be exposed. With this in mind, you have to design the system so that you have opportunities to inspect and/or block inappropriate access. You have to think of this at multiple points through the design.

To give some examples from our MA2 product:

  • Web traffic is not by default secure, and can be intercepted. To prevent this, use secure HTTP (HTTPS) which encrypts the traffic.
  • Any user-entered content runs the risk that users could insert content that disrupts the sessions of other users, often known as "cross site scripting" or XSS attacks. To prevent this, use a product such as Antisamy, which comprehensively analyses and modifies user input to remove potential attacks.
  • Use of SQL on the database runs the risk of injection attacks, where special data values are interpreted by the SQL as extra commands which can compromise data. To prevent this, never build SQL dynamically, but only use prepared SQL statements which are passed data parameters, which prevents SQL injection.
  • It is hard to write complicated user interface code that is sufficiently free from defects that it fully enforces security. To overcome this, pass all data access through a more formal API layer (in our case XML-based services) which can check security comprehensively.
  • Data might be compromised by accident, or through misuse of an account. To minimise the impact, provided a very granular permission structure so that users can only access the minimum amount of data required for their work.

Do design elements like this guarantee security? It is wrong ever to be complacent, and security requires many factors, but thinking about security during design certainly makes a system more secure. Importantly, factoring security into the design provides a set of touch points at which security checks can be implemented, and, should problems arise, they provide places where security can be improved by strengthening, extending or re-implementing the existing checks. It is certainly much better than attempting to retro-fit security on an otherwise insecure system

Designing in security is not easy, but it is something that should be an integral part of every system's design, and never an afterthought.

© Copyright 2011 Minimal IT Ltd. See the Minimal IT website for the original newsletter and copyright information.