Bug 141252 - [1.6]][compiler] ClassFormatError: Illegal class name "" in class file
Summary: [1.6]][compiler] ClassFormatError: Illegal class name "" in class file
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2.1   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-05-11 05:39 EDT by Philipe Mulet CLA
Modified: 2006-09-11 12:25 EDT (History)
1 user (show)

See Also:


Attachments
Patch for disassembler (to make it more resilient) (1006 bytes, patch)
2006-05-11 06:47 EDT, Philipe Mulet CLA
no flags Details | Diff
Proposed patch (950 bytes, patch)
2006-05-11 07:09 EDT, Philipe Mulet CLA
no flags Details | Diff
Regression test (5.32 KB, patch)
2006-05-11 07:22 EDT, Philipe Mulet CLA
no flags Details | Diff
Better patch (1.55 KB, patch)
2006-05-11 10:31 EDT, Philipe Mulet CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Philipe Mulet CLA 2006-05-11 05:39:08 EDT
3.2RC3

I recently observed that our regression tests were not performing in 1.6 mode (they reverted to 1.5 compliance). When fixing this, AutoboxingTest#test109 failed.

junit.framework.AssertionFailedError: Unexpected target error running resulting class file for X.java:
java.lang.ClassFormatError: Illegal class name "" in class file X
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:465)
	at 
	at junit.framework.Assert.fail(Assert.java:47)
	at junit.framework.Assert.assertTrue(Assert.java:20)
	at org.eclipse.jdt.core.tests.compiler.regression.AbstractRegressionTest.runConformTest(AbstractRegressionTest.java:445)
	at org.eclipse.jdt.core.tests.compiler.regression.AbstractRegressionTest.runConformTest(AbstractRegressionTest.java:317)
	at org.eclipse.jdt.core.tests.compiler.regression.AutoBoxingTest.test109(AutoBoxingTest.java:3261)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:589)
	at junit.framework.TestCase.runTest(TestCase.java:154)
	at junit.framework.TestCase.runBare(TestCase.java:127)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:118)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
	at junit.extensions.TestDecorator.run(TestDecorator.java:28)
	at org.eclipse.jdt.core.tests.util.CompilerTestSetup.run(CompilerTestSetup.java:48)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:457)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:670)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:58)
	at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:24)
	at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:589)
	at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
	at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
	at org.eclipse.core.launcher.Main.run(Main.java:977)
	at org.eclipse.core.launcher.Main.main(Main.java:952)
Comment 1 Philipe Mulet CLA 2006-05-11 05:40:15 EDT
Testcase:
public class X {
	public static void main(String[] args) {
		int foo = 0;
		String bar = "zero";
		System.out.println((foo != 0) ? foo : bar);
	}
}
Comment 2 Philipe Mulet CLA 2006-05-11 05:48:42 EDT
GenericTypeTest#test0894,0896 and 0897 exhibit the same issue.
Comment 3 Philipe Mulet CLA 2006-05-11 06:43:06 EDT
Problem is located in StackMapTable attribute:

We produce:
      Stack map table: number of frames 2
        [pc: 19, full, stack: {PrintStream}, locals: {String[], int, String}]
        [pc: 20, full, stack: {PrintStream, }, locals: {String[], int, }]

Instead of:
      Stack map table: number of frames 2
        [pc: 19, full, stack: {PrintStream}, locals: {String[], int, String}]
        [pc: 20, full, stack: {PrintStream, Serializable}, locals: {String[], int, String}]

Note that I had to change the disassembler to be resilient to empty names.
Comment 4 Philipe Mulet CLA 2006-05-11 06:47:24 EDT
Created attachment 41095 [details]
Patch for disassembler (to make it more resilient)

This isn't the fix to the problem, but a way for the disassembler tool to avoid crashing when such badness occurs.
Comment 5 Philipe Mulet CLA 2006-05-11 06:50:36 EDT
I suspect some mishandling of intersection types.
Comment 6 Philipe Mulet CLA 2006-05-11 07:09:43 EDT
Created attachment 41100 [details]
Proposed patch

Allows computing a constant pool from a wildcard & intersection type (by inferring it from its erasure).

This makes the scenario work, and is consistent with other definitions of constantPoolName, now in the past it was assumed that no wildcard/intersection type would ever need to be computed a constantpool name, which is false due to StackMapTable attribute requiring these.

So this is a safe fix.
Comment 7 Philipe Mulet CLA 2006-05-11 07:22:53 EDT
Created attachment 41102 [details]
Regression test

Ensure we have a test showing the included constant pool name for an intersection type (other tests are not disassembling)
Comment 8 Philipe Mulet CLA 2006-05-11 10:31:10 EDT
Created attachment 41118 [details]
Better patch

This version of the patch is also improving the erasure for the intersection type from Object to Comparable (more precise type).
Comment 9 Philipe Mulet CLA 2006-05-11 12:07:16 EDT
Added StackMapAttributeTest#_test008
Will queue the fix for 3.2.1, as there are more issues to address with intersection types, and we should address them all at once.
(i.e. erasure change is exposing bug 141330)
Comment 10 Philipe Mulet CLA 2006-05-16 10:52:29 EDT
Released for 3.2.1 integration.
Comment 11 Frederic Fusier CLA 2006-06-12 05:18:01 EDT
Released for 3.3 M1 while merging TARGET_321 in HEAD
Comment 12 Frederic Fusier CLA 2006-08-08 06:31:22 EDT
Verified for 3.3 M1 using build I20060807-2000.
Comment 13 David Audel CLA 2006-09-11 12:25:00 EDT
Verified for 3.2.1 using build M20060908-1655