Tag Archives: Java

Java Puzzlers: Number.MIN_VALUE

If I asked you what the largest possible Integer in Java is, you would easily answer 2^31-1, or Integer.MAX_VALUE. Smallest possible Integer? Integer.MIN_VALUE, -2^31.

How about a Long? It’s also a Number, and each Number has MIN_VALUE and MAX_VALUE, and you would be right to refer to them.

Obvious and boring, right?

How about a Double then?

It’s also a Number, and so it has Double.MAX_VALUE, and yes that is the maximum. Minimum? Let me go already, obviously Double.MIN_VALUE!

Nope.

I only learned it today even though I’ve been programming Java for years. Double.MIN_VALUE is actually a positive number. Quick look at docs says it all: It is the smallest positive nonzero value of type double. If you’re really looking for the smallest value of Double, you need to refer to Double.MIN_NORMAL.

Yes, docs are very clear about it. Yes, it is a static constant, so LSP does not really apply (as if Java didn’t violate it all the time). Yet I still think it looks like a duck, it quacks like a duck, but needs batteries. It has different semantics for no good reason, does not follow the principle of least surprise and is plain unintuitive. I add it to my shelf of quirks along with half of Swing, everything around Dates and Calendars, equals and… what am I still doing here by the way?

Integrating Spring, Velocity and Tiles

I like Tiles and I heard a lot about Velocity. They seem to serve different purpose and reportedly are easily married together, so I decided to give it a shot and use them both in Spring web app. The integration actually took many hours and was a real rollercoaster during which I learned a lot about all three technologies. Hopefully this post can spare someone this fun and let them focus on business.

Goals

When I use tiles, I don’t like the default (?) approach of tiles.xml. I don’t want to put imports of JS & CSS, page title, navigation, body etc. each in its own file like in the snippet below, because that makes me switch between editor windows.

<definition name="hello" template="/WEB-INF/templates/main.jsp">
	<put-attribute name="title" value="Hello" type="string" />
	<put-attribute name="head" value="/WEB-INF/templates/hello-js-and-css.jsp" />
	<put-attribute name="nav" value="/WEB-INF/templates/hello-nav.jsp" />
	<put-attribute name="body" value="/WEB-INF/templates/hello.jsp" />
</definition>

Obviously I don’t want to put too much detail in tiles.xml, either.

What I really like is having one file per page, assembling the template in one place, such as this piece of JSP:

<tiles:insertTemplate template="template.jsp">
	<tiles:putAttribute name="title" value="Hello" />
	<tiles:putAttribute name="head">
		<script type="text/javascript" src="/js/jQuery.js" />
		<script type="text/javascript" src="/js/hello.js" />
	</tiles:putAttribute>
	<tiles:putAttribute name="body">
		<div>Hello, world!</div>
	</tiles:putAttribute>
</tiles:insertTemplate>

In Velocity, it’s supposed to look like this:

#tiles_insertTemplate({"template": "template.vm"})
	#tiles_putAttribute({"name":"title", "value": "Hello"})#end
	#tiles_putAttribute({"name":"head"})
		<script type="text/javascript" src="/js/jQuery.js" />
		<script type="text/javascript" src="/js/hello.js" />	
	#end
	#tiles_putAttribute({"name":"body"})
		<div>Hello, world!</div>
	#end
#end

However, the docs on integration are really intended for adding some Velocity support to your Tiles-based app, while I wanted quite the opposite: Use Tiles in my rich Velocity app, with full support for spring context, macros etc.

Solution

In short, what we’re going to do is:

  1. Use VelocityViewResolver to resolve and render pages
  2. Add support for Tiles macros to this Velocity rendering engine
  3. Extend the Tiles renderer with full support for Velocity, including Spring context, macros etc. Ultimately we’re going to make it use the original Velocity engine created by Spring.

Full source code in form of a minimal, complete web app are at github. For details see below.

Spring & Velocity -> Tiles

For the first step, we define viewResolver and velocityConfig like this:

@Bean
public VelocityConfig velocityConfig() {
	VelocityConfigurer cfg = new VelocityConfigurer();
	cfg.setResourceLoaderPath("/WEB-INF/velocity/");
	cfg.setConfigLocation(context
			.getResource("/WEB-INF/velocity.properties"));
	return cfg;
}

@Bean
public ViewResolver viewResolver() {
	VelocityViewResolver resolver = new VelocityViewResolver();
	resolver.setViewClass(VelocityToolboxView.class);
	resolver.setSuffix(".vm");
	return resolver;
}

It’s important that we use VelocityToolboxView there, otherwise the tiles directives won’t work.

We also need to put the following in velocity.properties:

userdirective=org.apache.tiles.velocity.template.AddAttributeDirective,\
  org.apache.tiles.velocity.template.AddListAttributeDirective,\
  org.apache.tiles.velocity.template.DefinitionDirective,\
  org.apache.tiles.velocity.template.GetAsStringDirective,\
  org.apache.tiles.velocity.template.ImportAttributeDirective,\
  org.apache.tiles.velocity.template.InsertAttributeDirective,\
  org.apache.tiles.velocity.template.InsertDefinitionDirective,\
  org.apache.tiles.velocity.template.InsertTemplateDirective,\
  org.apache.tiles.velocity.template.PutAttributeDirective,\
  org.apache.tiles.velocity.template.PutListAttributeDirective

This adds basic support for Tiles directives to Velocity, but it’s still useless because once Velocity hands rendering over to Tiles, Tiles is unable to render Velocity and would simply ignore it (rendering syntax of #directives to browser.

Tiles -> Velocity

We need to teach Tiles to use Velocity. For this we’re going to need a custom TilesInitializer:

@Bean
public TilesConfigurer tilesConfigurer() {
	TilesConfigurer cfg = new TilesConfigurer();
	cfg.setTilesInitializer(new VelocityTilesInitializer(velocityConfig()));
	return cfg;
}	
public class VelocityTilesInitializer extends DefaultTilesInitializer {
	private VelocityConfig velocityConfig;

	public VelocityTilesInitializer(VelocityConfig velocityConfig) {
		this.velocityConfig = velocityConfig;
	}

	@Override
	protected AbstractTilesContainerFactory createContainerFactory(
			TilesApplicationContext context) {
		return new BasicTilesContainerFactory() {

			@Override
			protected List<TilesRequestContextFactory> getTilesRequestContextFactoriesToBeChained(
					ChainedTilesRequestContextFactory parent) {
				List<TilesRequestContextFactory> factories = super
						.getTilesRequestContextFactoriesToBeChained(parent);
				registerRequestContextFactory(
						VelocityTilesRequestContextFactory.class.getName(),
						factories, parent);
				return factories;
			}

			@Override
			protected AttributeRenderer createTemplateAttributeRenderer(
					BasicRendererFactory rendererFactory,
					TilesApplicationContext applicationContext,
					TilesRequestContextFactory contextFactory,
					TilesContainer container,
					AttributeEvaluatorFactory attributeEvaluatorFactory) {
				ContextPassingVelocityAttributeRenderer var = new ContextPassingVelocityAttributeRenderer(
						velocityConfig.getVelocityEngine());
				var.setApplicationContext(applicationContext);
				var.setRequestContextFactory(contextFactory);
				var.setAttributeEvaluatorFactory(attributeEvaluatorFactory);
				var.commit();
				return var;
			}
		};
	}
}

We’re almost there, but here’s a tricky bit. Normally in lines 31-32 you would put velocityAttributeRenderer. However, this renderer completely ignores the Spring-augmented Velocity context & engine that Tiles received from Velocity. It creates its own VelocityEngine and lets it do the rendering, throwing away all the Spring and tiles directives and context objects.

There is no way to change this behavior in Tiles (which otherwise seems to be an interesting study in design patterns and extensibility). I even created two JIRA issues for it: 541 for forwarding context and 542 for injecting VelocityEngine.

Meanwhile, we have to make do with this workaround (see github for full source):

public class ContextPassingVelocityAttributeRenderer extends
		AbstractTypeDetectingAttributeRenderer {
	// ...

	private VelocityEngine engine;

	public ContextPassingVelocityAttributeRenderer(VelocityEngine engine) {
		this.engine = engine;
	}
	
	// ...

	public void commit() {
		velocityView = new VelocityView(new TilesApplicationContextJeeConfig());
		velocityView.setVelocityEngine(engine);
	}

	@Override
	public void write(Object value, Attribute attribute,
			TilesRequestContext request) throws IOException {
		if (value != null) {
			if (value instanceof String) {
				InternalContextAdapter adapter = (InternalContextAdapter) ((VelocityTilesRequestContext) request)
						.getRequestObjects()[0];
				Context context = adapter.getInternalUserContext();
				Template template = velocityView.getTemplate((String) value);
				velocityView.merge(template, context, request.getWriter());
			} else {
				throw new InvalidTemplateException(
						"Cannot render a template that is not a string: "
								+ value.toString());
			}
		} else {
			throw new InvalidTemplateException("Cannot render a null template");
		}
	}
	
	// ...

It works arounds both of the JIRA issues and lets us accomplish the ultimate goal:

  1. The VelocityEngine injected to VelocityView here is the original VelocityEngine from Spring. Among other things, it supports Spring directives and context-dependent tools.
  2. The TilesRequestContext in write method still contains the original Velocity context created from Spring scaffolding. Standard implementation of VelocityAttributeRenderer simply throws it away. This workaround above extracts the original context and uses it for rendering.

Conclusion

This journey took much more time than I thought. Documentation on such cases is nonexistent, so I spent hours debugging, reading source code, experimenting, praying and cursing. It was even more fun as I had close to zero knowledge of internals of Spring view resolution and rendering engine, as well as Tiles and Velocity.

It’s quite satisfying since I learned a ton about all those technologies and eventually was able to resolve it in a fairly elegant way. But it was also a frustrating and time-consuming riddle and I hope this post spares someone some trouble.

Update – Velocity Tools

A while later I discovered this solution does not support Velocity Tools property. Here’s how to add it: Spring & Velocity Tools.

Careful with that PrintWriter

Let’s assume we have a nice abstraction over email messages simply called Email. Something that can write itself to Writer and provide some other functionality (e.g. operating on the inbox).

Now, take this piece of code:

public void saveEmail(Email email) {
	FileOutputStream fos = null;
	try {
		fos = new FileOutputStream("file.txt");
		PrintWriter pw = new PrintWriter(fos);
		email.writeContentTo(pw);
		pw.flush();
		email.deleteMessageFromInbox();
	} catch (IOException e) {
		log.error("Saving email", e);	
	} finally {
		IOUtils.closeQuietly(fos);
	}
}

Question: What happens if for whatever reason the PrintWriter cannot write to disk? Say, your drive just filled up and you can’t squeeze a byte in there?

To my surprise, nothing got logged, and the messages were removed from inbox.

Unfortunately, I learned it the hard way. This code is only a piece of a larger subsystem and it took me quite a while to figure out. Used to dealing mostly with streams, I skipped this area and checked everything else first. If PrintWriter was like a stream, it would throw an exception, skipping deleteMessageFromInbox.

All streams around files work like that, why would this one be different? Well, PrintWriter is completely different. Eventually I checked its Javadoc and saw this:

“Methods in this class never throw I/O exceptions, although some of its constructors may. The client may inquire as to whether any errors have occurred by invoking checkError().”

At first I was furious about finding that’s all due to yet another inconsistency in core Java. Now I’m only puzzled and a bit angry. Most things in Java work like this – they throw exceptions on every occasion and force you to explicitly deal with them. And it’s not unusual to see 3 or 4 of them in a signature.

One could say, it’s all right there in the Javadoc. Correct. But still, it can be confusing to have two fundamentally different approaches to error handling in one corner of the library. If one gets used to dealing with one side of it, he may expect the same from the other. Instead, it turns out you always have to carefully look at signatures and docs, because even in core Java there is no single convention.

Related: try/catch/throw is an antipattern – interesting read, even if a bit too zealous.

Java Web Start Bugs: Offline Edition

Java Web Start is full of bugs that never get resolved and make it next to unusable, and very costly, in business environment. If you have thousands of users who tend to cancel update prompts, or whose connections get interrupted, or who are simply unlucky, you are actually scared of releases. And if you try to release often? Yup, you guessed it.

Rant aside.

Recently I was trying to move away from web-based JWS to one that delivers jars and jnlp to the client and installs locally. I found several interesting bugs or quirks that I think are worth posting here.

Shortcut for all users

My first attempt was installing the application for all users from the Internet. To silently install shortcut on desktop for all users, you can add <shortcut> to your jnlp and execute:


javaws -import -system -silent http://example.com/myapp.jnlp

It does place shortcut on desktop for all users. But it doesn’t work!

Unfortunately, by default Java 6 on my Windows 7 has web start cache in C:\Users\Konrad\.... When you try to launch the app from John’s desktop, you get an ugly error because John cannot access that folder. It doesn’t matter that I run the command with -system switch from Administrator’s console. It lands in user-specific, protected directory.

Workaround: Force JWS to use another, accessible to everyone folder for cache.

Place this in C:\Windows\Sun\Java\Deployment\deployment.config:


deployment.system.config=file\:C\:/WINDOWS/Sun/Java/Deployment/deployment.properties
deployment.system.config.mandatory=false

And in C:\Windows\Sun\Java\Deployment\deployment.properties:


deployment.system.cachedir=C\:\\JavaWebStart
deployment.system.cachedir.locked=true

Offline installation and updates

Specification changed a bit and I researched purely “offline” solution. Place all files in a directory and install from there. Push updates with the same mechanism. In other words, use local file system for codebase and never ask JWS to look online. Official documentation advertises it as “CD installation”.

My JNLP starts with:


<jnlp codebase="file:/c:/myapp/" href="my.jnlp">

Files reside in C:\myapp and I install the app with:


javaws -import -system -silent file:/c:/myapp/my.jnlp

What could possibly go wrong?

Bug 1: You cannot change code if application is running

With web-based JWS, you can update your codebase anytime. Web Start keeps copies of the files in local cache and safely launches the application off that copy. Obviously.

Unfortunately, with local codebase it tries to be smart and does not copy to cache. Now, if you try to update by overwriting contents of C:\myapp while the application is running, it will die with a flood of ClassNotFoundExceptions in log. Oops.

Solution: None, sadly. Don’t update if the application is running. Period.

Bug 2: Curious “do you want to go online” message

OK, so I decided to update only when the application is not running.

Suppose John is running version 3.0.1. He closes the application. Now your smart updater overwrites contents of C:\myapp with 3.0.2. When John launches the application again, he may see a message requesting going online for an update because JNLP has changed.

This will happen if your <shortcut> is set for online="false".

That is plain wrong. My codebase is local, every single thing is local, and the user is bothered with a popup about going online. Then if I accept to “go online”, it innocently informs that it’s downloading update from file:/c:/...

Solution: Use <shortcut online="true">. Then it will always assume the application is “online” and therefore skip asking for permission to go online.

Bug 3: Update reinstalls app and removes shortcut

Remember, I am trying to maintain shortcut for all users at all times.

Now, if you update the application by simply overwriting contents of codebase directory, you’re in for another curiosity. On launch JWS will remove app from system cache and remove shortcuts from all desktops, and reinstall the application into this user’s cache. Others lose the shortcut for good.

Workaround: Reinstall the application into system cache yourself.

  1. javaws -uninstall file:/c:/myapp/my.jnlp
  2. Place new files in C:\myapp
  3. javaws -import -system -silent file:/c:/myapp/my.jnlp

Final rant

Every single time I deal with web start, it bites and makes me weep and gnash my teeth. I spent hours figuring all this out and fighting JWS who fought me back. As I deal with it I find some comfort researching the web and finding other desperate developers coping with similar issues. I hope this post saves someone some pain.

Fill and Print an Array in Clojure

In a post in the “Extreme OO in Practice” series (in Polish), Koziołek used the following example: Fill a 3x3x3 matrix with subsequent natural numbers and print it to stdout.

The example in Java is 27 lines of code (if you remove comments). It is later refactored into 55 lines that are supposed to be more readable, but personally I can’t help but gnash my teeth over it.

Anyway, shortly after reading that example, I thought of what it would look like in Clojure. Here it is:

(def array (take 3 (partition 3 (partition 3 (iterate inc 1)))))
(doall (map #(doall (map println %)) array))

That’s it. I know it’s unfair to compare this to Java and say that it’s shorter than your class and main() declaration. But it is, and it makes the full-time Java programmer in me weep. Anyway, I have two observations.

As I like to point out, Java is awfully verbose and unexpressive. Part of the story is strong typing and the nature of imperative programming. But then again, sometimes imperative programming is very clumsy.

Secondly, this solution in Clojure presents a completely different approach to solving the problem. In Java you would declare an array and then iterate over it in nested loops, incrementing the “current value” in every innermost iteration. In Clojure, you start with an infinite sequence of lazy numbers, partition (group) it in blocks (that’s one row), then group those blocks into a 2D array, and take 3 of those 2D blocks as the final 3D matrix. Same thing with printing the array. You don’t iterate over individual cells, but naturally invoke a function on a sequence.

The difference is subtle, but very important. Note how the Java code needed 4 variables for the filling (“current value” and 3 indexes) and 3 indexes for printing. There was a very clear distinction between data and what was happening to it. In Clojure you don’t need to bother with such low-level details. Code is data. Higher-order functions naturally “serve as” data in the first line, and are used to iterate over this data in the second.

Java Does Not Need Closures. Not at All.

I hope that most Java developers are aware of the Swing threading policy. It makes sense, except for that it’s so insanely hard to follow. And if you do follow it, I dare say there is no place with more ridiculous boilerplate.

Here’s two examples that recently got me scratching my head, gnashing my teeth, and eventually weep in disdain.

Case One: Display Download Progress

class Downloader {
    download() {
        progress.startDownload();
        while(hasMoreChunks()) {
            downloadChunk();
            progress.downloadedBytes(n);
        }
        progress.finishDownload();
    }
}

class ProgressDisplay extends JPanel {
    JLabel label;
    startDownload() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                label.setText("Download started");
            }
        });
    }
    downloadedBytes(int n) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                label.setText("Downloaded bytes: " + n);
            }
        });
    }
    finishDownload() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                label.setText("Download finished");
            }
        });
    }
}

Solution? Easy! Just write your own JLabel wrapper to hide this mess. Then a lengthy JTable utility. Then a JProgressBar wrapper. Then…

Case Two: Persist Component State

Task: Save JTable state to disk. You’ve got to read table state in EDT, but writing to disk from EDT is not the the best idea.

Solution:

ExecutorService executor = Executors.newSingleThreadExecutor();

void saveState(final Table table) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            TableColumns state = dumpState(table);
            executor.execute(new Runnable() {
                public void run() {
                    saveToDisk(table.getTableKey(), state);
                }
            });
        }
    });
}

Two inner classes, inheritance, all those publics and voids and parentheses. And there is no way to avoid that!

In a sane language, it could look like:

(defn save-state [table]
  (do-swing
    (let [state (dump-state table)]
      (future (save-to-disk table state)))))

All semantics. Little ceremony, almost no syntax. If you counted characters in both solutions, I guess the entire second snippet is as long as the first one somewhere to the invocation of invokeLater. Before you get to the actual logic. No strings attached, do-swing and future are provided by the language or “official” utils.

Bottom Line

I recently saw two presentations by Venkat Subramaniam on polyglot programming where he mercilessly made fun of Java. In his (vaguely remembered) words, when you write such code for the whole day, you come back home and weep. You can’t sleep because you’re tormented by the thought of the abomination you created, and that you will have to deal with tomorrow. If your children asked you what do you for living, would like them to see this?

Hibernate Cache Is Fundamentally Broken

Simple as the title says, I dare say Hibernate second level (L2) cache is fundamentally broken. At least with clustered cache, which appears to be supported from the official docs.

There are two strong reasons for clustering, that is spreading your load over multiple servers: Scaling out and availability.

What does availability mean? Among other things, zero downtime on updates. You take one server down, update, start it up and then continue with the next. With reasonable load balancer, proxy, middleware or what have you, the clients won’t notice a thing and be seamlessly redirected to whichever server is up at the moment.

Now, what if during an update you change definition of an entity? Add or remove a field? You have old servers with old definition, updated servers with new definition, all sharing the same clustered cache. Java has serialVersionUID for it. If you serialize an object, and then deserialize it on another node with a different version, it will fail with an exception.

Since Hibernate openly advertises clustered caching, one would expect it to work just fine with this case. Unfortunately, this is not so.

What Hibernate puts in cache is a plain old array of values of individual fields. That is submitted to clustered cache. Then a node with different version loads this array from cache and tries to populate entity with different definition with it, simply copying field by field by their numeric index.

When that happens, you’re screwed.

Suppose you have this entity definition:

class User {
  int id;
  String password;
  String email;
  String login;
}

… and you’re updating to this:

class User {
  int id;
  String password;
  Timestamp passwordExpires;
  String email;
  String login;
}

The best thing that can happen is an outage. For instance, the 3rd field used to be a String. You added a Timestamp field before it and in the new definition the 3rd field is a Timestamp. Hibernate on new nodes fails on load() with ClassCastException from String to Timestamp, because cache still has the old definition.

The much worse case is data corruption. Suppose you need a User for the following transaction:

User user = session.load(User.class, 4);
user.setPasswordExpires(...);
session.update(user);

Let’s say that email was null. load() does not yield a ClassCastException, because null is a perfectly valid Timestamp. But when Hibernate loads such entity from cache, the cached entry only has 4 fields. Login is not restored and remains null. When you update(), you’re doomed. In this made up example here this would hopefully fail on a DB not-null constraint. In real life, though, it can silently save corrupted data in database and guarantee hours of very interesting debugging and restoring from backups, if not physical damage caused by your application’s misbehavior.

There’s this old piece of music called “Careful with that Axe, Eugene”. If you don’t know it, don’t bother googling. Don’t even get me started about YouTube, it needs proper sound setup and dynamics. So, here’s how it goes. Apparently boring, monotonic bass softly playing “bing, bang, bing, bang” (or D, D, D, D as Wikipedia says). Nothing happens for a few minutes, except for just as soft ambientish keyboard tones. And so on for one minute, another, then another. Then, out of the blue, an air-shattering scream. For the first time in my life I heard it in Australians’ concert, and it literally made me jump with a shot of adrenaline and panic.

That’s the experience with clustered cache and Hibernate. It’s very robust and stable. Boring. Unnoticeable. Until one day it makes you scream hard and tear your hair out.

Handle with care. Be ware. Be prepared.

Little piece of disclaimer: I don’t know if this exact example here reproduces the problem. It’s merely a made up illustration. The fields might be ordered by name, and Hibernate may refuse to restore from an array that has fewer fields than the current definition. But I have witnessed both issues in real life, and they caused much pain and cost time and money.

Don’t Rely on Autoboxing in Java

Question: What does the following code display?

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

public class Demo {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    JLayeredPane container = new JLayeredPane();
    frame.setContentPane(container);

    JPanel bottom = new JPanel();
    bottom.setBounds(0, 0, 400, 200);
    bottom.setBackground(Color.WHITE);
    container.add(bottom); // default level is 0

    JLabel intLabel = new JLabel("I'm an int");
    intLabel.setBounds(0, 10, 400, 30);
    int layer = 10;
    container.add(intLabel, layer);

    JLabel integerLabel = new JLabel("I'm an Integer");
    integerLabel.setBounds(0, 50, 400, 30);
    container.add(integerLabel, new Integer(10));

    JLabel literalLabel = new JLabel("I'm a literal");
    literalLabel.setBounds(0, 100, 400, 30);
    container.add(literalLabel, 10);

    JLabel longLabel = new JLabel("I'm a long");
    longLabel.setBounds(0, 150, 400, 30);
    container.add(longLabel, new Long(10));

    frame.setSize(400, 200);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }
}

Answer

I'm an Integer

Explanation

If you open docs for JLayeredPane, you can see the following code snippets:

layeredPane.add(child, new Integer(10));
layeredPaneParent.setLayer(child, 10);

You can see Integer there and literal 10 here. Subconsciously, you think: who cares, 10 is the same thing as new Integer(10) because Java has autoboxing, right? WRONG!

The only right way to interact with layeredPane.add is an Integer that you box yourself. Let’s take a peek at its source code…

protected void addImpl(Component comp, Object constraints, int index) {
    int layer = DEFAULT_LAYER.intValue();
    int pos;

    if(constraints instanceof Integer) { // A-ha!
        layer = ((Integer)constraints).intValue();
        setLayer(comp, layer);
    } else
        layer = getLayer(comp);

    pos = insertIndexForLayer(layer, index);
    super.addImpl(comp, constraints, pos);
    comp.validate();
    comp.repaint();
    validateOptimizedDrawing();
}

Ironically, even though it uses int internally, it wouldn’t recognize it as a parameter.

Conclusion

Autoboxing works, except for when it doesn’t. Be defensive with APIs (even core Java) and when something is wrong do try all those ideas that seem obviously crazy at first. When writing your own API that uses type identification, remember that int and Integer are completely different beasts and both need to be included.

This example is from Swing, but it can happen anywhere. I’ve tripped on this issue before when I was implementing a CRUD framework or renderers, but did not expect it in core library.

Update

As frimble pointed out at reddit, there is one more reason why it would never work. In addition to add(Component comp, Object constraints), Container also has add(Component comp, int index).

Having two overloaded versions of a method, one of them accepting Integer and another for int, when both do completely different things, is even worse than what I criticized in the first place.

Rant: Yet another example of extremely poor design in core Java API. Just like Object.equals() having specification that’s impossible to meet in a reasonable way or the hierarchy of java.util.Date. They use Java to teach OOP. Apparently it’s just as good for teaching how NOT to program.

33rd Degree Conference

This April I’m going to attend the first eddition of the 33rd Degree Conference in Kraków. Not only does it have an exceptional theme (check out the web page!), but also has attracted several interesting speakers.

For some reason I am most interested in the non-Java talks and workshops given by Neal Ford (The Productive Programmer, Functional Thinking (hey, Clojure!) and Abstraction Distractions) and Linda Rising (Deception and Estimation). If there was a “Productivity and Psychology for Developers” conference, I would be the first to sign up for it.

Then there is a promising talk by Michael Nygard on scalability, as well as two sessions by Matthew McCullough on Git and Hadoop (both high on my to-learn list). Last but not least, a whole lot of more or less predictable talks on Java (mostly but not only EE).

I wish there was more Clojure and less Groovy on the schedule. Maybe next year. Anyway, the agenda is packed with interesting events and I expect it to be three very interesting and productive days.

Clojure vs. Java: The Beauty of Conciseness

I decided to take up something completely new: Functional programming in Clojure. It’s far from being the most popular tech on the market, but on the other hand it’s a chance to experience something completely new that might come in handy in future.

One of the first striking observations is how concise it is compared to the old, heavy and static languages. Here’s an excersise: Write a function that flattens a list of objects.

Here’s what it looks like in Java (24 lines, 543 characters):

import static java.util.Arrays.asList;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Hello {
  private static List<Object> myFlatten(Object in) {
    if (in instanceof List<?>) {
      List<Object> out = new ArrayList<Object>();
      for (Object obj : (List<?>) in) {
        out.addAll(myFlatten(obj));
      }
      return out;
    } else {
      return Arrays.asList(in);
    }
  }

  public static void main(String[] args) {
    System.out.println(myFlatten(asList(1, asList(2, 3, asList(3,
      asList(asList(3)))))));
  }
}

Now compare that to Clojure (6 lines, 141 characters):

(defn my-flatten [v] 
  (if(sequential? v)
    (vec (apply concat (map my-flatten v)))
    [v]))

(println (my-flatten [1 [2 3 [3 [[3]]]]]))

In this case Java is awfully verbose. Some of it is related to static typing. That’s fine, we know how useful it becomes as the amount of code grows.

However, even in this trivial example the functional approach and Clojure show their strengths. All the interesting logic resides in this single line:

(apply concat (map my-flatten v))

That has little to do with static typing or richness of Clojure’s standard library. It owes to the functional approach and closures

How simple and readable is that?