Community
Participate
Working Groups
Build Identifier: M20100909-0800 When using the scala-libary.jar in a java project, the org.eclipse.jdt.ui.AllCompletionProposalComputer throws an exception in certain cases. One of this cases is described in the "Steps to Reproduce". The autocompletion works fine in other IDEs. Nevertheless I will report this at the scala tracker too, because I don't know if this is a problem with the scala-libary.jar or eclipse. Reproducible: Always Steps to Reproduce: 1. Create a new java project 2. Add the scala-libary.jar to the project (from "http://www.scala-lang.org/downloads" - version 2.8.1.final) 3. Create the following test class: package simple; import scala.collection.immutable.Nil; public class Test { public static void main(String[] args) { scala.collection.immutable.List<int> myList = new Nil(); } } 4. Try to activate the autocompletion on the variable "myList"
> 3. Create the following test class: [..] This is not a valid Java source file. We will not pursue the Scala-related problems in JDT, but I'm keeping this bug for the ClassCastException that shows up when you follow the given steps 1-3. Although the file has syntax errors and the scala-library.jar may contain invalid class files, the compiler should not write to the log and the compilation error "Internal compiler error: java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.initializeTypeVariable(BinaryTypeBinding.java:956)" could also be improved. java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.initializeTypeVariable(BinaryTypeBinding.java:956) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.createTypeVariables(BinaryTypeBinding.java:659) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.createMethod(BinaryTypeBinding.java:497) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.createMethods(BinaryTypeBinding.java:602) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.cachePartsFrom(BinaryTypeBinding.java:337) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.createBinaryTypeFrom(LookupEnvironment.java:678) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.createBinaryTypeFrom(LookupEnvironment.java:657) at org.eclipse.jdt.internal.compiler.Compiler.accept(Compiler.java:295) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:138) at org.eclipse.jdt.internal.compiler.lookup.PackageBinding.getTypeOrPackage(PackageBinding.java:183) at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.findImport(CompilationUnitScope.java:486) at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.findSingleImport(CompilationUnitScope.java:540) at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInImports(CompilationUnitScope.java:368) at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInTypes(CompilationUnitScope.java:465) at org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:752) at org.eclipse.jdt.internal.compiler.ProcessTaskManager.run(ProcessTaskManager.java:137) at java.lang.Thread.run(Thread.java:619)
The signature of the method: // Method descriptor #295 (Lscala/PartialFunction;)Lscala/PartialFunction; // Signature: <A1:IB1:Ljava/lang/Object;>(Lscala/PartialFunction<TA1;TB1;>;)Lscala/PartialFunction<TA1;TB1;>; // Stack: 2, Locals: 1 public static final scala.PartialFunction orElse(scala.PartialFunction arg0); 0 getstatic scala.collection.immutable.Nil$.MODULE$ : scala.collection.immutable.Nil. [11] 3 aload_0 [arg0] 4 invokevirtual scala.collection.immutable.Nil$.orElse(scala.PartialFunction) : scala.PartialFunction [297] 7 areturn is boggus. I investigate what is the cleanest way to reject that .class file.
Would this be a better error handling ? The class file Nil contains a signature '<A1:IB1:Ljava/lang/Object;>(Lscala/PartialFunction<TA1;TB1;>;)Lscala/PartialFunction<TA1;TB1;>;' ill-formed at position 6
javac compiles the code, but doesn't run it. So I prefer to get an answer that tells me that something is wrong with the .class file.
The corrupted signature was properly detected, but could not be reported since it was failing before that. I would report a bug against scala to find out how this signature was computed.
Created attachment 185433 [details] Proposed fix
Patch is wrong. Will rework it.
Created attachment 186185 [details] Proposed fix I think the previous patch was right. Srikanth, please verify. This is a bug in the scala compiler in the way the class file is built. This patch simply try to improve the way the Eclipse compiler is handling the boggus class file.
Released for 3.7M5.
> Srikanth, please verify. > > This is a bug in the scala compiler in the way the class file is built. This > patch simply try to improve the way the Eclipse compiler is handling the boggus > class file. Agree with the patch.
I'm geting a similar error in 3.6.1 with a java project using scala library 2.8.1: java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.initializeTypeVariable(BinaryTypeBinding.java:944) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.createTypeVariables(BinaryTypeBinding.java:647) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.createMethod(BinaryTypeBinding.java:484) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.createMethods(BinaryTypeBinding.java:598) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.cachePartsFrom(BinaryTypeBinding.java:329) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.createBinaryTypeFrom(LookupEnvironment.java:674) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.createBinaryTypeFrom(LookupEnvironment.java:653) at org.eclipse.jdt.internal.compiler.Compiler.accept(Compiler.java:295) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:108) at org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding.resolve(UnresolvedReferenceBinding.java:49) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveType(BinaryTypeBinding.java:122) at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.resolve(ParameterizedTypeBinding.java:851) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveType(BinaryTypeBinding.java:100) at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.resolve(ParameterizedTypeBinding.java:856) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveType(BinaryTypeBinding.java:100) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveTypesFor(BinaryTypeBinding.java:1040) at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.getExactMethod(BinaryTypeBinding.java:795) at org.eclipse.jdt.internal.compiler.lookup.Scope.findExactMethod(Scope.java:908) at org.eclipse.jdt.internal.compiler.lookup.Scope.getMethod(Scope.java:2255) at org.eclipse.jdt.internal.compiler.ast.MessageSend.resolveType(MessageSend.java:403) at org.eclipse.jdt.internal.compiler.ast.LocalDeclaration.resolve(LocalDeclaration.java:186) at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolveStatements(AbstractMethodDeclaration.java:451) at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.resolveStatements(MethodDeclaration.java:212) at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolve(AbstractMethodDeclaration.java:410) at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1147) at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1235) at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.resolve(CompilationUnitDeclaration.java:540) at org.eclipse.jdt.internal.compiler.Compiler.resolve(Compiler.java:883) at org.eclipse.jdt.internal.compiler.Compiler.resolve(Compiler.java:928) at org.eclipse.jdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:189) at org.eclipse.jdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:255) at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.makeConsistent(ReconcileWorkingCopyOperation.java:190) at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation(ReconcileWorkingCopyOperation.java:89) at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:728) at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:788) at org.eclipse.jdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1244) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:126) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.access$0(JavaReconcilingStrategy.java:108) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy$1.run(JavaReconcilingStrategy.java:89) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:87) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.initialReconcile(JavaReconcilingStrategy.java:178) at org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.initialReconcile(CompositeReconcilingStrategy.java:114) at org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.initialReconcile(JavaCompositeReconcilingStrategy.java:133) at org.eclipse.jface.text.reconciler.MonoReconciler.initialProcess(MonoReconciler.java:105) at org.eclipse.jdt.internal.ui.text.JavaReconciler.initialProcess(JavaReconciler.java:398) at org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run(AbstractReconciler.java:173)
Has there been a bug logged against the scala compiler? This all I could find: https://codereview.scala-lang.org/fisheye/cru/SCL-478 but I haven't found a bug report for the scala compiler problem causing this.
(In reply to comment #2) > The signature of the method: > // Method descriptor #295 (Lscala/PartialFunction;)Lscala/PartialFunction; > // Signature: > <A1:IB1:Ljava/lang/Object;>(Lscala/PartialFunction<TA1;TB1;>;)Lscala/PartialFunction<TA1;TB1;>; > // Stack: 2, Locals: 1 > public static final scala.PartialFunction orElse(scala.PartialFunction arg0); > 0 getstatic scala.collection.immutable.Nil$.MODULE$ : > scala.collection.immutable.Nil. [11] > 3 aload_0 [arg0] > 4 invokevirtual > scala.collection.immutable.Nil$.orElse(scala.PartialFunction) : > scala.PartialFunction [297] > 7 areturn > > > is boggus. I investigate what is the cleanest way to reject that .class file. can you please quickly describe what is the error/specs-deviation in that signature? I would help me as a starting point for further investigation within the scala community, but before starting reading the jvm bytecode spec I would like to have a glimpse of the issue.
Hello. The scala ticket is: https://lampsvn.epfl.ch/trac/scala/ticket/4067 The signatures in question are definitely invalid. I just checked in some code which suppresses signature generation entirely on invalid signatures. Hopefully it won't be long before it isn't suppressing any, but until then you ought to have less troublesome bytecode.
The boggus part is: <A1:IB1:Ljava/lang/Object;> A FormalTypeParameter should be an identifier (A1) followed by a type descriptor. It is illegal to get a primitive type there (here int: I). FormalTypeParameters: <FormalTypeParameter+> FormalTypeParameter: Identifier ClassBound InterfaceBound* Hope this clarify what is wrong.
I implemented a small tool which patches the scala-library.jar classes, as a workaround until the scalac compiler fix and/or eclipse 3.6 is released. http://www.coldcode.net/2011/01/scala-generics-and-eclipse.html
(In reply to comment #15) > The boggus part is: > <A1:IB1:Ljava/lang/Object;> > A FormalTypeParameter should be an identifier (A1) followed by a type > descriptor. It is illegal to get a primitive type there (here int: I). > > FormalTypeParameters: > <FormalTypeParameter+> > > FormalTypeParameter: > Identifier ClassBound InterfaceBound* > > Hope this clarify what is wrong. Thank you a lot. That explains the lack of the semicolon, it's not needed with primitive type codes since they don't require an varying length argument. For now I hardcoded my signature patcher it for ":I" and ":J" cases since I saw those cases in real-world the signatures, but now that I know what those letters stand for I can improve that :-) (One life is really not enough to learn all...)
Verified for 3.7 M5 via code inspection.
Hi - sorry I didn't get back to update the ticket, but I fixed the compiler the same day I commented about the bug. Soon I'll have the compiler running the signature validater on all builds so this shouldn't come up again. (Semantically invalid signatures will still be possible of course.)