Archive for the ‘Java’ Category

Wicket auto-complete text fields

Tuesday, August 30th, 2011

It’s modern practice in web applications to augment text fields with suggestions while one types. There are plenty of Javascript libraries out there to do that, and plenty of integrations with the Java web framework Wicket out there as well, but somehow none quite did exactly what I wanted, so I’ve rolled my own Wicket code (based on JQuery). And here they are.

What I wanted, but what other Wicket / Javascript libraries did not do, were:

  • I wanted to allow the user to type multiple values. If you compose a message in Gmail, you want to be able to enter multiple recipients, not just one.
  • I wanted to have the option to either allow the user to type in options which were not presented (e.g. like when composing a message in Gmail, or typing in tags into Stack Overflow) or restrict them to the options presented (like recipients in Facebook)
  • I wanted to either allow the options to be included in the HTML page (e.g. for a set of 10 options, there is no point forcing the user to wait for a server round-trip to fetch matching options), or allow the options to be fetched from the server (e.g. if there are 1M options, they can’t be included in the HTML page).
  • I wanted the API to be incredibly simple. I want to include a single <input> into the Wicket HTML document, create the object in Java using a constructor, and attach the data source (client-side or server-side) in a single line.

Surprisingly all of the above are not particularly easy to achieve simultaneously. But they are now done:

And coupled with my newly created extensive multi-lingual location hierarchy database (hierarchy in the sense of 2nd district -> Vienna -> Austria -> Europe -> World, multi-lingual in the sense I have these displayable strings in various languages), allows me to create a MultipleValueLocationTextField subclass, which can be included in a host HTML page in one line of HTML and one line of Java, and which synchronizes its data with a Location[] in the client code (e.g. straight from/to a domain object), and it looks like this:

The source for the two Wicket fields linked to above is LGPL. Download Databases & Life Util ZIP.

Converting an SVG to a PDF programmatically

Saturday, August 20th, 2011

Searching for this topic on the web led to various libraries, all of which were no doubt very powerful, all of which were extremely large and difficult to use if one didn’t know how. Plenty of advice existed on the internet, “use library X”, but when the library has hundreds of thousands of lines that isn’t really enough information. I didn’t even mind in which programming language the solution was to be written.

After hours of searching, reading Javadocs, reading source, and experimenting, I finally came up with the following lines of Java code.

Alas, this method can only convert from a SVG file to a PDF file, i.e. these have to be files existing on the disk, they cannot be URLs, in memory, cannot be streamed, and the SVG cannot be an in-memory DOM object. My SVG is dynamic: I’m altering/creating it at runtime (after all, if I wasn’t doing that, I could just save the PDF somewhere statically in the first place and wouldn’t need to do the conversion). And I want to deliver the PDF to the browser so streaming would be good for me. But no matter, I use File.createTemporaryFile together with deleteOnExit to create these files, and just ignore the fact that if the JVM exits abnormally, e.g. the computer suffers from a power failure, these files will never get deleted, and, over a long enough time-span, will fill up the disk until the computer fails.

Here are the lines:

import org.apache.batik.apps.rasterizer.DestinationType;
import org.apache.batik.apps.rasterizer.SVGConverter;
import ...

// SVG is created programatically as a DOM Document 
Document svgXmlDoc = ...

// Save this SVG into a file 
File svgFile = File.createTempFile("graphic-", ".svg");
svgFile.deleteOnExit();
TransformerFactory tFac = TransformerFactory.newInstance();
Transformer transformer = tFac.newTransformer();
DOMSource source2 = new DOMSource(svgXmlDoc);
FileOutputStream fOut = new FileOutputStream(svgFile);
try { transformer.transform(source2, new StreamResult(fOut)); }
finally { fOut.close(); }

// Convert the SVG into PDF 
File outputFile = File.createTempFile("result-", ".pdf");
outputFile.deleteOnExit();
SVGConverter converter = new SVGConverter();
converter.setDestinationType(DestinationType.PDF);
converter.setSources(new String[] { svgFile.toString() });
converter.setDst(outputFile);
converter.execute();

And I have the following JARs (search using Google to find the projects and download them):

  • avalon-framework-4.2.0.jar
  • batik-all-1.7.jar
  • commons-io-1.3.1.jar
  • commons-logging-1.0.4.jar
  • fop-0.95.jar
  • log4j-1.2.15.jar
  • xml-apis-ext.jar
  • xmlgraphics-commons-1.3.1.jar

Visibility & type inference in Java

Tuesday, February 8th, 2011

In Java, private classes can be used in signatures of public interfaces. This makes no sense!

I had a situation the other day that I wanted to break one line down into multiple lines for readability. But it wasn’t possible. If I wrote the code as one line it worked; multiple lines it didn’t. This is rather inconsistent! The following public class demonstrates the situation:

public class PublicObject {
    private class PrivateObject { }

    private PrivateObject x;
    public void setX(PrivateObject x) { this.x=x; }
    public PrivateObject getX() { return x; }
}

As you see, PublicObject instances are allowed to provide public methods which take and return PrivateObject instances, however that doesn’t make a lot of sense, as you can’t write client code which creates or manipulates PrivateObject instances.

But in fact that’s not true. Java does, in a very few places, use type inference (more info here) to guess the type of objects, to save the programmer typing. And the public/private rule enforcement seems to be:

  • You get an error if you write the name of a private class anywhere in your client source
  • If you just use type inference to use the object, and avoid ever explicitly writing the class name in your source code, it compiles and works fine.

So the following code works:

myPublicObject.setX(myPublicObject.getX());

but the following code doesn’t:

PrivateObject x = myPublicObject.getX();
myPublicObject.setX(x);

And the reason the first line works is that, although the code is clearly using PrivateObject instances, it doesn’t ever use the word “PrivateObject” in the source code.

Surely, whether you explicitly reference the class in your code, or implicitly using the language’s type inference, are just syntactic differences only, and you should either be allowed to do both or neither.

(In .NET, the equivalent code does indeed not compile.)

Don’t use the @author Javadoc tag

Friday, September 3rd, 2010

In Javadoc there is an @author tag so you can specify who originally wrote the class, method, etc., being documented.

/**
 * This represents a user of the system as stored in Oracle.
 * @author Adrian Smith
 */
class User { ... }

But really, what’s the point, when version-control tools such as “svn log”, “svn blame” and exist? (And any project where it would be necessary to determine the author necessarily involves more than one person, any (at least) any project involving more than one person requires a version control system.)

  • The information in version-control log is always accurate
  • The information in the source file might originally have been accurate, but the class may have been heavily refactored by someone else
  • Some people start classes by copy/pasting another file and changing it: the tag will be wrong in those cases (the people who do that aren’t going to be the people who read/write/update doc)

I suppose there could be a case for using @author in the cases that the source is distributed without any version control information. But at least on the projects I work on, that’s never the case.

The project I’m currently working on has random @author tags all over the place, due to various copy/paste action and refactoring. The @author tag bears no relation to the person who last changed the code, who knows about it, or even who’s still in the company. Wrong documentation is worse than no documentation, as you might be tempted to believe wrong documentation.

Checked exceptions and Java Callables

Thursday, August 19th, 2010

Java supports checked exceptions. Many people have strong opinions about if they are good or bad. I believe they are good, but let’s agree that Java has them and they’re not going away.

(Any exception extending “Exception”, which can to be thrown from a method, must be declared at the end of method’s signature, and any caller of the method must handle the exception or itself declare to throw that type of exception; Any exception extending “RuntimeException” need not be declared on method signatures. A programmer is free to choose which superclass to extend when designing their own exceptions.)

There are two ways of dealing with tasks which should be run in the future, both of which are very inelegant w.r.t. checked exception handling.

  • Runnable – the task (method) may not throw any checked exception, as the “run” method does not declare any checked exceptions (as “Runnable” defines the method; and the interface, provided by Java, cannot know what exceptions your code may throw)
  • Callable – “Solves” the problem with Runnable in that the task/method may throw a checked exception. To achieve this the interface declares “throws Exception” meaning any checked exception may be thrown. This means the caller must handle “catch Exception” i.e. handle all checked exceptions, which again gives you no safety as to which exceptions can actually be thrown (the purpose of checked exceptions in the first place)

(In addition, the difference between these two interfaces is solely the way they deal with exceptions. But you wouldn’t know that, or know which interface uses which strategy, by looking at their name!)

What one would need would be to extend the generics system to deal with exceptions. For example:

interface Callable<V,E> {
    V call() throws E;
}

class MyException extends Exception { .. }

class MyCallable implements Callable<MyObject, MyException> {
    MyObject call() throws MyException {
        throw new MyException(); // ok to throw, signature declares it
    }
}

void usingCallable(MyCallable e) {
    e.call(); // error: must catch MyException
}

The generic parameter “E” would have to be a list of exception classes as opposed to just one class.

Update: I was surprised to find out that using generic parameters for checked exceptions is basically supported! However it still isn’t very useful, as:

  • There is no way for the generic parameter E to be a list of exceptions
  • Callable/Runnable interfaces provided by Java do not support it
  • All the useful ThreadPool code that comes with Java support only Callable/Runnable

Java is lacking a String “join” function

Friday, April 16th, 2010

Between Java 1.0 and Java 1.3 (1996-2002 according to Wikipedia) there was no way to split strings into an array or a list.

In Java 1.4 the authors of Java saw it fit to introduce a method to split strings,

String csvData = "field1,field2,field3";
String[] fields = csvData.split(",");

However they did not introduce a method to “join” strings! Even in Java 7 there is no way to do this, e.g. via a static String.join method (2002-now).

OK I realize this is not “rocket science”, and I appreciate it exists in various versions in various third-party libraries, but still, it’s something every program needs to do at some point, it’s annoying to have to re-define it or think about it for each application.

For example, in one project I was working on in the last 6 months, such a function was created, and then had a bug! (OK but to be fair, that was not the only bug in the application!)

Come on, I mean this is a totally trivial function, totally necessary, available in all scripting lanuags why is it still not in Java?!

(P.S. Want to see an “enterprise java” solution to this problem? Check out the number of methods on this class)

Java varargs: inconsistent behaviour if you pass an array

Thursday, April 15th, 2010

In Java 1.4 there was the function Arrays.asList. You could pass it an array and it would make a list out of it.

String[] myArray = new String[] { "foo", "bar" };
List myList = Arrays.asList(myArray);

In Java 1.5 this was retrofitted for varargs; you could simply pass elements to the function

List<String> myList = Arrays.asList("foo", "bar");

I never really understood how that worked in a backwards-compatible way; I mean either the function takes an array of stuff, or it takes individual elements, surely?

It turns out, that with the varargs syntax, the caller is not forced to pass individual elements, the caller can instead pass an array of elements.

List<String> myList = Arrays.asList("foo", "bar");
List<String> myList = Arrays.asList(new String[] { "foo", "bar" });

The above two calls are identical, both return a List<String>.

But surely this is really dangerous? I mean Arrays.asList does not make any assumptions about what types of arguments it accepts; the list can be composed of any object.

How can it be certain that you want to have an List of Strings, and not a List containing a single element which is a String array? (An array is an object.)

To demonstrate this inconsistency:

String[] arr = new String[] { "foo", "bar" };
Arrays.asList(arr);            // returns List<String>
Arrays.asList(arr, arr);       // returns List<String[]>
Arrays.asList(arr, arr, arr);  // returns List<String[]>

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.

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.

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