Atom Feed SITE FEED   ADD TO GOOGLE READER

Bind a single time to the same port in Mac OS X

I think I've resolved a problem I came across earlier: I could bind to the same port multiple times using NIO on Mac OS X.

A kind soul named Timothy Wall has helped me to work-around the problem. Just call setSoReuseAddress(false) on the channel's socket before binding:
        ServerSocketChannel channel = ServerSocketChannel.open();

ServerSocket socket = channel.socket();
socket.setReuseAddress(false);
socket.bind(listenAddress);


See the related thread on the Mac Java mailing list:
http://lists.apple.com/archives/java-dev/2004/Dec/msg00570.html

The inconsistencies of the SWT.FILL style

It seems like there's no shortage of unusual behaviours to be found in SWT. The most recent one that I've come across is the behaviour associated with the SWT.FILL style. Consider the layout found in the GlazedLists demo. Laying out the interface in a single GridLayout puts two Tables above one another. Those Tables should both be styled so that they grab excess vertical space and have the SWT.FILL style applied. This is a requirement so that they are rendered correctly when the window is resized.

When the demo is initially created, it renders correctly. The tables are sized fairly evenly. However, as soon as the window is resized, the lower Table implodes never to return. It's easy enough to expect this behaviour. If two or more widgets are contending for free space in the layout, the only two outcomes are either the first one wins and takes all or they should all share space evenly. The real problem is not how the widgets contend for space. The real problem is that that contention is different on initialization than it is on future resizings.

Just another bullet in the list of things that make SWT trying to use.

Stupid Bash Tricks: Find a file in a pile of jars

My latest code depends on ServiceMBeanSupport.class from JBoss. The problem is that JBoss is composed of dozens of .jar files and I'm not sure which one contains the file I'm interested in.

Tools
  • find this command will list all the files that meet the specified metadata. It can also execute a command for each file found, using that filename as a parameter. For example, to remove all the CVS folders in a directory tree, type find . -name CVS -exec rm -rf {} \; . Find will substitute {} for the file that's found and it needs \; to designate the end of the command.
  • grep give input text, grep prints only the lines that match my regular expression.
  • bash -c executes the bash shell. This can be used with find -exec to run multiple commands in sequence
  • jar tvf print all the files in a .jar file

    Find my file in a jar
    jar tvf jarfile | grep ServiceMBeanSupport.class

    This will tell me if the file is in the jar file or not. Its a start.

    Find my file in all the .jar files in the current directory or deeper
    find . -name *.jar -exec jar tvf {} | grep ServiceMBeanSupport.class \;

    This will tell me if the file is in any of the jarfiles. Unfortunately it doesn't tell me which jarfile it is in, since it just prints the contents of the jarfiles and not their names.

    The Command
    find . -name *.jar -exec bash -c "echo {} && jar tvf {} | grep ServiceMBean " \;

    This writes the name of the jar file, followed by any matching file's that are in it. So if I search for ServiceMBean, I get a list like this:

    ./client/jboss-iiop-client.jar
    
    ...
    ./client/jboss-net-client.jar
    ./client/jboss-system-client.jar
    ./client/jboss-transaction-client.jar
    ./client/jbossall-client.jar
    795 Fri Jun 25 19:55:16 EDT 2004 org/jboss/jmx/adaptor/rmi/RMIAdaptorServiceMBean.class
    1331 Fri Jun 25 19:55:16 EDT 2004 org/jboss/jmx/connector/ConnectorFactoryServiceMBean.class
    ./lib/jboss-system.jar
    603 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ListenerServiceMBean.class
    1745 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ListenerServiceMBeanSupport$MBeanInfo.class
    10950 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ListenerServiceMBeanSupport.class
    1309 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ServiceMBean.class
    9523 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ServiceMBeanSupport.class
    ...


    And my work is done for the day. Cool, eh?
  • PLAF Detection Workaround for Ocean Metal and Windows XP

    Currently, Swing has a couple of bugs which hinder PLAF detection on the client. In particular, Windows and Metal suffer from ambiguity in their UIManagers. In GlazedLists it's important that we inspect the PLAF precisely so that the pixel-perfect sort arrow icons that Jesse made are chosen correctly. Jesse wrote a couple of methods that workaround these bugs a while ago. In some recent refactorings, I extracted these into a better home and had a chance to look them over. I think them worthy of mention to help others who may have related problems.

    Metal


    There are now two types of Metal, Ocean and Steel. Unfortunately, the result of calling UIManager.getLookAndFeel().getName() is "Metal" for both. However, Ocean only exists on Java 5 so here's the workaround exploiting the new getCurrentTheme() method added in Java 5:

    public static String getMetalTheme() {
        try {
            MetalLookAndFeel metalLNF = (MetalLookAndFeel)UIManager.getLookAndFeel();
            Method getCurrentTheme = metalLNF.getClass().getMethod("getCurrentTheme", new Class[0]);
            MetalTheme currentTheme = (MetalTheme)getCurrentTheme.invoke(metalLNF, new Object[0]);
            return "Metal/" + currentTheme.getName();
        } catch(NoSuchMethodException e) {
            // must be Java 1.4 because getCurrentTheme() method does not exist
            // therefore the theme of interest is "Steel"
            return "Metal/Steel";
        } catch(Exception e) {
            e.printStackTrace();
            return "Metal/Steel";
        }
    }

    Windows


    There are two types of Windows themes as well called XP and Classic. Just as with Metal, the result of calling UIManager.getLookAndFeel().getName() is "Windows" for both. Here's a workaround derived from code in the XPStyle class:

    public static String getWindowsTheme() {
        String classic = "Classic Windows";
        String xp = "Windows XP";

        // theme active property must be "Boolean.TRUE";
        String themeActiveKey = "win.xpstyle.themeActive";
        Boolean themeActive = (Boolean)java.awt.Toolkit.getDefaultToolkit().getDesktopProperty(themeActiveKey);
        if(themeActive == null) return classic;
        if(!themeActive.booleanValue()) return classic;

        // no "swing.noxp" system property
        String noXPProperty = "swing.noxp";
        if(System.getProperty(noXPProperty) != null) return classic;

        // l&f class must not be "WindowsClassicLookAndFeel"
        String classicLnF = "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel";
        if(UIManager.getLookAndFeel().getClass().getName().equals(classicLnF)) return "Classic Windows";

        // must be XP
        return xp;
    }

    SWT vs My Sanity: Round 2

    I'll try to keep my rants on SWT to a minimum, but I feel the need to provide information to others who run head first into the brick wall that is SWT. I remember reading a comparison of Swing and SWT some time ago and it clicked into my mind today. Despite Google's best efforts, I couldn't find the article but I'll give you the conclusion:

    SWT is great and fast as long as you want to do small, simple things, one time.

    Bearing that in mind, parts of the framework make a little more sense. But then again, lots of things make sense when you don't plan to ever make anything complex, scalable or maintainable. Large projects need Swing, or at least, they need something that feels Object-Oriented; Something that's built with best-practices and patterns like MVC in mind.

    Today's SWT Strangeness:
    A Table widget only fires events to a registered MouseListener iff the MouseEvent occurs inside the table.

    Doesn't seem strange at first save for the following problem: The table headers are not inside the table.

    In order to gain information on table headers being clicked you need to use a SelectionListener(groan). SelectionEvents are only fired by mouse clicking with the left mouse button. But can't you add a MouseListener to the TableColumn and access the header? No, you can't. The only Table-related widget that supports MouseListeners is Table. I even tried using the base Listener (which you can add to anything), and seeing if perhaps handleEvent() might shed some light on things. Wrapping the event in a MouseEvent I dumped the details of the MouseEvent to my console. At first it was exciting. I had beaten SWT. But no, just like that SelectionEvent, those events only show up with you left-click. In the event that you wanted to provide a complex interface that behaves different when you right click or ctrl-click on a table header, come running back to Swing before your boss has his heart set on SWT.

    Tomorrow's SWT Strangeness:
    Table Implosion

    Stay Tuned...

    My private interfaces design pattern

    So I found myself writing some code that seemed like a GoF design pattern. I'm not so sure that it is, but if it were, here's its criteria...

    Name: Private Interfaces
    Intent: Implement methods in a class without exposing them in the public API.
    Motivation: Hiding methods prevents them from being called by the API's user. Method hiding also streamlines the API of a class. For example, a class may need to receive mouse events without exposing methods like mouseClicked() in its external API.
    Applicability: When the class must implement an API without exposing it.
    Consequences: Essentially, Interface methods become 'private'. This prevents extending classes from overriding them and users from calling them. The interface may still be exposed where it is needed.
    Implementation: Add an inner class that implements all the private interfaces. Create a private member of this inner class, and use pass as the parameter wherever the private interfaces are needed.
    Sample Code:
    /** Before. This class exposes 6 methods */
    
    public class ClickCounter implements MouseListener {
    private int clicks = 0;
    private int presses = 0;
    private int releases = 0;
    public MyClass(Component c) {
    c.addMouseListener(this);
    }
    public void mouseClicked(MouseEvent e) { clicks++; }
    public void mousePressed(MouseEvent e) { presses++; }
    public void mouseReleased(MouseEvent e) { released++; }
    public int getClickCount() { return clicks; }
    public int getPressCount() { return presses; }
    public int getReleaseCount() { return releases; }
    }

    /** After. This class exposes only 3 methods */
    
    public class ClickCounter {
    private int clicks = 0;
    private int presses = 0;
    private int releases = 0;
    private PrivateInterfaces privateInterfaces = new PrivateInterfaces();
    public MyClass(Component c) {
    c.addMouseListener(privateInterfaces);
    }
    private class PrivateInterfaces implements MouseListener {
    public void mouseClicked(MouseEvent e) { clicks++; }
    public void mousePressed(MouseEvent e) { presses++; }
    public void mouseReleased(MouseEvent e) { released++; }
    }
    public int getClickCount() { return clicks; }
    public int getPressCount() { return presses; }
    public int getReleaseCount() { return releases; }
    }

    Related Patterns: Event listener

    Bind several times to the same port in Mac OS X

    My PowerBook lets me bind to the same port twice using NIO. The following code throws an IOException under Windows and Linux, but not under Mac OS X:

        public void bindTwice(int port) throws IOException {
    
    InetSocketAddress listenAddress = new InetSocketAddress(port);

    ServerSocketChannel firstChannel = ServerSocketChannel.open();
    ServerSocket firstSocket = firstChannel.socket();
    firstSocket.bind(listenAddress);

    ServerSocketChannel secondChannel = ServerSocketChannel.open();
    ServerSocket secondSocket = secondChannel.socket();
    secondSocket.bind(listenAddress);
    }


    It wouldn't be too big a deal but I want my application to fail if it can't bind! One horrible problem that has come up in my tests is this:
    1. Bind to port X as server.
    2. Connect to self on port X as client.
    Now the client has fully connected but server has not received anything!

    Yuck. And Google doesn't tell me anything. Yuck yuck.

    Oh SWT, how I loathe thee. Let me count the ways.

    Some reasons why SWT frustrates me in no particular order:


    • A column title in a table header has the same justification as the contents of the column.

    • Common style constants have common (and therefore ridiculously vague) descriptions in the documentation. Next to no effort was put in to provide more detailed descriptions in classes which will commonly use those styles. In fact, most if not all of the widgets even specify a list of best fit styles for that widget but don't elaborate on what, if anything, something like SHADOW_IN might do when applied.

    • Common style constants period. If I enjoyed writing painful to maintain code, my language of choice would not be Java. It just makes so much more sense to have a Style object that you can set properties on. Would that really be any different that the GridData class? Internally, it could pretend to be all 1337 and do everything with bitmasks like it was written in C, but I shouldn't have to see fifty million constants. It's no wonder Sun refuses to touch SWT with a ten foot pole. But I suppose I shouldn't complain, they could replace GridData with 25 more common style constants.

    • Virtually every class has the following warning (or a slightly different one with the same meaning): 'IMPORTANT: This class is not intended to be subclassed'. If that's the case, Java has a keyword for it. It's called final.

    • Out of the box, my apps don't look right on Windows. Seriously...I have to manually set the margins on the Layout for it to look native. Why isn't native the default? The default width on a Shell with a GridLayout is at least twice the size of the native window border. Funny though, the window border with the defaults looks identical to that of a Swing window. And here I thought SWT was supposed to be 'better'.

    • EVERYTHING is a SelectionEvent. Clicking on a Button, okay. I can shift my mindset to see how that is a selection. You are 'selecting' that Button when you click it. But will someone please tell me, honestly, if I press ENTER in a Text field, how is it that I just defaultSelected it? In fact, I would have already had to select it a while a go to type ENTER into it in the first place. And defaultSelected? To me that sounds like a widget has default focus, not the user did something that can't possibly be considered default by any definition of the word. I'm very curious why SWT felt ActionEvents were the devil, as they make so much more sense.

    • The GridData class has no methods, just public fields and constructors. And yet they aren't supposed to be reused? Weird that their siblings RowData and FormData don't have this problem. Oh, and as Jesse mentioned, they also have some convenience style constants that don't work in obvious cases.



    Sorry, I just felt the need to rant. It seems that working with SWT has that affect on people.

    How many bytes to the centre of the tootsie pop?

    Today I ran into an unexpected problem while dealing with InputStreams and OutputStreams...

    Pop-Quiz
    How many times is "World O Hell" printed when the following code is executed?

        for(byte i = -128; i <= 127; i++) {
    
    System.out.println("World O Hell");
    }


    < 256 times
    255 times
    256 times
    > 256 times

    Pop-Answer
    If you answered > 256 times you're correct. This is because in byte math, 128 + 1 = -127. It reminds me of the good old days of modular arithmetic in Math 137.

    Dump a Java Stack Trace

    Sometimes I write broken code. Sometimes my test cases never complete. For this, there is a simple solution. Type CTRL+BACKSLASH into the Java process. The result is a full stack trace of all my JVM's threads.

    It's a great way to debug deadlocks.

    Apache MyFaces

    My current project at work uses JavaServer Faces extensively. Although the current implementation feels like a version 1.0, it's quie a kick-ass framework.

    Today I found out that a small component called "NewspaperTable" that I have built has made its way into the MyFaces open source JSF implementation. I even get my name in the credits!

    Docbook and a Glazed Lists Profit Model

    I think that Glazed Lists has to be open source for the project to be successful. Currently the project progresses because of the charity of myself, Kevin Maltby, James Lemieux, and O'Dell Engineering Ltd. Although these contributions are voluntary, I think that we need a profit strategy for the project. The project doesn't need to make anybody rich but it should pay for itself.

    Meanwhile, I'm planning on revising the project tutorial for the upcoming 1.0 release. I've decided to switch to Docbook, which is the ideal hacker's publishing tool. Docbook exports 'real documents' like paper and PDF and people have been known to pay for these things.

    Should I write a Glazed Lists book and sell it, then use that money to further finance Glazed Lists?

    I think the book is a very clean profit strategy:
  • Everyone can convince their boss to drop $40 on a book
  • Still open source in its purest form
  • Encourages further documentation on the project

    But it has its downsides:
  • I'd have to write a book
  • Would enough people buy it to justify its expense (in terms of my time)

    I think I'll wait for the big 1 dot owe, and then give this some further thought.