| Summary: | [1.8][compiler] Race condition causes injection of spurious raw types into the type system. | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Srikanth Sankaran <srikanth_sankaran> |
| Component: | Core | Assignee: | Srikanth Sankaran <srikanth_sankaran> |
| Status: | VERIFIED FIXED | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | jarthana, stephan.herrmann |
| Version: | 4.4 | ||
| Target Milestone: | BETA J8 | ||
| Hardware: | PC | ||
| OS: | Windows 7 | ||
| Whiteboard: | |||
| Bug Depends on: | |||
| Bug Blocks: | 427787 | ||
I have a fairly straightforward fix in the works that simply pulls up a couple of statements before the type is added to the package. Testing underway. Fix released here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=eb0413d7c3f6c8377e410e116826fcfccbec3365. I had some trouble getting this reproduced in a junit - resorted to verifying the fix by rebuilding the JRE from sources instead. Verified as working for Eclipse + Java 8 RC1 using Kepler SR1 + Eclipse Java Development Tools Patch for Java 8 Support (BETA) 1.0.0.v20140220-2054 (I am able to build JRE8 successfully with the above) See that the equivalent race condition in the case of BinaryTypeBinding is already taken care of by the constructor eagerly initializing this.typeVariables to a suitable value. (In reply to Srikanth Sankaran from comment #4) > See that the equivalent race condition in the case of BinaryTypeBinding > is already taken care of by the constructor eagerly initializing > this.typeVariables to a suitable value. Seeing how this is handled for BinaryTypeBinding, I released amended fix that follows the same approach - Any potential for side effects is eliminated. (I did verify there are no material side effects with the original fix as things stand today - but that executes a fair amount of code as opposed to just an inlined pair of statements as in the present fix. I verified that JRE8 builds fine. (In reply to Srikanth Sankaran from comment #5) > Seeing how this is handled for BinaryTypeBinding, I released amended fix > that follows the same approach - Any potential for side effects is > eliminated. Amended fix is here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=ca551e9f50d120a7df024c143f37ec7681949c67 |
In this call stack: SourceTypeBinding.kind() line: 797 LookupEnvironment.convertUnresolvedBinaryToRawType(TypeBinding) line: 605 ParameterizedTypeBinding.swapUnresolved(UnresolvedReferenceBinding, ReferenceBinding, LookupEnvironment) line: 1221 UnresolvedReferenceBinding.setResolvedType(ReferenceBinding, LookupEnvironment) line: 133 PackageBinding.addType(ReferenceBinding) line: 78 ClassScope.buildType(SourceTypeBinding, PackageBinding, AccessRestriction) line: 411 CompilationUnitScope.buildTypeBindings(AccessRestriction) line: 153 LookupEnvironment.buildTypeBindings(CompilationUnitDeclaration, AccessRestriction) line: 190 CompilationUnitResolver(Compiler).accept(ICompilationUnit, AccessRestriction) line: 331 CompilationUnitResolver.accept(ICompilationUnit, AccessRestriction) line: 178 CompilationUnitResolver.accept(ISourceType[], PackageBinding, AccessRestriction) line: 174 LookupEnvironment.askForType(char[][]) line: 147 UnresolvedReferenceBinding.resolve(LookupEnvironment, boolean) line: 103 BinaryTypeBinding.resolveType(TypeBinding, LookupEnvironment, boolean) line: 174 PackageBinding.getTypeOrPackage(char[]) line: 190 ClassScope(Scope).getTypeOrPackage(char[], int, boolean) line: 3296 ClassScope(Scope).getType(char[]) line: 3008 SingleTypeReference.getTypeBinding(Scope) line: 54 SingleTypeReference(TypeReference).internalResolveType(Scope) line: 468 SingleTypeReference(TypeReference).resolveType(ClassScope) line: 559 SingleTypeReference(TypeReference).resolveSuperType(ClassScope) line: 537 ClassScope.findSupertype(TypeReference) line: 1264 ClassScope.connectSuperInterfaces() line: 1030 ClassScope.connectTypeHierarchy() line: 1085 CompilationUnitScope.connectTypeHierarchy() line: 308 LookupEnvironment.completeTypeBindings() line: 228 LookupEnvironment.completeTypeBindings(CompilationUnitDeclaration) line: 260 CompilationUnitResolver(Compiler).accept(ICompilationUnit, AccessRestriction) line: 335 CompilationUnitResolver.accept(ICompilationUnit, AccessRestriction) line: 178 CompilationUnitResolver.accept(ISourceType[], PackageBinding, AccessRestriction) line: 174 LookupEnvironment.askForType(char[][]) line: 147 UnresolvedReferenceBinding.resolve(LookupEnvironment, boolean) line: 103 BinaryTypeBinding.resolveType(TypeBinding, LookupEnvironment, boolean) line: 174 PackageBinding.getTypeOrPackage(char[]) line: 190 MethodScope(Scope).getTypeOrPackage(char[], int, boolean) line: 3296 MethodScope(Scope).getType(char[]) line: 3008 SingleTypeReference.getTypeBinding(Scope) line: 54 SingleTypeReference(TypeReference).internalResolveType(Scope) line: 468 SingleTypeReference(TypeReference).resolveType(BlockScope, boolean) line: 555 MethodScope(Scope).connectTypeVariables(TypeParameter[], boolean) line: 935 SourceTypeBinding.resolveTypesFor(MethodBinding) line: 1793 SourceTypeBinding.methods() line: 1467 SourceTypeBinding.faultInTypesForFieldsAndMethods() line: 855 CompilationUnitScope.faultInTypes() line: 424 CompilationUnitResolver.resolve(CompilationUnitDeclaration, ICompilationUnit, NodeSearcher, boolean, boolean, boolean) line: 1201 CompilationUnitResolver.resolve(ICompilationUnit, IJavaProject, List, NodeSearcher, Map, WorkingCopyOwner, int, IProgressMonitor) line: 693 ASTParser.internalCreateAST(IProgressMonitor) line: 1187 ASTParser.createAST(IProgressMonitor) line: 813 ASTProvider$1.run() line: 548 SafeRunner.run(ISafeRunnable) line: 42 ASTProvider.createAST(ITypeRoot, IProgressMonitor) line: 541 ASTProvider.getAST(ITypeRoot, SharedASTProvider$WAIT_FLAG, IProgressMonitor) line: 484 SharedASTProvider.getAST(ITypeRoot, SharedASTProvider$WAIT_FLAG, IProgressMonitor) line: 132 SelectionListenerWithASTManager$PartListenerGroup.calculateASTandInform(ITypeRoot, ITextSelection, IProgressMonitor) line: 170 SelectionListenerWithASTManager$PartListenerGroup$3.run(IProgressMonitor) line: 155 Worker.run() line: 53 we could conclude that a non-generic type is a generic type and create raw versions of it. This is because, ClassScope.buildType() calls PackageBinding.addType() to add the new source type that is being built *before* its type variables are built. These type variables are consulted by frame 0 i.e SourceTypeBinding.kind() which reads: if (this.typeVariables != Binding.NO_TYPE_VARIABLES) return Binding.GENERIC_TYPE; since this.typeVariables is still null and not initialized with either the special value Binding.NO_TYPE_VARIABLES or to the built type variables in the case of generic type, we would confuse a non-generic type to be a generic type and create raw versions of it. This results various type incompatibilities down the road between List<Type#Raw> and List<Type> For example, while building JRE8 from the sources, we obsreve errors of the form: Type mismatch: cannot convert from List<GarbageCollectorMXBean> to List<GarbageCollectorMXBean> ManagementFactory.java /JDK Source/src/java/lang/management line 415 Java Problem Type mismatch: cannot convert from List<MemoryManagerMXBean> to List<MemoryManagerMXBean> ManagementFactory.java /JDK Source/src/java/lang/management line 399 Java Problem Type mismatch: cannot convert from List<MemoryPoolMXBean> to List<MemoryPoolMXBean> ManagementFactory.java /JDK Source/src/java/lang/management line 386 Java Problem