Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Wednesday, 5 May 2010

ColorLogs log colorizing script - my version

Finally got round to publishing my log colorizing script 'ColorLogs'.

It's available here on GitHub: http://github.com/memorius/colorlogs

This is a perl script intended to have command output piped through it to a terminal, and allows easy creation of new highlighting configurations using simple text matches, globs or regular expressions. See the readme for instructions - very simple to use.

My version started as a fork of v1.1 from here, but I've made numerous improvements since then. It's become an essential tool for me when running ant, maven and various other programs in the terminal.

Please feel free to use it, modify it, etc. You can also send me your custom highlighting config files - I'll be happy to put them in my repository for others to use.

Monday, 1 March 2010

Spring: setting static fields

This is pretty obscure, but I just found this nice trick with Spring framework, for injection of values into static fields: I've been looking for a way to do this for AGES.

What that article doesn't mention, and the key benefit in my project, is that when you use @AutoWired, you can have the Spring-invoked initialization method marked as private, to avoid polluting your public API.

Spring config:
<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <!-- Scan for @Autowired annotations -->
    <context:annotation-config>

    <!-- The instance to be injected into the static field on StaticHub -->
    <bean class="internal.stuff.MyInterfaceImpl" name="myPrecious">

    <!-- The class which will have its static field set via @Autowired -->
    <bean class="very.public.api.StaticHub" name="dummyInstanceOfStaticHub">
</beans>

Java class with static field:
package very.public.api;

import org.springframework.beans.factory.annotation.Autowired;

public final class StaticHub {
    private static MyInterface theStaticInstance;

    /**
     * Note this initialization method is private! No nasty public setInstance method.
     */
    @Autowired(required = true)
    private StaticHub(MyInterface instance) {
        theStaticInstance = instance;
    }

    /**
     * My public API, making the Spring-created instance of MyInterface statically accessible
     */
    public static MyInterface getInstance() {
        return theStaticInstance;
    }
}

This is a big improvement over my previous unsatisfactory solution, which was to use org.springframework.beans.factory.config.MethodInvokingFactoryBean with a public method on StaticHub like this:
<bean name="staticHubInitializer" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="very.public.api.StaticHub.setInstance"/>
        <property name="arguments">
            <list>
                <ref bean="myPrecious"/>
            </list>
       </property>
    </bean>

    public static void setInstance(MyInterface instance) {
        theStaticInstance = instance;
    }
...which is not very pretty.

You can also use @Qualifier to disambiguate if you have multiple beans in your Spring container which implement MyInterface:
import org.springframework.beans.factory.annotation.Qualifier;
...
    private StaticHub(@Qualifier("myPrecious") MyInterface instance) {
        theStaticInstance = instance;
    }

Before you use this, consider carefully whether static fields are actually a good idea - in general this kind of pattern is something Spring is designed to help you avoid!

In my project there are good reasons for it, but it needs thought - things get complicated quickly in environments with multiple classloaders, or with multiple Spring containers inside the same classloader; it also makes it harder to use newfangled clustering technologies which let you scale to multiple JVMs.

Friday, 26 February 2010

Comedy autocorrect suggestion of the day

Eclipse's built-in spelling checker recommends I replace "hashcode" with "hitchhike":
/**
 * Generate a hitchhike for this event
 *
 * @return a hitchhike considering only the event's topic and properties
 */
@Override
    public final int hashCode() {
    ...

Sunday, 22 November 2009

Offset your Bad Code footprint today

Twisting the much-abused concept of "offsetting" carbon dioxide emissions (your "carbon footprint") by buying "carbon credits", now you can "offset" your footprint of badly-written software by buying Bad Code Offsets.

Donations go to the widely-used open source projects jQuery, PostgreSQL, and the Apache Software Foundation.

Nice idea, but that last one is enough to trigger my rant mode:

Perhaps this will help Apache Commons to actually finish and maintain a project for once!

Apache may have, according to their home page, "a desire to create high quality software that leads the way in its field", and be "celebrating a decade of open source leadership", but the part I have experience with - the Commons java libraries - are, despite being very widely used, hardly a shining beacon of what open source can achieve in terms of Good Code!

Over the last few years I have spent a lot of time with several of these, using them in a large java project in my day job. This has proven a very time-consuming and frustrating experience. Without exception, I have found them to be incomplete, buggy and poorly written, and often essentially orphaned, with no releases in several years despite numerous reported critical bugs. I have had to build custom versions of four of them to fix basic failures - typically things that have already been reported with submitted patches, and often things severe enough to break my production installations. Fixes contributed back to the projects generally just sit in the issue tracker, unreleased! Why even bother contributing?

Bad open source code which is free, I can tolerate, if it admits its limitations and its completely unsupported status. After all, I can (and do) fix it myself, given the permissive license.

Bad open source code which makes a lot of noise about community, claims to strive for high quality and to lead its field, provides an issue tracker and release plan, yet doesn't release contributed critical bugfixes even after several years - this I have much less tolerance for.

More than most projects, I blame the Apache Foundation and its process for this. As Paul Graham points out, process (especially ease of releasing, and hence frequency) has a lot to do with software quality and currency. Apache places a big emphasis on their community consensus process, committees, the process of gaining project committer status etc, so they should be blamed when that process fails dismally and still hasn't released known, already-implemented fixes after several years.

via Coding Horror

Friday, 16 October 2009

More iPredict My Portfolio tweaks - adding persistent Notes field

Following on from my previous hacks, I've made another addition to my Greasemonkey script to modify iPredict's My Portfolio page, this time inspired by a forum post by ORACLE.

He requested that iPredict should add an editable Notes column to the portfolio. I've wanted this feature myself, so I figured this would be a good time to experiment with DOM Storage, since this allows local persistence of data like this, without requiring support from the server.

My updated script now adds a 'Notes' column next to each line in the portfolio, which lets you enter freeform text which is stored permanently (in your Firefox local user profile) for when you come back to the page.

The DOM Storage API for globalStorage seems to work fine in Greasemonkey (in Firefox 3.0.14), providing you tunnel through the Greasemonkey wrapper using 'wrappedJSObject' to access the globalStorage object, like this:
window.wrappedJSObject.globalStorage[window.location.hostname].setItem(key, noteText)
(I've used the older, non-standard globalStorage object, rather than the HTML5-standardized localStorage, because I'm still running FF3.0 which doesn't implement localStorage; when I eventually switch to 3.5 I may change it.)

As before, to get the script, download the current ipredict-portfolio.js from my repository on github here, and install in Greasemonkey - then just use iPredict as normal and enjoy the new stuff. See the previous post for more info.

Saturday, 5 September 2009

iPredict My Portfolio customization

Following on from something I thought of yesterday and posted on the iPredict forums, I decided to have a go at customizing iPredict's My Portfolio page. I wanted to make it easier to see the information I'm interested in when placing limit orders to trade on stock movements.

To do this I've written a Greasemonkey script, which uses javascript to read some values from the tables on the page, and adds extra columns correlating the current stock holdings with the active orders and watchlist.

It works purely on the information already on the HTML page and visible in the page source - it doesn't make any requests to the server, so I think it should fall within iPredict's terms and conditions.

To get it, download the current ipredict-portfolio.js from my repository on github here.

To use it, see the comments at the top of the file. Basically:
  • Use Firefox (tested on 3.0.13, will probably work on 3.5 if Greasemonkey does)
  • Install the Greasemonkey firefox addon
  • Install ipredict-portfolio.js as a userscript in Greasemonkey, for URLs matching the pattern https://www.ipredict.co.nz/Main.php?do=portfolio* (the iPredict My Portfolio page).
  • The script will apply its changes whenever you view that page in iPredict.

This will probably break whenever iPredict change their site layout; I may provide an updated version at the above page if I am still using it myself.

Sunday, 30 August 2009

Programming editor wars

Yet another 'editor wars' discussion on Hacker News.

I'm always surprised by how many people come out in favour of Emacs and Vi in these debates. Despite their undoubted power in the hands of an experienced user, both feel to me like slightly stone-age tools, wilfully and perversely eschewing recent progress in GUIs, usability, learn-ability, intuitiveness, and unsurprisingness. Admittedly I haven't spent the time to become proficient in either, but with similarly powerful but infinitely more modern tools like jEdit and Eclipse available, why would I?

Powerful tools should have interfaces that empower the new user right away, not cripple them until they fortuitously discover the right tricks, or work through 10 tutorials, or digest the entire manual.

My contributions:
Eclipse
jEdit