-
Bug
-
Resolution: Fixed
-
P3
-
5.0
-
b39
-
generic
-
generic
The implementation of java.lang.reflect.Proxy generates class files that are of version 45.3 but that contain some names (of types and methods) derived from user-supplied interfaces-- which may be defined by version 49.0 class files. In 49.0 class files, names may contain characters that are not allowed in names with previous class file versions (like '+', which is used by the Tiger javac with "-target 1.5" for naming synthetic members and local and anonymous classes). If a user-supplied proxy interface contains a name with such characters that gets used by the Proxy implementation in the generated dynamic proxy class file, a ClassFormatError will occur when creating the dynamic proxy class for that interface.
Fortunately, as far as I can determine, interfaces produced by javac from valid Java source files cannot encounter this bug, because it is impossible to declare an interface in the scope of a local or anonymous class and interfaces cannot have synthetic members (because they would have to be public). Therefore, this bug does not seem like a showstopper to me (compared to 4972791, a similar bug for normal reflection and serialization).
But this is still a real bug, which could be exposed by non-javac class file generators (JVM compilers for other languages, sophisticated tools, etc.) that take advantage of the version 49.0 class file format.
Attached is a simple test case that demonstrates this bug. The class file for the interface "Test+Interface" was part-manually crafted (because it could not have been produced by javac). The test must be executed with the "-Xverify:all" VM option to ensure that classes defined by the system class loader undergo verification:
[terrier] 160 % java -version
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32a)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32a, mixed mode)
[terrier] 161 % java -Xverify:all Test
interface Test+Interface
Exception in thread "main" java.lang.IllegalArgumentException: java.lang.ClassFormatError: Illegal class name "Test+Interface"
at java.lang.reflect.Proxy.getProxyClass(Proxy.java:497)
at Test.main(Test.java:7)
(The ClassFormatError gets transformed into an IllegalArgumentException because the Proxy implementation assumes that it has generated a well-formed class file unless the user has supplied a list of interfaces that, when implemented together, would exceed virtual machine limitations. Incidentally, the 1.4 exception chaining mechanism should be used here.)
Fortunately, as far as I can determine, interfaces produced by javac from valid Java source files cannot encounter this bug, because it is impossible to declare an interface in the scope of a local or anonymous class and interfaces cannot have synthetic members (because they would have to be public). Therefore, this bug does not seem like a showstopper to me (compared to 4972791, a similar bug for normal reflection and serialization).
But this is still a real bug, which could be exposed by non-javac class file generators (JVM compilers for other languages, sophisticated tools, etc.) that take advantage of the version 49.0 class file format.
Attached is a simple test case that demonstrates this bug. The class file for the interface "Test+Interface" was part-manually crafted (because it could not have been produced by javac). The test must be executed with the "-Xverify:all" VM option to ensure that classes defined by the system class loader undergo verification:
[terrier] 160 % java -version
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32a)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32a, mixed mode)
[terrier] 161 % java -Xverify:all Test
interface Test+Interface
Exception in thread "main" java.lang.IllegalArgumentException: java.lang.ClassFormatError: Illegal class name "Test+Interface"
at java.lang.reflect.Proxy.getProxyClass(Proxy.java:497)
at Test.main(Test.java:7)
(The ClassFormatError gets transformed into an IllegalArgumentException because the Proxy implementation assumes that it has generated a well-formed class file unless the user has supplied a list of interfaces that, when implemented together, would exceed virtual machine limitations. Incidentally, the 1.4 exception chaining mechanism should be used here.)
- relates to
-
JDK-4972791 REGRESSION: 5 Regression-test tests fail with ClassFormatError
-
- Closed
-