It's Friday everybody!!!
You know what that means.
Two quickie things first.
1. I've been crazy busy w/firedrills this week. Stop. Drop. Roll.
That's why we've been having radio silence on the blog front.
Blog=Extracurricular.
2. Can somebody please explain to me why it is that all you
Y-chromosome
types have this propensity towards beeping at people. People you don't
know. I walked to my parents house this week. (across the street). And
going from
here to there -- it can't be more than 100 meters -- somebody
beeps at me. So I figure somebody's beeping at
me, it must be somebody I know. Nope, just some yahoo in a pickup
truck. What compels you to behave in this way? I have never in my
entire life known a woman to randomly beep at people as she was driving
down the street.
We digress...
We've got Friday Free Stuff to get to.
But first, some unfinished business...
Please find below the solution to
last week's puzzler which came
straight to my personal inbox directly
CrazyBob (
java.net,
google fame... remember... he was our Sub
last week). Please note, as he's a
techno celeb I didn't have the courage to edit his language...
don't be offended by it though...
..It's meant in an endearing way....
Last week's puzzle challenged you to
create an object o such that o.getClass().getMethods()
returned an inaccessible method. Michael Appleby posted the correct
solution first. He takes home the booty. Congratulations, you lucky
bastard.
The key to this puzzler: Class.getMethods()
returns all public methods regardless of the enclosing class's
scope. If we declare a public method in a package private (default
scope) class, the method is not actually accessible outside of the
package:
package bob;
class Bob {
public void inaccessible() {}
}
We can expose an instance of this class
from a public class in the same package:
package bob;
public class BobFactory {
public static Object newBob() {
return new Bob();
}
}
Attempting to reflectively invoke the
method from another package throws an IllegalAccessException:
import bob.BobFactory;
public class PuzzlerSolution {
public static void main(String[] args) throws Exception {
Object o = BobFactory.newBob();
java.lang.reflect.Method[] methods =
o.getClass().getMethods();
for (int i = 0; i < methods.length; i++)
if (methods[i].getName().equals("inaccessible"))
methods[i].invoke(o, null);
}
}
The output:
Exception in thread "main" java.lang.IllegalAccessException: Class PuzzlerSolution can not access a member of class bob.Bob with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57)
at java.lang.reflect.Method.invoke(Method.java:317)
at PuzzlerSolution.main(PuzzlerSolution.java:10)
[Dis]honerable mentions:
- Andrew Taylor submitted the first attempt, but Andrew's code
actually throws
InvocationTargetException, not IllegalAccessException.
- MooBob42 is incorrect. This is not currently considered a bug,
though I agree it probably should be.
- Nic Laborera's solution throws an
IllegalArgumentException,
but only because he passes in the wrong number of arguments.
- Kris Schneider, a runner up, gets bonus points for reusing code
from the core library to produce the smallest working solution. Nice
work, Kris.
I first discovered this pitfall while
testing code that traversed a graph of objects. To avoid a similar
fate, minimize reflection. If there's a chance you could run into this
exception, I advise silently logging it (a developer might have
forgotten to make the class public).
Which would make Michael Appleby our winner!!!!
(Have I ever mention that Free Stuff is the brand promise of
MaryMaryQuiteContrary. And as
I've personally participated in a branding workshop, I am an expert in
these kinds of things.)
Everybody
who posted wins a prize! Expectation set: a pen .(see picture
below) It's a nice pen. But it's just a pen. Kris, you get two.
Claim your prize by sending me email with Friday Free Stuff in the
subject line with your name and address. I will mail the pen to you
with stamps I buy at the post office. (Michael, I'll send the fabulous
prize package to you.). I won't share your personal info or use
it for any other purpose whatsoever. I will delete the mail after I've
copied it down. We got privacy policies around here, people.
My email address: mary.smaragdis-AT-sun.com.
Now let's get to
this week's
spectacular prize....
A pen. A really nice pen. (i got a lot of them. they fell off a truck.)
Submit
a JavaOne session and tell me about it by posting a comment to this
blog entry. Sessions that you've already submitted count. You don't
have to
think up a new one. First twenty people get a really nice pen.
Honor system. (Like I said, we got a privacy policy around here;
I'd have no way of checking.)
You don't have to tell me what the session was about. I totally get how
you want to keep it a secret until the
call for
papers closes on January 31.
All you gotta do to get a pen shipped directly to you -- entirely for
free -- is
submit a
JavaOne session and be one of the first 20 people to tell me about
it by posting a comment to this blog entry.
And in conclusion, I'd like to tell you all to go hug your number one.
Thanks for listening.
mary