Yesterday, when I should have been paying attention to my breathing during yoga, I was instead thinking about inner classes. Specifically I was wondering how Java resolves ambiguities between package names and inner class names.
In Java, an inner class is specified using its parent's name, a dot, and its name. for example, Foo.Bar is an inner class named "Bar" in the parent class "Foo". But this is also how Java names packages. Bar could just as easily be a first class class in package Foo.
Note that there's no ambiguity once the code has been compiled. The class file format uses / as a package separator and $ as an inner class separator, so Foo$Bar is an inner class, and Foo/Bar is a top level class in package Foo. The ambiguity is only present in the compiler, where "." serves both purposes.
I wrote a simple test case. I created a simple Foo.java file with a public static inner class Bar, and a Foo/Bar.java file with a public class Bar. Then I wrote a test class like this:
public class Test {
public static void main(String[] args) {
System.out.println(new Foo.Bar());
}
}
What happens when you compile and run this?
peter$ java Test
Foo$Bar@c53dce
Notice the '$' in the name? The inner class won, so it looks like javac resolves the ambiguity in favour of the inner class.
But what if we really want to mess with the compiler? What happens if you try to compile this file?
public class java {
public static class lang {
public static class Object {
}
}
}
Yes, the file is called java.java. None of these names are reserved in Java, so this ought to be a perfectly legitimate class named java. It has an inner class, java.lang, with its own inner class, java.lang.Object (not to be confused with java.lang.Object, the superclass of each of these classes).
javac doesn't seem to like this class very much, at least not the version installed on my Mac:
tmp peter$ javac java.java
An exception has occurred in the compiler (1.6.0_17). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.NullPointerException
at com.sun.tools.javac.comp.Flow.visitIdent(Flow.java:1214)
at com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:1547)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:35)
...
I don't think that this is a security hole, since the ambiguity is only present in the compiler. It's possible that there's a similar ambiguity in reflection, but I'm not sure. That might be somewhat higher risk.
Update: Eclipse compiles this java.java file with no problem. Looks like it's just an obscure bug in javac.
Further update: I'm not the first person to discover this: http://www.bodden.de/tag/name-resolution/
Saturday, November 6, 2010
Saturday, October 16, 2010
RIP Benoit Mandelbrot
Benoit Mandelbrot, the father of fractals, is dead at 85.
When I was in high school I was fascinated by the Mandelbrot set. I wrote a program which rendered it (quite slowly) on my 286. It let you draw a line anywhere across the set and play it as musical tones. (Well, as musical as a PC's speaker could be.)
When I was in high school I was fascinated by the Mandelbrot set. I wrote a program which rendered it (quite slowly) on my 286. It let you draw a line anywhere across the set and play it as musical tones. (Well, as musical as a PC's speaker could be.)
Saturday, October 2, 2010
Data Mining 101: Amazon Wishlists
I was searching for someone's Amazon wishlist and found this link, instead: Data Mining 101: Finding Subversives with Amazon Wishlists. It's nearly 5 years old, so you probably discovered this long before I did, but it's pretty interesting how much data he could find just linking together a few public, free databases.
It reminded me of an ad I saw on a website yesterday. (I should have captured it.) It said something like "Searching for Gary Gnu?" and then provided links to a couple of sites ostensibly selling Gary Gnu (Buy Gary Gnu on eBay.ca!). I had done a Google search for Gary Gnu a few days before; the ad must have been sniffing my browser history to figure that out, possibly using the old link coloring trick.
Is privacy dead? Probably, but I think it has been for a long time now. The only real difference is that we know it, and I guess that's half the battle.
It reminded me of an ad I saw on a website yesterday. (I should have captured it.) It said something like "Searching for Gary Gnu?" and then provided links to a couple of sites ostensibly selling Gary Gnu (Buy Gary Gnu on eBay.ca!). I had done a Google search for Gary Gnu a few days before; the ad must have been sniffing my browser history to figure that out, possibly using the old link coloring trick.
Is privacy dead? Probably, but I think it has been for a long time now. The only real difference is that we know it, and I guess that's half the battle.
Thursday, September 23, 2010
-XX:+UseCompressedStrings?
Our friends at Oracle have recently published some impressive SPECjbb2005 scores. Hotspot got a little over 3.3 million bops using 8 JVMs on a Sun Fire X4800.
I'm curious about some of the command line options they used. Most of them look like they're JIT and GC tuning options (would anyone really use -XX:InlineSmallCode except for a benchmark?), but one looks a bit different: -XX:+UseCompressedStrings. I also noticed that they've prepended some libraries called alt-string.jar and alt-rt.jar onto the bootstrap classpath.
I've googled this option but not much turns up. My best guess is that they're representing String data using byte arrays instead of char arrays. This would save half the space (8-bits vs. 16-bits), but would only work well for ASCII. i.e. good if you're Western European, not so good if you're Eastern European or Asian. Plus it wouldn't be very significant for small strings, since the object headers of the String and char[] objects take up a big portion of space occupied by each String.
According to the SPEC submission the JVM which supports these options should be available this month, so maybe we'll see some doc for this option to satisfy my curiosity.
I'm curious about some of the command line options they used. Most of them look like they're JIT and GC tuning options (would anyone really use -XX:InlineSmallCode except for a benchmark?), but one looks a bit different: -XX:+UseCompressedStrings. I also noticed that they've prepended some libraries called alt-string.jar and alt-rt.jar onto the bootstrap classpath.
I've googled this option but not much turns up. My best guess is that they're representing String data using byte arrays instead of char arrays. This would save half the space (8-bits vs. 16-bits), but would only work well for ASCII. i.e. good if you're Western European, not so good if you're Eastern European or Asian. Plus it wouldn't be very significant for small strings, since the object headers of the String and char[] objects take up a big portion of space occupied by each String.
According to the SPEC submission the JVM which supports these options should be available this month, so maybe we'll see some doc for this option to satisfy my curiosity.
Wednesday, September 1, 2010
What I'm reading
I'm heading off to Paris with Kristin for a week. We'll be looking for merchandise for her store, sight seeing and eating well.
I found a few papers which looked interesting to read on the flight:
I found a few papers which looked interesting to read on the flight:
- The Economics of Garbage Collection -- the authors suggest applying microeconomics theory to memory management
- Improved Replication-Based Incremental Garbage Collection for Embedded Systems -- I'm interested in incremental GC and region-based GC right now
- Tracing Garbage Collection on Highly Parallel Systems -- multi-core GC is clearly something we need to focus on in the coming years
Sunday, August 29, 2010
We're hiring
Interested in working on the J9 VM in Ottawa? We've got a job opening.
Note that a demonstrated aptitude for low-level programming is so important that we've written it twice. We've written it twice.
If you're interested (and you have a demonstrated aptitude for low-level programming) apply through the web site or send me a note.
Note that a demonstrated aptitude for low-level programming is so important that we've written it twice. We've written it twice.
If you're interested (and you have a demonstrated aptitude for low-level programming) apply through the web site or send me a note.
Saturday, August 28, 2010
Debugging tip: timing holes
Parallel programming is hard. Really hard. And, as we're now firmly in the era of multi-core computing, it's an increasingly important skillset.
A couple of days ago we hit an assertion in some code. The failing test case reproduced the problem 2 out of 300 times. So it was reproducible, but highly intermittent.
The developer who was debugging the problem speculated that there might be a timing hole. There was a section of code which set two variables kind of like this:
He hypothesized that if one thread ran through this code while another thread read the same fields, the second thread might see that the section has red objects, but, briefly, might think they start at NULL instead of the correct address somewhere in the middle of the section.
We used a really simple technique to prove this: make the timing hole bigger.
Adding a 10ms sleep between the two assignments caused the problem to occur nearly every time, confirming his hypothesis.
(We fixed the problem by getting rid of the bool hasRedObjects field. We defined a new function, bool hasRedObjects() { return NULL != baseOfRedObjects; }. With only one field, the updates are atomic and the timing hole is eliminated.)
A couple of days ago we hit an assertion in some code. The failing test case reproduced the problem 2 out of 300 times. So it was reproducible, but highly intermittent.
The developer who was debugging the problem speculated that there might be a timing hole. There was a section of code which set two variables kind of like this:
section->hasRedObjects = true;
section->baseOfRedObjects = basePointer;
He hypothesized that if one thread ran through this code while another thread read the same fields, the second thread might see that the section has red objects, but, briefly, might think they start at NULL instead of the correct address somewhere in the middle of the section.
We used a really simple technique to prove this: make the timing hole bigger.
section->hasRedObjects = true;
usleep(10000); // sleep for 10 ms
section->baseOfRedObjects = basePointer;
(We fixed the problem by getting rid of the bool hasRedObjects field. We defined a new function, bool hasRedObjects() { return NULL != baseOfRedObjects; }. With only one field, the updates are atomic and the timing hole is eliminated.)
Subscribe to:
Posts (Atom)