Community
Participate
Working Groups
I've compiled the classes from classpath.org with Eclipse 3.1RC3 and RC4 and on both, once I want to use the classes in the Sun JVM, I got the following message: compile: [jnode.compile] Compiling 4 source files to D:\epr\cvswork\jnode\core\build\clas ses [jnode.compile] D:\epr\cvswork\jnode\core\build\gen\org\jnode\test\PrimitiveDoub leTest.java:11: cannot access java.lang.String [jnode.compile] bad class file: D:\epr\cvswork\jnode\core\build\classes\java\lan g\String.class [jnode.compile] undeclared type variable: T [jnode.compile] Please remove or make sure it appears in the correct subdirector y of the classpath. [jnode.compile] public static void main(String [] args) { [jnode.compile] ^ [jnode.compile] 1 error This problem did not occur in 3.1-M7 and before. Ewout
Could you please provide steps to reproduce? What version of GNU Classpath classes are you compiling? What are your compiler's settings??
For the exact classpath files, see our repository (we copy them) at: http://cvs.sourceforge.net/viewcvs.py/jnode/jnode/core/src/classpath/ It is a mix of classpath HEAD branch and the generic branch (in the 5.0 directory in our repository) The compiler settings are 5.0 source & target. See: http://cvs.sourceforge.net/viewcvs.py/jnode/jnode/core/.settings/ Ewout
We have the same or similar problem! This is a severe problem for us since all our JSP's are compiled using SUN's javac, and our java source using the eclipse compiler. Can be reproduced as follows: Foo.java public interface Foo<T> { public T getIt(); } FooImpl.java: public class FooImpl implements Foo { public String getIt() { return null; } } Bar.java public class Bar { public void doIt() { Object s = new FooImpl().getIt(); } } Compile Foo and FooImpl using eclipse JDT compiler. Compile Bar using SUN javac 1.5.0: >javac Bar.java Bar.java:5: cannot access FooImpl bad class file: .\FooImpl.class undeclared type variable: T Please remove or make sure it appears in the correct subdirectory of the classpath. Object s = new FooImpl().getIt(); ^ 1 error Using javac for all source files succeeds without errors.
Please consider changing the priority for this bug.
Later scenario reproduced. It results from insertion of generic signature attribute for bridge method.
Re: comment 4: why ?
First of all, the example in comment 3 is just a simple case to reproduce the bug, and easy to work around. However, in our code there are other places that are harder (or maybe even impossible) to fix. The main problem is that all our JSP files are runtime compiled using javac. Our web application is based on the usage of JSP files. Since the java code is compiled by Eclipse ande the JSP files are compiled by javac, we cannot start or debug our application from Eclipse any longer. This is a big problem.
I agree this is unhappy, but given it was reported to us very late, it doesn't qualify as a stop ship issue (which it would take to get into 3.1). A workaround is to compile all files with the same compiler (either Eclipse or javac). Note that our compiler can also be used on the command line as a batch compiler. However, this should be fixed in upcoming 3.1.1. We can even post you a patch for it as soon as we have it. Would this be ok ?
Rephrasing beginning of my previous comment. I agree this is unhappy, but given it was reported to us very late, it cannot be addressed for 3.1, as at this stage only stop ship issues can be addressed. Had it been reported earlier, we would have considered it. We are compromising the gain of a fix with the risk of breaking more.
I understand and agree. I'll have a look into using Eclipse to compile out JSP files. We use Jasper, so technically it must be possible. Is it possible to configure Eclipse to use javac instead of the built in compiler? I am looking forward to receiving a patch.
For me not having this fixed in 3.1 means that I cannot start to use 3.1 and i have to stick with 3.1M7 until it is fixed. So unhappy... certainly please submit the patch as soon as possible. Thanks Ewout
Re: comment 10. No, you cannot use javac in place of Eclipse built-in compiler, other than using Ant scripts. Re: comment 11. I wonder how M7 did work for it. It was broken since ever... need to investigate.
Created attachment 24024 [details] Patch for SyntheticMethodBinding Disable the generic signature generation for bridge methods.
(In reply to comment #13) > Created an attachment (id=24024) [edit] > Patch for SyntheticMethodBinding > > Disable the generic signature generation for bridge methods. Can you provide a compiled version. I've never build Eclipse myself (and I hope i don't have to start now) Ewout
Reproduced upon initial test case. Also checked that 3.1 M7 generates different contents for String.class than 3.1 RC4 does. Differences of interest summarized in attachment.
Created attachment 24033 [details] javap differences
The patch works for us. Thank you for you quick and effective response.
Problem got introduced between v_559 and v_560.
Got it. Problem got introduced with fix for bug 96646. The bogus signature was tagged on the bridge method, but the corresponding attribute was never generated. Our fix therefore looks adequate, and is fully understood.
Created attachment 24035 [details] Differences between M7 and RC4 on smaller testcase
Regression tests: //https://bugs.eclipse.org/bugs/show_bug.cgi?id=101794 public void test772() { this.runConformTest( new String[] { "X.java", "interface Foo<T> {\n" + " public T getIt();\n" + "}\n" + "\n" + "class FooImpl implements Foo {\n" + " public String getIt() {\n" + " return null;\n" + " }\n" + "}\n" + "public class X {\n" + " public void doIt() {\n" + " Object s = new FooImpl().getIt();\n" + " }\n" + "}\n", }, ""); this.runConformTest( new String[] { "X.java", "public class X {\n" + " public void doIt() {\n" + " Object s = new FooImpl().getIt();\n" + " }\n" + "}\n", }, "", null, false, null); String expectedOutput = " // Method descriptor #18 ()Ljava/lang/Object;\n" + " // Stack: 1, Locals: 1\n" + " public bridge synthetic Object getIt();\n" + " 0 aload_0\n" + " 1 invokevirtual FooImpl.getIt() : java.lang.String [20]\n" + " 4 checkcast java.lang.Object [4]\n" + " 7 areturn\n" + " Line numbers:\n" + " [pc: 0, line: 1]\n"; try { File f = new File(OUTPUT_DIR + File.separator + "FooImpl.class"); byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); int index = result.indexOf(expectedOutput); if (index == -1 || expectedOutput.length() == 0) { System.out.println(Util.displayString(result, 3)); } if (index == -1) { assertEquals("Wrong contents", expectedOutput, result); } } catch (org.eclipse.jdt.core.util.ClassFormatException e) { assertTrue(false); } catch (IOException e) { assertTrue(false); } } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=101794 - variation public void test773() { this.runConformTest( new String[] { "X.java", "interface Foo<T extends Exception> {\n" + " public T getIt() throws T;\n" + "}\n" + "\n" + "class FooImpl implements Foo {\n" + " public NullPointerException getIt() {\n" + " return null;\n" + " }\n" + "}\n" + "public class X {\n" + " public void doIt() {\n" + " Object s = new FooImpl().getIt();\n" + " }\n" + "}\n", }, ""); this.runConformTest( new String[] { "X.java", "public class X {\n" + " public void doIt() {\n" + " Object s = new FooImpl().getIt();\n" + " }\n" + "}\n", }, "", null, false, null); String expectedOutput = " // Method descriptor #18 ()Ljava/lang/Exception;\n" + " // Stack: 1, Locals: 1\n" + " public bridge synthetic Exception getIt() throws java.lang.Exception;\n" + " 0 aload_0\n" + " 1 invokevirtual FooImpl.getIt() : java.lang.NullPointerException [23]\n" + " 4 checkcast java.lang.Exception [21]\n" + " 7 areturn\n" + " Line numbers:\n" + " [pc: 0, line: 1]\n"; try { File f = new File(OUTPUT_DIR + File.separator + "FooImpl.class"); byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); int index = result.indexOf(expectedOutput); if (index == -1 || expectedOutput.length() == 0) { System.out.println(Util.displayString(result, 3)); } if (index == -1) { assertEquals("Wrong contents", expectedOutput, result); } } catch (org.eclipse.jdt.core.util.ClassFormatException e) { assertTrue(false); } catch (IOException e) { assertTrue(false); } }
Considering for 3.1 rebuild.
Olivier/Kent - pls review the change
Patch looks good.
Verified that the bridge method compareTo doesn't have a signature attribute anymore. Verified in I20050627-1435
Reporters, could you please verify that the latest build no longer has this issue ?
It seems to work fine now. Thanks for the quick response. Ewout
*** Bug 102022 has been marked as a duplicate of this bug. ***