Saturday, 11-Sep-10 17:51
...and the best car is...

When I was a kid, one of the major questions in life whether Matchbox toy cars are better than Corgi, or perhaps Majorette (yeah, I had a happy childhood). So, after about 40 years of intensive testing, I think I've arrived to a conclusion.

Corgi - especially the Whizzwheels series - is the best.

Their cars have withstood the damage from two generations of kids with nothing but paint and occasional window damage. And their wheels still roll as well as the day they were new, whereas Matchbox wheels invariably are squashed or twisted or loose. Majorette scores second best, and unfortunately the infamous Matchbox comes last.

Well done, Corgi.

(I know I'm a bit late, since all three brands have been sold and resold a number of times. Corgi Toys, owned by Mattel, still seems to produce stuff tho'.)

Some nostalgic drooling pictures for you:

Friday, 10-Sep-10 23:20
Stripes and Shiro

I've been a long-time fan of Stripes, a really simple but powerful way of doing web apps in Java. It throws away complicated XML configuration and just prefers convention over configuration and uses annotations heavily to denote actions. It's clean cut and fast to develop in. However, it doesn't really do security (as in authentication and access control), but leaves those to the application.

Enter Apache Shiro (incubation), which is another really simple but powerful library to add access control and authentication to your Java application. It's not limited to webapps, but can be used in anything - though I don't think too many people are doing Java clients these days anymore.

Shiro comes with Spring integration built-in, but I figured I should try to make it Stripes-compatible too. Turns out this was a fairly easy task, though it was made a bit extra difficult by the fact that the AOP libraries of Shiro are not very well documented.

The way this works is that you add a new Stripes Interceptor that just delegates the access control checking to Shiro at just the right point. It even uses Shiro's built-in annotations, so it's fairly simple. Just add the following class to whichever package you like and play with it.

package stripes.util;

import java.lang.reflect.Method;

import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.controller.ExecutionContext;
import net.sourceforge.stripes.controller.Interceptor;
import net.sourceforge.stripes.controller.Intercepts;
import net.sourceforge.stripes.controller.LifecycleStage;

import org.apache.shiro.aop.MethodInvocation;
import org.apache.shiro.authz.aop.AnnotationsAuthorizingMethodInterceptor;

/**
 *  A Stripes Interceptor which will check if the given handler method has a {@link Require}
 *  annotation, and checks from Shiro whether the user has access to it.  For example
 *  <pre>
 *     public class AdminActionBean implements ActionBean
 *     {
 *        @DefaultHandler
 *        @RequiresRoles("admin")
 *        public Resolution doAdminThingies()
 *        {
 *           ...
 *        }
 *     }
 *  </pre>
 */
@Intercepts(LifecycleStage.HandlerResolution)
public class AccessInterceptor extends AnnotationsAuthorizingMethodInterceptor implements Interceptor
{
    public Resolution intercept( ExecutionContext ctx ) throws Exception
    {
        // First, execute the HandlerResolution
        Resolution resolution = ctx.proceed();

        MethodInvocation mi = new StripesMethodInvocation( ctx );
        
        // This throws a SecurityException if there's no access, which will
        // be caught by the ShiroFilter and acted upon.
        assertAuthorized( mi );
        
        return resolution;
    }
    
    /**
     *  Private class which wraps the current ActionBean/Method invocation
     *  information into a Shiro MethodInvocation.
     */
    private static class StripesMethodInvocation implements MethodInvocation
    {
        private ExecutionContext m_context;
        
        public StripesMethodInvocation(ExecutionContext ctx)
        {
            m_context = ctx;
        }

        public Object[] getArguments()
        {
            // Stripes handlers never get arguments, so this is cool.
            return null;
        }

        public Method getMethod()
        {
            return m_context.getHandler();
        }

        public Object getThis()
        {
            return m_context.getActionBean();
        }

        public Object proceed() throws Throwable
        {
            // This is not actually used by us
            return null;
        }
        
    }
}

Enjoy :-)

Thursday, 09-Sep-10 11:41
Native2ascii on web

Java folks know that in order to make sure your source code survives on multiple platform, you need to encode anything outside of ASCII (or Latin1) in the Java escape format (\uxxxx). This can be a laborious job, since you need to use a command line tool, native2ascii to do the conversion.

I got tired of doing the conversion manually (the alternative would be NOT to run my unit tests in non-ascii characters, but that's clearly the path to i18n hell), so I whipped up a small tool that can do the conversion directly on the web for you.

Enjoy; please comment here or directly in email.

Tuesday, 07-Sep-10 13:28
Running JConsole through firewalls

For anyone who have tried this and failed (and most people doing sysadmin stuff for Java programs have, I think), here comes a really simple solution for running JConsole over, well, firewalls and NATs and what-have-you.

Use SSH as a SOCKS proxy.

A minor caveat - the $jconsole_host from the original article refers to the name/IP address of the host you're connecting to - NOT the machine making the connection. Especially with EC2 it needs to be the local address from the 10.x range, not the DNS name.

I can't count the hours I've tried to figure out how to do this. RMI is so deeply unusable for all situations except when you're running machines in your own intranet. It reeks bigco all over the place...


Private comments? Drop me an email. Or complain in a nearby pub - that'll help.



More info...  
"Main" last changed on 10-Aug-2015 21:44:03 EEST by JanneJalkanen.