Friday, June 4, 2010

Invoking Maven and having it ignore your local settings

I recently found myself working remotely from my network and needed to perform a build using Maven. My ~/.m2/settings.xml file is configured with information about my network's Nexus repository and a few other things. I therefore needed to find a way to tell Maven to ignore my regular settings; preferably without mutating my settings.xml file. In particular I just wanted to have Maven pull out a plugin from the Central repo.

The documentation on the Maven command doesn't mention how it can be invoked to ignore your settings.xml. However if you type the following then it will ignore it (in my case I wanted to download the wonderful Cobertura plugin and produce a code coverage report) :

mvn -s/dev/null cobertura:cobertura

All good.

Wednesday, May 12, 2010

Flash on the iPhone

Given Steve Job's most recent letter concerning Flash on the iPhone, I'd like to broaden the debate to native plugins on the iPhone. Mr. Jobs provides a host of reasons why Flash is not permitted and it reminds me largely of his previous argument around needing native applications on the iPhone (remember that they encouraged us to create nice web apps instead at first; then there was the whole multi-tasking debate..).

There reaches a point with web applications where HTML, Javascript and CSS just can't do what you need them to do. These technologies have come an awful long way and HTML5 in particular is great. I spend a lot of time with these technologies and they are top of mind when considering new applications.

Let's take a concrete example of when you do require a plugin: Google Earth. Google Earth exists as a web plugin as well as a standalone executable. There are times when you'd like to embed Google Earth in a web page given its 3D capabilities; that's why the plugin exists of course!

Another example is with our own web plugin; it is something similar to Google Earth and has advanced capabilities with regards to map projections. We rely on third party C++ libraries and we utilise OpenGL.

Actually I think when it comes to 3D and the use of, say, OpenGL, web technologies fall short. There is a Mozilla proposal to expose OpenGL ES to Javascript, and that's great, but ES doesn't provide full OpenGL capability. Believe me, there are times when you need full OpenGL capability.

If I thought about it I'm sure there are other applications with dependencies such that you need to go native with a web plugin; not often perhaps, but we need to leave the native plugin door open for these situations.

I think Mr. Jobs has his reasons for not supporting Flash, but that's a separate consideration to supporting native web plugins.

In the end, I think that Adobe and Apple will come to an agreement and Adobe will release a well written and performant Flash plugin. The rest of us will then be able to install and write plugins for the iPhone when they are required.

Friday, April 16, 2010

Spring PropertyEditor for JSON map and array properties

I'm a big fan of Spring but found that it does not support map and list expressions in a property file to be substituted when using a PropertyPlaceholder. So I rolled my own PropertyEditor and can now express a map using JSON in my properties file e.g.:

myMapProperty ={"en-AU": "SKY", "ms": "SKY"}

Here's the property editor (depends on json-lib):

package <packagename>;

import java.beans.PropertyEditorSupport; 

import net.sf.json.JSON;
import net.sf.json.JSONSerializer;

/**
* Converts JSON expressions to Java arrays or maps and vice versa.
*
* @author huntc
*
*/
public class JSONPropertyEditor extends PropertyEditorSupport {

@Override
public String getAsText() {
Object object = getValue();
JSON jsonObject = JSONSerializer.toJSON(object);
return jsonObject.toString();
}

@Override
public void setAsText(String text) {
JSON json = JSONSerializer.toJSON(text);
setValue(json);
}
}

and here's what you must declare in your spring configuration xml:

<bean id="customEditorConfigurer"
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Map">
<bean class="<packagename>.JSONPropertyEditor" />
</entry>
</map>
</property>
</bean>

The above indicates that for any required substitution of a map, use my property editor e.g.:

<bean id="someBeanWithAMapProperty"
class="someClass">
<property name="someMapProperty"
value="${myMapProperty}" />
</bean>

 

Tuesday, April 13, 2010

iPhone and multitasking

So here we are. Apple appears to be finally opening up the threading APIs to developers on the iPhone.

I've had numerous conversations with colleagues since the iPhone came out and they've been all sorts of reactions as to why there's no multithreading. Actually, now that I've just typed multithreading let's get this straight. Multitasking relates to the human experience of doing multiple things at the same time; it is a use-case; it is something that I've been told (by my wife) that men can't do and women can (!).

Multithreading is the ability for an OS to cooperatively or pre-emptively (generally the latter) slice processor time between different paths of execution within and outside of a number of processes (generally applications).

The iPhone has supported multitasking and multithreading forever. The difference now is that Apple appears to have opened up the multithreading API to non-Apple developers. I've not seen the details on this, perhaps they've constrained the thread APIs in some interesting way with the goal of limiting battery usage, but it is a very good (and necessary) thing that there will now be multithreading.

One application that I'm really looking forward to using is Skype. Finally, we'll be able to receive Skype calls with the same experience of receiving regular mobile calls; so long as you're on a WiFi network of course. I think that this will be amazing as I'm never near my computer when someone wants to contact me via Skype. However, I always have my iPhone at hand of course.

I can't wait for SIP supporting applications to come along for the iPhone either. The prospect of receiving my home phone calls when away from home via VOIP is fantastic.

Oh and one thing I'd like to joyfully throw back at the multithreading doubters: get over it. Yes, multithreaded programming is harder but its just the way the world is. Multiple things happen at the same time. Embrace it.

Well done Apple. I look forward to iPhone 4.0.

Monday, April 12, 2010

The pitfall of setting a list of parameters on a JQL query

I recently had a need to provide a collection as a parameter to a JQL IN expression. This is what I did:

List results = getJpaTemplate()
.find(
"from AbstractEvent e "
+ "where "
+ "(e.subscription, e.eventTime) in "
+ "(select e.subscription, max(e.eventTime) "
+ "from e "
+ "where "
+ "e.class in "
+ "(SentSMSFlightSubscribed,"
+ " ReceivedSMSFlightUnsubscribe) and "
+ "e.subscription.flightNo in (?) and "
+ "e.subscription.scheduled = ? "
+ "group by e.subscription)",
renderedFlight.getFlights(),
renderedFlight.getScheduled());

The problem with the query is that you get a class cast exception when an attempting to substitute the collection (renderedFlight.getFlights) .

To fix this you simply need to be explicit about the parameters:

    + "e.subscription.flightNo in (?1) and "
+ "e.subscription.scheduled = ?2 "

Problem solved.

Updated: Sunday 11 July 2010: Even using position parameters doesn't always work. While it works in the above example it didn't work for me when using a parameter of a non-primitive type; at least I think that was the issue. So in a nutshell, if the above doesn't work for you then just use findByNamedParams instead.

You may also note this beauty of a line:

e.class in (
SentSMSFlightSubscribed,
ReceivedSMSFlightUnsubscribe)

That is how you perform an "instanceof" style of operation in JQL. Nice.

 

Sunday, February 28, 2010

Java's Swing framework for Javascript and Canvas

It is 0051 on Sunday morning and I just had a wild thought...

I've been developing applications in Javascript using jQuery and taking an interest in Sproutcore. I love jQuery but most definitely subscribe to Sproutcore's architecture where it makes a very strong statement about web applications being distinct from web documents (there is a place for both).

...and then it occurred to me... why not try and implement Java's Swing framework in Javascript and use the Canvas element almost exclusively for web applications? Do away as much as possible with CSS and HTML - I don't think they're great for web applications anyhow...

I don't doubt that it'd be a lot of work implementing Swing in Javascript, but there's an awful lot of design to be leveraged there.

I think I'll sleep on it...

Wednesday, February 17, 2010

Does Grails lower the barriers of entry to programming?

Grails is the Groovy equivalent of Ruby on Rails and I've been working with Grails for the past couple of months.

I'm a big fan of programming by convention and adopted Apache Maven many moons ago for just this reason. Grails also promotes programming by convention and by and large its quite reasonable for building server hosted web applications.

However one thing in particular has been bothering me. It seems that there is a view that Grails saves you the trouble of worrying about what goes on underneath it. This attitude is similar to one where using ORMs such as Hibernate save you the need to understand databases.

These attitudes are fraught with dangers as has been beautifully pointed out by Joel Spolsky in his Leaky Abstractions article.

I would agree that Grails can assist in increasing productivity but not at the expense of knowing what goes on under the hood. As Joel puts it, "... the abstractions save us time working, but they don't save us time learning".

Today I came across a Grails situation where I compared a newly instantiated domain object with one obtained through GORM. From my perspective both objects were equivalent as they had the same identifiers. I had wrongly assumed though that GORM had adopted the Hibernate convention of providing hashCode() and equals() on a natural key. Because Grails does all this magic for me, I had just assumed that this would be done. Well, it doesn't; and that's fair enough; how would GORM know what the natural key is? (declaring the natural key could be a nice feature for GORM). The point is that I could quickly find the problem because I'm familiar with Java/JPA/Hibernate and know that hashCode() and equals() should be provided for natural keys.

My advice is to stay curious. Don't be content with copy and pasting a bit of code you found using Google, seeing it work but not understanding it. This situation will bite you on the bum when your product goes live and you get a problem that you can't diagnose because you don't really understand what the code is doing.

Programming computers is a complex business and that's a fact that should not be avoided. Embrace the complexity.