2008-09-25

pom-parser is dead, long live jde-mvn!

As some of you know (I know you're out there, freaks), I'm happily hacking away at my JDEE-Maven integration project. Up to now I have had two separate projects:
  1. pom-parser, which dealt with getting information from the POM and into JDEE's variables
  2. jde-mvn, which dealt with using Maven as a build tool
This became cumbersome, and got in the way of some cool stuff I wanted to do. So I merged them. :)

pom-parser is now deprecated; if you use it, you should move to jde-mvn.

This shouldn't be onerous for the, like, two people besides me who use it (while I'm on the subject, if you use this please drop me a note!), even though most (all?) of the functions in pom-parser have changed names.

jde-mvn is packaged as a JDEE plugin (for more on this, read about plugins in the JDEE manual), which means that the installation process is both simpler and more complicated, but ultimately I think this is the way I want to go.

Anyway, jde-mvn now supports a server mode, thus amortizing the startup cost of the JVM across calls. Wee! The initial startup cost is quite heavy, though, but there is not much I can do about that.

So. If you want to play with jde-mvn, it is available from my Mercurial repository. I will try to keep even tip fairly stable (I do the major hacking on a local clone), but I will also tag what I consider to be stable revisions with 'stable-DATE'; if you don't fancy life on the severely-hemorrhaging edge, you may want to go with one of these.

Enjoy!

2008-09-19

New features in pom-parser

pom-parser just got a bit simpler; I now delegate the work of resolving artifacts to files in the file system to Maven (using the dependency:list goal with outputAbsoluteArtifactFilename=true). Less work for me, more robust system; it should now work out of the box if you have a non-standard local repository location (or if you're on Windows).

There are also three notable bug fixes:
  • with-pom will no longer fall over if there is no POM; this allows you to have a single prj.el in the parent directory of all your source dirs without nastiness happening if you need to work on an Ant-based project
  • Newer versions of maven-help-plugin have changed the output format; pom-parser should now be able to find the effective POM regardless of the plugin version
  • The classpath order (as presented by Maven) is now preserved. This is only relevant if you're using Maven 2.0.9 or later; before 2.0.9, the classpath order as generated by Maven was non-deterministic anyway (!).
Next up: Integrating with Nexus for completion of artifacts (in pom-add-dependency).

pom-parser is, as usual, available from my Subversion repository.

2008-09-05

I just can't let this go unpublished...

public class $_ {
public static <$_> $_ $_($_ a) {
return a;
}
public static <$_> void $_($_ ... $__) {
for ($_ $_ : $__) {
// \u000a\u0053\u0079\u0073tem\u002eo\u0075t\u002epr\u0069n\u0074\uu006c\u006e($_($_));
}
}

public static void \u006d\u0061\u0069\u006e(\u0053t\u0072i\u006e\u0067 ... $_) {
$_($_);
}
}


Or, even better:

public class $_ {
public static <$_> $_ $_($_ a) {
return \u0061\u003b\u002f\u002f$!"#$&/($##§!"a;
}
public static <$_> void $_($_ ... $__) {
for ($_ $_ : $__) {
// \u000a\u0053\u0079\u0073tem\u002eo\u0075t\u002epr\u0069n\u0074($_($_));
}
}

public static void \u006d\u0061\u0069\u006e(\u0053t\u0072i\u006e\u0067 ... $_) {
/*
* \u002a\u002fif($_\u002ele\u006egth\u003d=0)$_=\u006ee\u0077 \u0053t\u0072i\u006e\u0067[]{\u002f\u002a\u002a\u002f"Obfuscated!"};\u002f\u002a
*/

for (\u0053t\u0072i\u006e\u0067 _$ : $_) {
$_(_$\u002es\u0070\u006ci\u0074(\u0022"));
$_(\u0022\n"\u002c "")\u003b;
}
}
}

More obfuscation fun

From this blog entry comes this gem:

import java.util.Collection;
public class TestType {
public static <Collection> Collection myMethod(Collection a) {
return a;
}
public static void main(String ... args) {
System.out.println(myMethod("Hello World"));
}
}


Beautiful, just beautiful...

2008-09-02

The joy of programming

Today I had occasion to rediscover the joy of programming. Not that it's been dull lately, far from it, but today I did something real fun. Today's word is 'obfuscation'.

It started when I directed a colleague to The International Obfuscated C Code Contest. Obfuscation is just so easy in C; but can the same kind of thing be done in Java? Well...

Inspired particularly by the Mullender entry from the very first IOCCC, in 1984, I sat down and thought.

Here is what I came up with:
public class Obfuscated {
static String n, m;
static java.util.Map bm = new java.util.HashMap();
static {
try {
n = new String(new byte[] {79,66,70,85,67,76,65,83,83}, "UTF-8");
bm.put(n, new byte[] {
120,-100,109,80,93,75,2,65,20,61,-41,
-81,117,-73,45,77,-45,62,5,95,34,-19,33,-95,87,-93,
-88,64,8,36,-125,45,95,122,-102,-43,81,70,118,103,
67,103,-125,126,86,61,20,-12,-48,15,-24,71,69,
119,77,-112,-64,121,-72,-9,-50,-103,115,-18,61,119,
-66,127,62,-65,0,-100,-94,70,-80,123,87,-99,-121,
-21,-18,-91,-25,89,32,66,113,34,-98,69,43,16,122,
-36,-22,-7,19,57,48,22,-46,-124,66,-49,31,-59,-77,
-127,48,114,120,-110,16,8,-71,51,-91,-107,57,39,
-92,27,-51,-66,-117,28,44,7,25,-28,9,-103,80,40,
77,-88,54,30,-69,-53,86,-98,-103,42,61,110,55,-5,
-1,6,120,47,51,35,67,11,46,119,-119,98,67,-88,-4,
73,84,-44,-70,99,-66,97,-107,20,97,-37,-59,6,10,
54,-42,81,-28,-74,55,51,125,100,-22,-47,-62,-114,
-118,116,125,20,-21,-117,60,74,-124,-14,10,-79,-123,
45,-126,-11,-108,0,1,-69,-86,52,86,-103,114,81,
-59,-74,-125,10,118,-40,-2,117,52,-108,-68,112,87,
105,121,27,-121,-66,-100,-34,11,63,96,-60,-15,-94,
120,58,-112,29,21,72,16,82,-68,108,114,82,92,-13,
-18,28,-9,-8,86,-29,76,-100,-77,-57,31,-80,95,
-71,32,-20,115,-52,-51,65,-2,106,56,88,91,80,15,-25,
82,-64,126,-61,102,-87,-4,-114,-35,37,-35,-31,
39,36,-97,-119,44,35,7,-13,41,-39,95,48,-4,89,-18
});

m = new String(new byte[] {109,97,105,110}, "UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
}
}

public static void main(String[] a) throws Exception {
ClassLoader cl = new ClassLoader() {
protected Class findClass(String cn) throws ClassNotFoundException {
if (bm.containsKey(cn)) {
try {
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
java.util.zip.InflaterOutputStream ios = new java.util.zip.InflaterOutputStream(baos);
ios.write(bm.get(cn));
ios.close();
byte[] bytes = baos.toByteArray();
return defineClass(cn, bytes, 0, bytes.length);
} catch (java.io.IOException e) {
throw new ClassNotFoundException(cn, e);
}
} else {
return super.findClass(cn);
}
}
};

Class c = Class.forName(n, true, cl);

for (java.lang.reflect.Method me : c.getDeclaredMethods()) {
if (m.equals(me.getName()))
me.invoke(null, (Object)a);
}
}
}
You can download this code.
Not as pithy as Mullender's, but it still has a certain something.

Now, of course, I didn't write that monstrous byte array by hand; in fact, the entire program above was written by another program, which is listed below:

public class Obfuscator {
static String n, m;
static java.util.Map bm = new java.util.HashMap();
static {
try {
n = new String(new byte[] {79,66,70,85,67,76,65,83,83}, "UTF-8");
bm.put(new String(new byte[] {77,101,116,104,111,100,82,101,110,97,109,101,114}, "UTF-8"),
new byte[] {
120,-100,-107,84,-51,78,19,81,24,61,-73,
45,20,-38,-31,-81,-108,42,34,32,32,-38,118,40,
69,65,65,1,21,17,-76,74,107,34,-124,-123,-69,-95,
-67,-64,-32,48,37,-19,-16,-93,111,-30,-54,37,91,77,
68,-125,11,-29,-54,-123,-113,-32,11,-8,14,-58,-120,
-25,78,-85,-87,-76,42,-90,-55,-52,-67,-33,-49,
57,-25,-98,-5,77,63,125,127,-9,30,-64,101,-36,23,
104,74,75,103,61,-97,123,36,109,99,83,22,-4,16,2,
-67,-7,-62,90,50,-65,-78,33,-77,-50,-82,92,73,26,
-59,-51,100,-87,104,38,103,108,57,-86,-56,43,16,
-6,-83,111,120,-61,-40,49,4,26,-14,86,46,-61,125,
81,-96,101,65,-123,-110,-37,-114,105,37,23,-91,51,
41,-32,-73,-27,-82,74,-78,-73,-108,-77,12,123,45,
-71,-24,20,76,123,-115,105,-49,-26,-114,64,-33,-62,
-97,-72,-105,-51,-94,-23,-28,11,44,-84,-97,50,
109,-45,-71,33,48,23,-3,103,-11,49,17,-43,-68,-79,
101,-127,-13,-1,-58,-119,45,107,-48,-48,28,-128,
15,45,26,2,8,54,-62,-125,54,13,-11,-16,-85,85,-69,
-122,6,52,-86,85,7,29,-35,81,77,75,79,-73,100,-54,
46,-38,2,-111,104,-86,54,111,-45,111,-30,-4,-24,
-92,-127,-39,-68,-19,24,-90,77,3,59,-94,21,93,15,
93,109,-109,-79,-57,26,-70,112,54,-120,51,-24,-2,
-53,61,-107,85,-5,-47,-85,-31,20,78,7,113,14,125,
2,-51,-82,-82,121,83,90,-71,-110,-80,-21,-75,-124,
-99,36,-94,-60,123,87,-51,61,-127,11,-47,26,-39,
-22,-112,-122,65,92,8,-48,-98,-117,26,6,112,94,9,
-118,113,68,92,65,37,-55,74,-111,6,-67,-108,27,-94,
17,38,7,-51,-32,33,-108,127,-79,-118,107,76,-107,
-29,-60,28,70,82,57,49,-62,-127,-86,-50,-5,113,
-103,35,-73,110,20,51,114,-49,-95,-36,-88,-14,110,
12,87,-126,24,-59,85,1,-97,-19,-122,-61,-47,88,
-75,-53,26,38,112,77,-43,93,23,104,61,126,22,63,-90,
-120,107,-38,57,-71,-9,112,-11,-40,45,-3,52,32,
-91,-31,6,110,6,48,-115,91,2,-127,-126,-36,-78,-116,
-84,-100,-79,44,-127,-119,26,-27,39,116,-16,54,
102,21,-30,29,106,-97,-51,-25,-92,-6,-62,76,91,
102,-74,55,87,100,97,-55,88,-79,24,105,90,116,-116,
-20,-109,-76,-79,85,-34,7,22,-13,-37,-123,-84,-100,
55,45,-119,62,-70,-17,-29,71,-17,-27,-101,83,
-53,-107,71,-51,-84,-5,-26,60,-13,93,7,-63,25,111,
-30,115,-98,-69,-23,114,125,71,92,127,-117,-42,-72,
126,-128,80,124,-24,0,-31,120,-30,0,-111,87,76,
8,-36,-27,51,-62,54,-80,-83,-114,-115,1,52,-93,-123,
-65,48,90,-103,-27,-32,-107,-95,30,-112,-44,-53,
119,79,-4,53,-62,67,-121,-24,-15,-32,57,26,-72,
-119,-92,-7,8,117,49,-44,-17,-59,43,87,-118,-62,
12,-71,-60,-19,68,12,115,29,65,55,-79,-18,-71,-46,
69,-120,-112,28,-96,50,-16,42,79,-94,-24,39,42,-127,
-69,92,76,-123,-98,-120,119,-6,-34,34,122,-120,
120,29,-10,121,16,-105,-85,50,120,-100,-14,12,41,
-69,56,-86,-35,24,71,-81,75,-23,-125,103,-80,-115,
108,-6,127,115,38,106,113,38,-86,57,-5,-55,57,
64,-50,65,114,94,-84,-32,-12,-88,79,-90,-52,-7,-116,
71,87,-75,-41,-12,-113,-72,-86,120,15,113,73,32,
77,-10,113,65,-10,1,46,-8,-65,-8,1,-45,25,61,-15,
6,51,-98,23,71,95,-12,-124,82,-13,6,115,11,-5,71,
-97,-11,-105,-65,72,123,-36,-85,-113,19,78,-25,
109,37,-24,-20,48,71,35,-55,-56,8,5,-116,-71,2,-126,
-16,124,67,-77,31,-93,95,17,-91,-126,-108,-37,
92,-9,3,-68,-120,101,94
});
bm.put(new String(new byte[] {67,108,97,115,115,82,101,110,97,109,101,114}, "UTF-8"),
new byte[] {
120,-100,-83,84,91,79,19,65,20,-2,-90,
-76,93,104,-73,92,-54,117,1,11,5,-124,-19,-115,42,
34,-105,114,81,44,-96,-43,82,-116,24,-116,-6,-76,
-76,11,44,46,109,-45,46,-105,-8,-32,-1,-48,23,31,
125,-43,68,32,-43,-60,-8,-60,-125,63,-63,63,-32,
127,48,68,60,-77,20,-71,-76,4,30,-52,38,-77,51,-25,
-100,-7,-50,-9,-51,-100,51,63,-2,124,-7,6,96,0,
-113,25,-60,-88,-82,-28,-13,79,-44,-76,-78,-82,-26,
4,48,6,79,38,-73,18,-50,44,-83,-87,73,99,75,93,
10,43,-7,-11,-80,25,51,-107,82,-78,6,-113,-87,96,
-112,74,99,-26,-77,-55,76,74,-51,11,-80,49,-44,-99,
6,-19,95,83,54,21,-122,-54,-116,-98,74,-48,58,
-49,80,19,-25,-90,-16,-122,-95,-23,-31,5,-43,24,99,
16,-46,-22,22,119,50,-72,-113,124,-70,-110,94,9,
47,24,57,45,-67,66,110,-5,-72,-106,-42,-116,73,-122,
105,57,126,1,-69,69,45,-81,25,-103,-36,-40,57,
-24,82,52,-33,34,67,-9,-91,48,-66,69,17,34,-86,29,
-80,-94,70,68,37,-86,-86,96,65,-99,8,7,-100,124,
86,-49,96,-37,-28,-95,12,9,57,22,43,-51,114,21,-53,
-53,-14,-28,92,103,20,8,104,102,-88,80,82,41,-122,
70,-7,-44,-122,121,-109,-5,-104,-17,-123,8,9,
-83,78,-76,-96,-115,-63,-110,-36,100,-24,-68,76,-101,
-120,107,-16,112,21,29,23,95,118,49,86,-128,87,
68,35,-102,-100,-24,66,55,-125,-45,-44,60,-89,26,
-85,25,-30,-77,46,-1,71,-31,101,72,31,-27,57,102,
77,-89,-80,-84,109,51,-12,-54,-27,118,-105,-104,
68,-12,65,118,-112,72,-97,-120,-21,-24,-27,2,2,116,
-74,71,-104,-1,-54,61,-60,48,83,-82,22,-50,-90,
-66,66,77,-15,106,9,59,-48,-113,27,12,29,-105,-32,
9,24,-96,118,-48,-88,-105,20,90,49,52,-55,-66,83,
25,98,69,59,41,24,-60,109,126,-79,67,-44,21,-91,
126,1,35,-44,55,-85,74,62,-95,110,83,25,86,-56,-68,
20,34,24,115,98,20,-29,12,-42,-76,105,110,-112,
125,-91,69,35,98,18,119,120,-36,93,-122,-38,-13,
98,4,-36,35,92,45,-99,82,-73,-25,-105,-49,21,-35,
-79,-36,-104,-120,105,-52,56,16,-59,44,-125,35,-89,
102,117,37,-87,78,-23,58,-61,72,-103,-16,43,-34,
-41,3,-60,56,-30,67,-30,30,-91,-105,-124,63,19,90,
90,77,108,-84,47,-87,-71,-89,-54,-110,78,22,-41,
-126,-95,36,95,-51,41,-39,-30,-38,-79,-112,-39,-56,
37,-43,89,77,87,-31,-91,-69,-74,-126,-34,10,-6,
91,120,-57,-46,11,-25,-26,-3,74,127,110,23,-31,-94,
49,78,-85,65,51,18,-88,-11,7,-10,104,8,-18,-64,
-19,15,-19,-96,-31,19,-39,24,-26,-52,125,-36,-17,
-126,13,-43,-124,80,67,95,45,121,-88,15,-118,8,83,
16,-24,3,-68,-2,-49,112,-121,10,104,-73,-32,25,
77,59,-37,-84,52,54,72,86,-55,38,-39,11,-24,17,112,
2,89,-115,10,26,-21,-119,78,3,58,9,-118,-15,-86,
44,-62,101,-120,52,-121,-101,48,49,-126,-2,-48,30,
-4,126,-55,74,-93,100,43,32,104,71,-60,46,-39,-9,
-31,105,-85,-77,-30,-51,59,52,125,69,-1,115,-55,
-50,115,-13,116,123,-72,-55,-3,31,9,-64,114,-118,
125,11,90,-23,101,-24,-93,49,-126,118,36,-56,82,
9,118,-128,-120,-128,91,20,71,-51,81,76,-2,-102,-120,
-15,-8,-47,-64,62,-122,56,102,1,-61,68,57,88,
-64,4,-61,91,116,-45,100,-118,-31,59,-94,-119,64,
104,23,-9,45,-17,15,127,5,66,60,-17,46,30,-59,63,
28,-2,12,-100,36,-10,28,29,10,-63,117,-111,-34,30,
52,-109,70,47,-87,-12,83,-70,97,4,76,18,78,88,14,
80,45,96,-12,-73,-55,96,-34,-36,44,-4,5,18,3,-92,
-11
});
bm.put(n, new byte[] {
120,-100,-107,87,121,120,27,-59,21,-1,
-115,108,107,-27,-107,18,-37,74,-28,-80,4,-110,37,
64,34,57,-118,12,118,49,65,54,9,62,48,56,-8,0,-100,
-60,56,110,74,-41,-46,-38,86,34,-19,-118,-43,
42,-119,49,38,16,82,-96,-123,-74,20,122,81,-24,-107,
-46,-70,119,33,-76,50,-58,77,74,75,47,40,-67,40,
-67,75,79,-38,-46,-5,-8,-89,31,-3,10,-18,-101,93,
-55,-110,34,-39,-112,-3,108,-51,-18,-101,119,-49,
-69,-26,-23,87,30,63,9,-96,9,-1,98,-88,30,-24,-24,
-34,-43,-39,-37,62,56,40,-128,49,-44,-18,83,14,
40,-115,113,69,27,111,28,24,-35,-89,70,76,1,21,12,
-110,110,-116,55,-22,-42,-9,65,117,-76,81,73,37,
26,7,-110,17,61,-86,-90,4,84,49,-44,12,-116,-114,
-91,83,17,-59,-44,-115,16,-89,103,112,-74,-59,-76,
-104,-71,-115,-95,-62,31,-40,-19,-127,11,-43,34,
42,33,50,84,38,-108,-104,-58,80,-17,31,-23,-51,75,
26,52,-115,-104,54,-34,26,-40,-51,-80,42,15,-67,
-4,80,68,77,-102,49,93,19,-80,-78,72,-79,-63,-55,
-108,-87,38,4,-44,18,123,-43,48,24,124,54,-81,-104,
-34,120,53,49,50,-119,-99,-86,36,90,61,-16,98,
85,53,-22,-80,-102,97,79,58,-91,-116,-85,97,57,-81,
-88,-36,22,-119,43,-87,-108,-90,36,-44,109,114,
91,66,53,39,-12,-88,-87,-57,-76,3,-6,126,14,-32,112,
125,44,66,-116,76,53,106,97,110,-109,71,-38,-108,
104,52,-58,53,82,-30,54,40,20,10,-19,117,-95,62,
-89,118,-79,2,2,-50,96,16,-110,28,16,39,-109,125,
-2,114,22,123,112,38,-42,-118,-112,112,22,-7,70,
61,20,51,105,-15,-9,112,-8,58,-84,23,73,121,89,-124,
-125,59,-82,-62,72,19,-109,-34,50,76,94,11,-92,
-84,-73,61,56,23,-25,113,-10,-25,-77,-86,71,-109,
-23,-47,120,44,34,91,118,-55,83,23,76,-53,-101,
-90,54,-119,50,61,41,83,49,105,-61,-90,-110,-75,-96,
-100,104,45,-124,115,-66,-95,-76,25,-117,-121,
-6,-108,100,-101,-115,21,28,-99,52,-43,-111,-67,-37,
-28,-47,-124,124,-87,-84,-87,7,11,-80,-82,84,82,
19,-91,-104,-2,64,17,-45,-100,108,-2,-104,-58,100,
-47,55,127,52,98,59,117,-31,116,-85,56,-43,52,
93,-76,-63,-27,77,53,79,-73,46,2,-89,101,58,-19,-56,
-124,-20,-73,52,-120,-23,-95,93,90,42,-99,76,-22,
6,29,-21,-27,26,-123,48,41,-79,24,104,-78,26,40,
18,101,-13,-98,22,-83,37,-21,-96,-84,-122,7,-12,
88,84,-26,-79,-20,-73,13,25,-39,43,43,1,-39,-100,
48,-12,-125,41,57,-49,-80,-112,91,39,119,109,-81,
-82,68,85,-125,-36,-100,117,76,1,-48,31,40,-79,51,
105,-24,38,-27,-100,26,-75,-15,-38,-74,111,-109,
-57,98,90,-44,-6,-56,10,-106,35,-38,-94,92,11,-34,
-81,-101,-35,122,90,-117,-106,87,34,-9,-60,-58,
100,-1,104,34,20,-47,53,-109,-116,72,93,-91,78,-6,
-119,81,-87,6,-53,-99,66,-31,-109,115,111,7,-99,
103,-69,97,40,-109,3,105,51,-103,-50,102,-126,60,
-86,-24,-87,-62,72,88,10,49,23,6,75,74,-80,66,-24,
-58,88,50,-44,-93,-115,-59,41,53,-115,34,49,-79,
98,41,-53,34,-5,-71,78,-53,-120,35,94,-95,-125,70,
-52,84,-71,-101,-58,85,-45,114,-49,-14,-24,-111,
-72,-98,82,-105,51,-63,14,118,107,-31,-118,114,13,
66,-90,-66,-24,-119,-27,72,13,-43,76,27,-102,28,
85,-23,-4,85,-5,-4,35,-108,-117,22,-85,-96,124,65,
-10,45,20,87,-75,113,115,98,9,62,37,-71,-48,51,-80,
100,-24,-97,-6,88,17,-106,-113,-40,-110,32,-77,
-76,81,-105,18,92,2,-99,-106,-43,120,74,93,82,98,
-42,90,-54,84,-43,8,-27,35,-98,-114,-96,84,64,49,
-13,-4,23,21,-127,-30,-44,-29,-39,19,33,-73,91,31,
-95,49,-35,-24,-89,26,-17,39,-75,77,35,-83,6,41,
37,3,5,20,-76,-99,-11,19,-81,-103,33,67,29,-117,
83,34,-122,-6,-84,62,33,39,84,57,44,71,120,88,116,
-87,84,49,13,53,106,111,-92,-4,101,82,-120,-89,90,
34,-92,-34,-112,86,-30,41,127,66,-27,84,-106,-28,
64,32,80,98,12,109,-37,45,-56,-81,-91,-29,-15,-96,
-20,-73,-101,112,64,41,48,60,87,-107,-90,93,-40,
-60,-80,-58,42,-20,60,-44,27,123,99,-38,126,53,
-54,11,-20,-96,74,125,59,32,-94,-127,119,-114,21,
121,12,11,30,-92,102,66,-115,-20,-108,-114,100,11,
106,13,-20,-15,32,-124,70,55,-74,-32,2,-122,-70,
60,105,-74,110,11,104,18,-47,-52,-39,-70,40,55,12,
-34,73,121,55,15,-12,-26,49,123,-78,112,106,-64,
23,-95,-123,115,-70,-104,-63,91,-70,47,-32,18,-22,
-113,19,74,-86,95,61,100,90,-109,2,-55,110,69,-101,
27,97,92,74,109,80,-77,-64,-85,115,-68,11,-75,
-12,96,59,46,-29,120,-19,-59,-125,-127,85,17,5,116,
-110,118,-28,101,-21,-96,-87,55,23,113,-80,-128,
-60,-32,114,116,-13,-111,-28,-118,-100,7,11,24,116,
-92,99,113,-86,-57,2,122,68,-20,-32,-90,10,-122,
-102,-116,43,17,-107,91,-38,-39,25,40,-19,-91,30,
-12,-94,79,68,23,-6,105,-12,81,-110,73,85,35,-9,
110,41,-41,-16,75,64,89,97,-60,-30,106,92,-61,-27,
93,75,44,66,86,27,118,97,39,25,98,-22,54,-30,-87,
-82,88,20,-67,27,67,-100,-18,58,-102,-61,78,49,
83,-64,30,50,-97,60,113,-83,-102,-46,-45,70,68,109,
79,-39,-59,-113,33,-80,-76,114,52,-59,-12,104,-117,
117,-110,4,-68,30,123,69,-116,-32,13,12,103,-105,
-50,-127,-106,-96,107,85,-59,114,-40,27,25,-50,
-16,-105,-27,98,79,-127,-93,34,20,68,-106,-26,51,
-60,11,46,-15,81,57,50,-115,63,99,32,-77,-41,45,
-127,-36,30,85,-110,22,118,-116,-31,92,127,-17,18,
88,-69,99,-87,24,15,70,91,-127,-3,34,-10,33,78,
30,-74,-45,-47,3,13,-115,-4,-36,-12,-110,88,-73,82,
-27,6,17,6,68,23,31,-116,61,89,67,-7,96,72,50,-45,
12,93,-81,42,-77,-73,40,-13,-54,-116,101,-74,82,
7,69,28,-64,33,30,57,17,94,77,25,-50,123,85,-50,
-42,-124,120,35,-90,-72,63,111,34,127,-26,92,94,
-74,-85,10,-72,89,-60,97,30,-56,27,-14,10,81,95,108,
-20,82,75,-5,-94,-128,91,105,-34,-49,31,98,-31,
94,86,-33,-37,68,28,-63,81,6,119,65,-17,-30,99,107,
96,-92,-61,-125,-37,113,7,63,-73,59,25,-86,-84,
-10,73,-85,127,-92,-125,19,-66,5,119,113,-62,-69,
9,98,117,74,15,-34,-58,-81,5,71,-16,118,-122,115,
120,103,-55,-74,-57,-87,-78,45,-63,-123,119,112,
-39,107,121,-88,-33,-57,-51,33,9,78,-69,-35,89,-75,
-93,-57,-125,119,-29,61,124,-9,-67,12,103,-47,8,
-67,108,-90,-67,-113,35,62,-64,17,-53,-92,115,33,
-30,-5,57,-30,7,-88,86,46,-95,-44,-121,-56,112,34,
74,120,112,-116,-89,97,23,62,66,21,-87,20,-19,-93,
-92,44,-115,89,-86,65,-89,27,-14,-9,-100,94,97,
-104,-63,-57,-71,22,-97,-96,-53,90,74,53,123,45,
-101,61,-8,20,79,-112,29,-8,52,-43,-42,-46,-98,-24,
-62,103,11,46,37,5,-119,40,-32,97,17,-113,112,-105,
23,-76,5,-85,-82,63,74,110,36,52,-122,-83,101,
-38,66,-103,70,81,-82,42,127,1,25,55,62,-113,89,
-78,118,-65,58,73,49,79,105,85,-44,27,120,26,120,
48,-121,-57,57,-38,60,-87,88,-88,53,13,90,-92,-128,
-33,-123,19,12,76,115,-31,75,100,-80,-98,-67,-80,
81,28,109,124,77,-11,-108,-40,127,25,95,-31,-73,
-102,39,25,28,65,-14,-3,-41,-8,74,73,-4,13,50,112,
-100,-85,-76,-79,92,-33,43,103,-50,83,120,-102,
-21,-7,45,-18,-8,-12,104,42,91,-122,125,-27,-126,
-117,-80,-65,-115,-17,-16,0,-8,46,-119,-95,110,-19,
-62,-9,-23,69,79,-101,30,-4,-64,-66,-122,62,-105,
107,53,38,53,-74,-58,62,53,-59,-81,-92,-35,-70,
-111,80,-88,-46,-4,-120,92,54,102,-67,51,92,82,-58,
-48,-111,-27,85,94,84,-30,39,-8,-87,-120,31,-29,
103,-28,-38,50,119,62,1,-65,32,103,-116,116,8,-8,
37,85,-103,92,120,44,119,37,18,-16,107,82,-101,103,
-89,-51,-62,95,-104,-88,46,-4,-106,-110,121,-41,
-50,-18,45,91,93,120,-63,110,-70,-68,34,-92,120,
-93,44,115,88,-68,62,-4,1,127,-28,94,122,-111,-54,
-57,116,80,-34,96,17,111,8,-72,-16,103,74,-92,78,
61,74,-25,92,67,115,-116,-38,-97,78,-116,-86,-58,
78,101,52,78,-112,21,-125,-90,18,-39,79,81,-102,
-3,22,23,-43,35,73,-30,-96,-43,-38,-70,99,113,21,
100,28,-11,116,114,37,96,-83,46,84,-45,-17,95,-23,
-21,108,90,25,-83,85,13,-77,112,63,66,47,12,127,
-93,95,-89,5,-84,39,52,15,86,16,49,71,-67,14,85,
22,116,83,-61,73,-25,49,-44,28,-121,-49,-69,38,-125,
-77,43,31,-61,57,-13,112,12,-49,98,67,67,69,83,
67,101,83,67,85,83,67,6,27,57,51,-121,-59,-84,-98,
8,65,-9,121,39,-42,98,37,-50,-126,23,-21,-79,17,
50,-2,78,-48,10,48,47,-2,-111,85,-85,-122,-2,-23,
-22,109,-53,-85,124,-103,8,-42,16,-113,125,94,127,
-40,57,-113,6,-110,-80,57,44,72,-62,-26,57,92,-24,
-64,-112,84,121,-46,-7,16,-50,113,-74,-72,124,
46,122,63,-122,122,73,-112,42,125,-82,38,123,-5,-88,
-117,-51,44,-68,56,-113,102,34,123,93,-40,37,9,
115,-40,-54,16,-82,-106,-86,-25,-80,-115,-31,126,
-74,-99,-65,117,48,60,-127,-82,-80,72,10,95,57,-113,
29,-124,123,-107,36,-42,-122,106,27,51,24,-56,
96,-48,-69,-117,126,50,24,-50,-32,-6,-80,123,30,
-54,-80,-28,-98,69,52,-20,-103,-57,-40,-80,115,22,
19,-31,21,-13,-40,55,44,-83,-104,69,34,-68,82,18,
55,103,-112,-68,31,-21,-25,97,16,-93,84,-72,-58,
107,-122,107,-25,113,-128,16,-92,26,-87,118,22,-109,
-124,-28,-111,86,86,100,48,61,-113,-61,-124,115,
75,-72,102,30,71,-122,-91,-102,89,-68,41,92,43,
-43,74,43,50,120,115,6,111,-107,106,51,-72,-121,-21,
-29,-67,119,22,-17,12,-41,73,53,25,-68,43,-20,
-107,-68,39,91,86,85,-76,-84,-10,-83,-10,-83,58,-122,
54,-55,-21,91,-35,-36,-30,-109,-22,50,-72,-65,
-91,94,-86,-13,-7,50,120,-80,54,-104,-63,7,-121,
124,-11,-75,-35,73,107,-125,-42,-121,-32,-106,-22,
-68,31,38,83,-122,-114,-82,38,-81,60,-55,57,-13,
77,-78,-21,33,-30,95,-31,-3,88,6,-97,36,41,117,22,
69,101,52,-125,-49,16,-63,-25,56,-127,-28,-50,-32,
-72,-28,-110,68,11,127,14,-113,85,96,104,-26,-107,
19,89,95,-111,59,93,115,-8,34,-125,-19,92,81,18,
109,-25,-30,14,-2,-106,117,-82,91,114,-37,-114,
113,121,-51,25,84,73,-18,-80,71,-86,-10,-98,36,-18,
-7,-115,39,102,80,-35,32,121,102,-15,-43,34,-16,
-41,9,-33,-5,-51,2,-48,26,82,-59,61,-121,103,28,
-100,115,45,121,-23,123,51,-88,41,-124,-15,67,123,
-106,43,62,-77,-112,110,-16,-102,-60,-112,14,55,
-56,23,-9,113,-4,80,114,10,39,80,57,92,-79,101,112,
-72,82,18,7,-121,-85,-92,-22,-63,97,-89,-28,30,
124,12,63,-89,80,-50,-121,-20,113,4,-23,119,35,69,
101,47,-59,127,31,-123,112,63,-91,-54,0,-4,-44,-6,
46,-94,-75,21,59,41,89,119,33,66,83,-26,29,24,-62,
-67,-108,29,15,98,-104,90,-46,30,60,76,51,-31,
28,13,-121,39,-80,23,-49,-32,122,60,71,-77,-56,-13,
24,-59,-117,-124,-3,111,68,-15,31,-116,49,7,13,
112,-21,49,-63,54,-46,-112,-42,-116,125,-84,19,-5,
-39,85,4,-69,6,9,54,1,-115,-103,52,121,-35,-124,
36,-69,21,6,-69,7,41,118,31,13,86,15,-30,0,123,2,
7,-39,-77,56,-28,-72,8,-45,-114,-83,56,-20,-72,12,
-73,56,-82,-64,17,71,12,-73,-15,116,98,79,-63,-69,
64,-103,85,45,-64,33,-96,43,-9,-9,60,-84,-91,-127,
-78,-9,-65,56,-13,101,-44,9,104,22,16,94,-64,-51,
-88,41,-113,105,35,88,-17,-113,8,80,4,-116,9,52,
32,98,-127,-116,-10,-99,6,-123,-128,-61,2,-114,
8,-40,33,-32,87,52,43,-30,101,-70,-38,-80,-105,80,
-75,-128,118,-120,-53,-15,-31,-94,-22,-31,94,6,101,
-121,-123,-11,63,-100,75,-80,118,-6,-25,-8,43,
94,5,-33,-34,0,-93,-81,5,-86,73,-81,17,-35,97,125,
117,93,109,81,-79,-45,-92,-70,-34,-94,114,-97,38,
-43,75,68,-111,47,-118,14,-34,-71,-77,69,-8,1,-86,
-104,2,-83,125,86,117,-8,29,101,111,-33,102,-17,
-17,51,-8,83,-1,-106,-109,45,-107,21,45,85,-66,42,
95,-27,49,-84,-35,-30,-85,106,110,113,6,125,-50,
-59,-110,112,-76,-118,82,-1,-123,96,48,-105,-31,
65,-17,95,120,-98,-48,-9,-16,-61,-117,113,-65,-50,
98,126,59,68,-118,-22,-13,113,39,46,-92,-11,98,-102,
80,-37,113,23,-82,-60,-35,86,-55,62,3,-114,5,
-6,113,-26,44,-54,29,-18,-70,69,-107,127,67,-1,-1,
-76,120,10,-1,7,0,126,-15,92
});

m = new String(new byte[] {109,97,105,110}, "UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
}
}

public static void main(String[] a) throws Exception {
ClassLoader cl = new ClassLoader() {
protected Class findClass(String cn) throws ClassNotFoundException {
if (bm.containsKey(cn)) {
try {
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
java.util.zip.InflaterOutputStream ios = new java.util.zip.InflaterOutputStream(baos);
ios.write(bm.get(cn));
ios.close();
byte[] bytes = baos.toByteArray();
return defineClass(cn, bytes, 0, bytes.length);
} catch (java.io.IOException e) {
throw new ClassNotFoundException(cn, e);
}
} else {
return super.findClass(cn);
}
}
};

Class c = Class.forName(n, true, cl);

for (java.lang.reflect.Method me : c.getDeclaredMethods()) {
if (m.equals(me.getName()))
me.invoke(null, (Object)a);
}
}
}
You can download this code, too.
You'll need to have ASM 3.0 or later on your classpath to run this.

Happy hacking, and remember, kids:

If it ain't fun, you ain't doin' it right!

Final (hopefully) edit: Updated the example and the obfuscator to actually work. Wee.

Really final and last edit (2008-09-03): Tweaked the obfuscator to produce smaller class files, allows obfuscation of more complicated classes without bumping into JVM limits.

2008-06-03

Next step, world domination

My JDEE/Maven integration work is proceeding apace; pom-parser is now learning to modify the POM. The first evidence of this is the command pom-add-dependency, which allows you to add a dependency element to your POM. It even does completing-reads of groupId, artifactId and version!

It doesn't reparse the POM when it changes, though. I know how to do it, I just haven't gotten around to it yet; besides, I'm not sure if I want it to. Maybe it should be a customizable option?

I've also fixed one genuine bug (I only changed the first dot in the groupId to a slash... oops) and one unexpected behavior:

Imagine a file structure where you have a src directory with two Maven projects inside, foo and bar. You have a generic prj.el file in the src directory.

If you visit a Java file from project foo, the foo POM is read and JDEE variables are set correctly; then visit a file from project bar, and the bar POM is read and JDEE variables set.

But if you then switch back to the file from the foo project, you will get bar's variable settings (e.g. classpath). Bummer.

Once I twigged to what was going on, though ("Dude, why is this file not compiling? Hang on, that classpath looks strange...") it was fairly easy to fix.




In other news, I have more-or-less ready code to use Maven as a build tool for JDEE (ala the Ant integration); I just want to hammer it a bit more before I make it public.

And I may have a solution for the "making JDEE wait for Maven" issue mentioned a couple of weeks ago. Once again, stay tuned!

Bidirectional Mercurial + SVN

I've been playing with Mercurial lately, and I'm really impressed. However, I still need to interact with Subversion repositories (not least my own), so I thought I'd try hgsvn, which lets you use Mercurial locally on a Subversion checkout. Sweetness!

That is, as long as you remember to tell Emacs that you prefer Mercurial to Subversion by moving the 'Hg' entry before 'SVN' in vc-handled-backends...

One wrinkle, though: hgsvn does not handle pushing changes back to the remote repo...

But that's nothing a little shell scripting can't fix!

hgpushsvn.sh lets you do just that.

Run it like this: hgpushsvn.sh mono[lithic]|single


monolithic (or mono)

Checks in all changes since the last revision in Subversion as one commit. The commit message is the output of hg log --style changelog for the changesets back to the last pulled from Subversion.

single

Checks in each changeset since the last pull as a separate commit. The commit message is still the output of hg log --style changelog. This is a much slower operation!