Friday, March 19, 2010

On Java's (supposedly) immutable strings

The power of setAccessible is beyond belief.
import java.lang.reflect.*;

public class MutableStrings {
   public static void main(String args[]) throws Exception {
      Field value = String.class.getDeclaredField("value");
      value.setAccessible(true);
      value.set("foo", "bar".toCharArray());      

      System.out.println("foo"); // prints "bar"
   }
}
Note: Although I label this post as [fun], I don't think it actually is...

Thursday, March 18, 2010

Modifying static final fields through reflection

In Java, nothing is impossible.
import java.lang.reflect.*;

public class EverythingIsTrue {
   static void setFinalStatic(Field field, Object newValue) throws Exception {
      field.setAccessible(true);

      Field modifiersField = Field.class.getDeclaredField("modifiers");
      modifiersField.setAccessible(true);
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

      field.set(null, newValue);
   }
   public static void main(String args[]) throws Exception {      
      setFinalStatic(Boolean.class.getField("FALSE"), true);

      System.out.format("Everything is %s", false); // "Everything is true"
   }
}
Having fun yet?

Sunday, March 14, 2010

Open facebull

I was asked to share my solution for my facebull, and I finally did (github).

I'm not particularly proud of the code, since it's rather messy. I spent about 5 days thinking about the algorithm, and I coded it in about 30 min and submitted it, and to my surprise it passed.

I am aware that this is probably the most challenging Facebook puzzle, which is why I was initially reluctant to share the solution. In the end, though, I decided that none of this really matters anyway. It's just 250 lines of poorly written Java code that when compiled and ran against some input produces the expected output, and some bot decides that it's good enough.

So there.
Update 03/18: I plan to rewrite this using immutable sets instead of java.util.BitSet; I was worried that the algorithm is way too slow and thought I'd need to squeeze every bit of performance to pass the bot. I think this optimization is premature.

Fact: the original passing solution had 100 more lines of various preprocessing heuristics; they turned out to be unnecessary, since the current version still passes.

Saturday, March 13, 2010

St-st-stuttering rr-rr-regex

Credit for this one goes to Alan Moore on stackoverflow.com (again!) from his answer to my question:
Matcher m = Pattern.compile("(?=(..))").matcher("12345");
while (m.find()) {
   System.out.println(m.group(1));
} // prints "12", "23", "34", "45"
This is the most instructive pattern I've seen BY FAR. The most important revelations for me are:
  • You can capture during lookaround! Which means that...
  • Group zero is not necessarily a superstring of all the other groups!

Tuesday, March 9, 2010

Looking behind as far as the eyes could see...

System.out.println(
   java.util.Arrays.deepToString(
      "This works! Yes, really!! Try it! JUST DO IT!!!".split("(?<=!++)")
   )
); // [This works!,  Yes, really!!,  Try it!,  JUST DO IT!!!]
 
The above snippet works. I had to experiment with the different quantifiers, and neither greedy nor reluctant worked, but somehow possessive does what I wanted. And I'm not sure how and why.

It turns out that it isn't supposed to work. That pattern isn't supposed to be compilable; a PatternSyntaxException should've been thrown. That it compiles is a bug (ID 6695369); that it works is mind-boggling. So, unlike the case in the bug report, this pattern doesn't "fail silently" -- it "works unexpectedly"!!!

For what it's worth, the "right" pattern to use is "(?<=!)(?!!)" (credit to Alan Moore on stackoverflow.com).

Tuesday, March 2, 2010

Kidnapping an inner class instance

This blew my mind. Although I suppose this naturally follows from the fact that Java's final fields aren't:
import java.lang.reflect.*;

public class Me {
    final String name;

    Me(String name) {
        this.name = name;
    }

    class InnerMe {
        void whoAreYou() {
            System.out.println(name);
        }
    }
    
    InnerMe innerSelf() {
        return new InnerMe();
    }

    public static void main(String args[]) throws Exception {
        final Me me = new Me("Just the old me!");
        final InnerMe innerMe = me.innerSelf();

        innerMe.whoAreYou(); // "Just the old me!"

        Field outerThis = innerMe.getClass().getDeclaredFields()[0];
        outerThis.setAccessible(true);
        outerThis.set(innerMe, new Me("New and improved me!"));

        innerMe.whoAreYou(); // "New and improved me!"
    }
}

Monday, March 1, 2010

Go invoke yourself!

import java.lang.reflect.Method;

public class InfiniteMirror {
   public static void main(String args[]) throws Exception {
      Method m = Method.class.getMethod(
         "invoke", Object.class, Object[].class
      );
      Object[] a = { m, null };
      a[1] = a;
      m.invoke(m, a);
   }   
}
Oh my...
This is not a bug by any mean, but out of curiosity, I looked into the database to see if there's anything like it. There is (ID 4185411), since it was a bug back when this would crash the JVM (!!!).
WORK AROUND: Never, ever, write code that is as stupid as this in any real project.