Name: boT120536 Date: 07/15/2001
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
Our security architecture includes a ClassLoader which wants to be
able to attach an array of objects (of arbitrary type) to classes
it has defined, and it hopes to be able to retrieve them (verbatim)
later. As these objects are (our own representation of) code signers,
ClassLoader.setSigners() and Class.getSigners() seemed ready-made for us.
They worked just fine until we started testing with jre 1.3!
What I got back from getSigners() didn't seem to match what I put in...
Here's the test code I put together to illustrate the problem I'm having:
class t extends ClassLoader
{
public static void main(String[] a)
{
String[] b = new String[] {"foo","bar"};
Class me = t.class;
System.out.println("Setting signers to "+b+", length "+b.length);
new t().setSigners(me,b); // ClassLoader.setSigners()
Object[] thing = me.getSigners();
System.out.println("Got a "+thing+", length "+thing.length);
System.out.println("First element is "+thing[0]);
// thing[0] = thing[0]; // ArrayStoreException!
String[] c = (String[]) thing;
System.out.println("c is "+c+", length "+c.length);
}
}
In brief, I put in an array of String and expect to get out an array
of String. This is indeed what happens with v1.2.2 on both NT (build
JDK-1.2.2_005) and Linux (build 1.2.2-L):
] Setting signers to [Ljava.lang.String;@d660c514, length 2
] Got a [Ljava.lang.String;@d1f0c514, length 2
] First element is foo
] c is [Ljava.lang.String;@d1f0c514, length 2
However, when I built and ran this under j2sdk 1.3.0 on NT (build 1.3.0-C)
it exploded:
] Setting signers to [Ljava.lang.String;@41cd1f, length 2
] Got a [[Ljava.lang.String;@17d257, length 2
] First element is foo
] java.lang.ClassCastException: [[Ljava.lang.String;
] at t.main(t.java:17)
An array of an array of String? Even more baffling is that the elements
of the returned String[][] are in fact the original (String) elements
of the String[] I passed in in the first place. getSigners() seems to be
returning the same array, same contents but with a different type!
This is further confirmed by uncommenting line 15 (gives an
ArrayStoreException); it's a sad day when you can't store something back into
the same array it came from! At least "checkcast" seems to be working properly
:-)
I then attempted to determine the extent of this bug. I was able to
reproduce it with all the >=1.3.0 j2sdks I had to hand: 1.3.0 (build
1.3.0-C) and 1.3.1 (build 1.3.1-b24) on Win2k, as well as 1.3.0 on Linux
(build Blackdown-1.3.0-FCS, for what it's worth). I then downloaded and
installed build 1.4.0-beta-b65 for NT, and found it still occurred.
As far as I can tell (with javap), Class.getSigners() is native, and
ClassLoader.setSigners() calls Class.setSigners() which is also native. I
therefore suspect that one or other of those two natives has changed in
some subtle way in j2sdk 1.3... Have either of them been deliberately
changed? I haven't been able to find any documentation to suggest that
this is the case, which is why I think it's a bug.
(Review ID: 127616)
======================================================================