Archive for the ‘Coding’ Category

Code generation? Don’t generate to Java

Wednesday, February 10th, 2010

I tried to write a program using Java; it all seemed to be going well but then I hit a ridiculous limit. Java cannot be used for this type of problem. I have now completely re-written it in a different programming language, and that works fine.

Be aware of this limit. I was unaware of it when I started this project. But it makes Java completely unsuitable for a whole class of problem.

My customer supplies me with a config file from time to time, this specifies a certain algorithm. When the user enters data, this algorithm must be applied. The algorithm is complex, so performance is an issue.

The solution I chose was to generate code to execute the algorithm, based on the information in the config file. This is a valid computer-science approach, and is used for similar problems. For example, language parsers are often expressed as a grammar, and code to parse documents in the grammar are generated. JSPs are turned into Java classes which are then compiled and executed. WebTek pre-compiles HTML templates containing macros into code which produces the resulting HTML when executed.

However, don’t try this in Java, unless you are only working with small problems. A single method in Java can only be 64KB in size, once compiled.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4262078

This means, JSPs can only be of a certain length, parsers can only parse languages of a certain complexity, if WebTek were written in Java then templates could only be of a certain length and complexity, and so on. Do you want to place such restrictions on the software you produce?

My specific problem involves simulating one million variations to a particular solution. How can I fit that into 64K?

  • That is 0.06 bytes per solution variation; yet the simulation of a single variation involves many lines of code (i.e. in total compiling to more than 0.06 bytes!).
  • I could put each variation into its own method, and have a big method which calls them all—but a method call takes more than 0.06 bytes!
  • I could have a hierarchy of methods: one main method which calls, say, 100 sub-methods, each of those call 100 sub-sub-methods, and finally those methods call the methods for the individual variations.

It’s not even possible to know how many bytes a method will generate to! So, as the complexity of the simulation of a variation is expressed in the config file, I would have to essentially have to do a “trial and error” approach: generate a method, compile it, if I get the error concerning the 64KB limit, split the problem up into slightly smaller methods, try the compilation again, repeat, etc. (And the Java compiler is not even very fast.)

This is all so wrong! This is complexity, which isn’t solving the customer’s problem. This complexity costs me time (and thus my customer money), complexity leads to bugs and difficulty of maintenance, etc.

So I have changed the language. Rather than generate Java, I generate C and compile it using the GNU gcc compiler. From the GNU coding standards:

Avoid arbitrary limits on the length or number of any data structure, including file names, lines, files, and symbols, by allocating all data structures dynamically.

This is a good standard! I like it. All programs should be written with this in mind. Your program may well be online in 10 or 20 years, and the hardware may well have changed: a 64KB limit may seem reasonable one year but is a real limitation 10 or 20 years later in software which would otherwise still be useful.

So, if you are solving this type of problem, don’t use Java.

P.S. On a separate project I used a similar approach using Perl, and that worked out fine too.

PHP infinite recursion

Wednesday, November 18th, 2009

What can I say? How about “toy language”?

$ php -r 'function foo() { foo(); } foo();'
Segmentation fault

I’m not saying that infinite recursion is a good idea, but during development it can happen by accident, and I don’t expect such a simple error to crash the PHP interpreter! (Also it took me about 20 minutes to debug this problem, as I had no idea where it happened, nor indeed what the problem was..)

PHP 5.2.6 on Linux 2.6.26 Debian

“Go” programming language

Wednesday, November 11th, 2009

Before everyone gets too excited about the “Go” language, let’s not forget it lacks:

Generics are necessary to express concepts like List<List<MyType>>. If you are in to static typing, then you need to be able to express those concepts. (And if you are not, then a statically typed language like Go is not for you anyway.)

Obviously it has good features as well, such as its concurrency constructs and type inference, but without those features above, I can’t see how you can do any useful modeling in the language; or rather how can you can express a useful model in the language without losing a lot of information.

http://golang.org/doc/go_lang_faq.html

Perhaps those features will be added in future versions.

Java: Always explicitly specify which XML parser to use

Tuesday, September 15th, 2009

There is the following design error in Java (at least in Servlets):

  1. A server may serve multiple applications; each application may use different libraries or even different versions of the same library, “side by side”.
  2. XML parsers, transformers (XSLT), etc., have a standard interface, and there may be different implementations of this interface from different vendors, open-source projects, etc.
  3. Which XML parser, transformed etc. is actually used depends on a global system variable.

And it’s point 3 that’s the problem really. Points 1 and 2 are debatable: they certainly bring advantages, but they certainly bring complexity too.

I just had the problem that one of my web applications stopped working, but only intermittently. Restarting the server led to everything being OK, but later things would not be OK. I do hate environments where everything appears to work, yet in fact doesn’t. I mean how do you know when you’re “done” in such an environment? (Or how do you even know you are in such an environment?)

The bug was caused by:

  1. Application one used the default XML parser, and didn’t have any extra JARs (libraries) for reading XML
  2. Application two required a special XML parser, set the global variable so it would be used, and included the JARs necessary for the special XML parser

So when a request came to application 1, after a request had come to application 2, then the system would try to instantiate the special XML parser within application 1 (specified in the global variable set by application 2), but wouldn’t find it, as it wasn’t deployed in application 1 (and applications can’t use one another’s libraries, due to feature #1).

This seems obvious when one describes it, but looking at the logs, on a live server, with the system down and the clock ticking? – Far from obvious.

So now, I assert, every time you want to create an XML parser, do the following:

If you require a special XML library, use:

System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
    "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
...

If you require the standard XML library, use:

Properties systemProperties = System.getProperties();
systemProperties.remove("javax.xml.parsers.DocumentBuilderFactory");
System.setProperties(systemProperties);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
...

There is also the possibility to pass a parameter to DocumentBuilderFactory to specify which XML parser technology to use. That’s a good option too, as it wouldn’t “corrupt” this global variable (“system property”). However I think one should be defensive, and always delete the global variable if one wishes to use the standard XML parser, and therefore it doesn’t matter if this global variable gets corrupted or not.

Never do the following:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

This simply relies on whichever XML parser is currently set in the global variable. You have no way to guarantee that some other application running on the same server won’t set the global variable to use an XML parser you don’t have installed in your application. Even if you have control of the server and all applications, you don’t know what software you’ll be writing in the future. (In this case I installed a new application to a server which’d been running fine for 1 year, but due to setting the global variable, the old application broke..)

The same applies for all those other “factory” situations such as TransformerFactory.newInstance() etc.

This feels all quite inelegant to me, and has just cost me a lot of time, and it’s not as if I’m so new to programming Java. I am wondering if there is a better way to approach it? Or is Java just broken in this particular respect?

P.S. This is not the only thing that went wrong with the old application today. I upgraded from Java 5 to Java 6 and suddenly some XML was not compliant against a schema according to Java – I had hit this error.

Never close PHP class files with the “?>” tag

Friday, August 21st, 2009

When developing PHP, a front-end PHP file will include other files: classes, utilities, etc.

When writing those class files, one also needs to use the <?php tag at the start of the file, otherwise PHP will simply take the text and output it unchanged to the browser. (PHP’s assumption is that it sits in a web page, with probably more markup than code, so by default characters in the source code get copied one-to-one to the browser and the <?php?> tags are necessary to introduce PHP to the “exceptional circumstance” that one might actually want to program some PHP.)

If one must open the class source file with <?php then it would seem to make aesthetic sense to close it with ?>. However, there are no negative side-effects if one does not close the tag, plus one very negative side-effect if one does close it.

We performed a minor release a while ago, after which the display of generated PDF files no longer worked. Yet the minor release had nothing to do with the section of code that produced PDFs. What sort of weird action-at-a-distance could possibly be happening here?

The reason was that one class file in the minor release had a blank line after the ?> tag. This was impossible to spot in the text editor. The blank line was printed to the browser, which was also invisible in nearly all of the site, as HTML ignores blank lines. PDFs probably do as well (I haven’t checked) but the problem wasn’t with the content. As HTTP response content is streamed to the browser (as opposed to being collected first and then sent to the browser at the end of the request), HTTP headers can only be set before the first byte of output has been produced by the software. As the blank line in the class source file consituted content, and the source file was (necessarily) parsed before the code could be executed, the HTTP header “Content-Type: text/pdf” couldn’t be sent, and various errors about headers not being able to be sent, combined with the binary source of the PDF, arrived at the user’s screen.

So given there are no disadvantages, and one particulary weird source of bugs can be removed, I would say one should never end PHP files with ?>.

Starting Jetty: FAILED

Sunday, July 12th, 2009

It is literally 23:19 on a Sunday and I’ve been working through the weekend to get a release out of some software I’m working on.

The Java application webserver (Jetty) was taking a long time to restart each time I did a change, so for some reason I thought I’d experiment with some new command-line options. Probably not the right time to do that.

Normally I would type

$ sudo  /etc/init.d/jetty6 restart
Stopping Jetty: OK
Starting Jetty: OK

and everything would be good. I tried typing

$ sudo /etc/init.d/jetty6 supervise

Then some stuff happened that I didn’t really understand. Rather than try and work out what it did I tried to restart it again using the old restart mechanism

$ sudo  /etc/init.d/jetty6 restart
...
Starting Jetty: FAILED

OK I mean that was basically what was going on, it just wrote FAILED. How helpful! There was no info in the logfile. I searched Google but didn’t come up with anything.

A reboot later, and about half an hour of looking into /etc/init.d/jetty6 with vi and randomly making changes and printing more stuff out yielded the fact that the “supervise” command had evidently run Jetty “as me” and not as the “jetty” user. So when the normal “restart” command came along and tried to run the program as “jetty” then there were files it couldn’t write to.

Solution:

$ sudo chown jetty /var/log/jetty6/2009_07_12.stderrout.log

My favourite Hibernate error

Wednesday, June 10th, 2009

… is this one. I’ve wasted many an hour searching for the cause of this. And it’s one you’re likely to run into pretty quickly when you try to write your first Hibernate configuration file.

The XML

<one-to-many type=”OtherClass”/>

delivers the error

Error parsing XML: Attribute “type” must be declared for element type “one-to-many”.

This looks like a perfectly self-explanatory error, however looking at the file, the element does have a “type” attribute. What should one do?

Thinking about it, I only just introduced the “type” attribute to the <one-to-many> element in my config. What happens if I change the attribute name to “fsdjkfdk”?

<one-to-many fsdjkfdk=”OtherClass”/>

The error is now:

Error parsing XML: Attribute “fsdjkfdk” must be declared for element type “one-to-many”.

What the error means is that the attribute must not be declared, as opposed to must.

It’s amusing to read even people on the Hibernate team get confused by this error, and can’t find a solution.

(Hibernate 3.3.1 – the most current version – although I encountered this error within the first hour of ever using Hibernate in Q1/2006.)

Order of function parameters

Friday, May 8th, 2009

Functions take parameters. What order should these parameters be in?

Perhaps a bit of a ridiculous question, given that it clearly doesn’t matter.

void writeUser(Connection c, User u) { ... }
void writeUser(User u, Connection c) { ... }

If one writes either of these functions, they will both work, and any performance differences between the two would be an extreme micro-optimization which wouldn’t be platform independent (e.g. in RISC OS the first 6 parameters to a C function were stored on the stack and the rest weren’t, unless one used a “pass by value” structure, so it might have an impact on performance… but I digress)

However, certain languages support the feature partial application, where passing only some of the parameters to a function produces a function taking only the remaining parameters. For example (in SML, syntax examples, BTW A sad sign of the times when Googling for SML yields “Did you mean: XML”)

fun add (a,b) = a + b;
add 1 2;                 (* prints 3 *) 

val successor = add 1;   (* generates function taking 1 parameter *)
successor 2;             (* prints 3 *)

So in those languages, it makes sense to place the most constant parameters as left-most as possible. (The syntax only allows left-most parameters to be partially applied.)

For example a function to write a user to a database connection might be defined as taking two parameters, a database connection and the user to be written, and partial application could be used as follows:

  Result of partial application
writeUser db user   Function which writes any user to a fixed database connection
writeUser user db   Function which writes the particular user to any database connection

Clearly the first partial-application function is much more useful than the second.

Even in languages which don’t support partial application I’ve noticed a convention of functions being defined this way, probably because at least some (of the best?) code is written by people with experience of functional programming languages. I like this convention, and adhere to it myself.

Java really delivers “write once, run anywhere”

Wednesday, May 6th, 2009

Java’s slogan was “write once, run anywhere”. They received a certain amount of criticism but I have to say that compared to other programming languages it’s really true. You can use it for:

  • Background jobs (without user-interface)
  • Server-side web applications (many web servers & web frameworks available)
  • In the web browser (applets)
  • In the web browser (translation from Java to Javascript by GWT)
  • On the desktop (using platform-independent Swing, or with native Apple UI using Cocoa)
  • On some mobile phones (J2ME, Google Android) – although I haven’t tested how good that really works?

Writing the previous version of a certain application website in Perl, there was no easy way to give the customer a “tool” to test out new versions of the configuration file. These files would normally be installed on the server, were multiple megabytes in size, and the Perl would parse and use them. For testing, it was not ideal to have to upload potential new files to the test server, due to their size.

The new version is in Java and also takes a configuration file, but I have written a Swing (desktop) tool which simply allows the tester to select a new potential configuration file from their local hard disk, and the desktop tool reuses all the processing logic 1:1 that the web server in production would use.

That wouldn’t have been possible with the old version of the logic written in Perl. (I know there are windowing libraries for languages like Perl but they are hardly as easy to deploy – i.e. install on a Windows workstation – as a Java application – simply double-click the .jar file once Java is installed)

I am writing the web front-end for the new version in GWT so I can reuse certain (mainly user validation) code between the web browser (giving the user instant feedback in case of errors) and the web server (necessary for security in case someone bypasses the client and sends HTTP requests directly.) And simply pass Java objects between the web server and the web client, without having to worry about how that transfer works (JSON, XML, etc.)

Other mainstream candidates for languages which run on multiple places:

  • Objective-C is not too bad, running on Apple desktops, Apple iPhones, and on the web server via WebObjects (does the current version of WO still use Objective-C or is it Java-only these days?) – but not in the browser
  • Javascript runs on the web browser and server, and no doubt mobile browsers (but not desktops as far as I know)
  • Perhaps C#? Certainly good desktop, web server integration, no doubt IE/Windows integration via ActiveX

“v” command in “less”

Wednesday, March 4th, 2009

Cool, just discovered: if you’re using the (UNIX command-line program) “less” to view a file, you can hit the “v” character to open the file in “vi”!