Bug 153490 - IllegalStateException thrown: How come we're in AsmObjectType resolving an inner type of something that is NOT a AsmObjectType??
Summary: IllegalStateException thrown: How come we're in AsmObjectType resolving an in...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 minor (vote)
Target Milestone: 1.5.3   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-08-10 16:39 EDT by Thomas Zuberbuehler CLA
Modified: 2006-09-25 09:50 EDT (History)
1 user (show)

See Also:


Attachments
Bug reporter's example reworked as a unit test. (951 bytes, application/octet-stream)
2006-08-10 17:50 EDT, Dean Wampler CLA
no flags Details
failing testcase (4.86 KB, patch)
2006-08-29 10:56 EDT, Helen Beeken CLA
no flags Details | Diff
zip containing improved tests (12.16 KB, application/zip)
2006-08-31 04:12 EDT, Helen Beeken CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Zuberbuehler CLA 2006-08-10 16:39:18 EDT
I try out Contract4J 0.5 with AspectJ 1.5.2 (Build 20060629124300) and Eclipse 3.2 (Build M20060629-1905) under Windows XP SP2 and Java 1.5.0_06. So I became following exception. (You will find my testcode below the exception.) I am not sure if this bug related to Contract4J or to AspectJ!?

==== The Exception ====

java.lang.IllegalStateException
at org.aspectj.weaver.asm.AsmDelegate.getFormalTypeParametersFromOuterClass(AsmDelegate.java:465)
at org.aspectj.weaver.asm.AsmDelegate.ensureSignatureUnpacked(AsmDelegate.java:395)
at org.aspectj.weaver.asm.AsmDelegate.getDeclaredInterfaces(AsmDelegate.java:538)
at org.aspectj.weaver.ReferenceType.getDeclaredInterfaces(ReferenceType.java:426)
at org.aspectj.weaver.ResolvedType.getDirectSupertypes(ResolvedType.java:64)
at org.aspectj.weaver.ResolvedType.collectInterTypeMungers(ResolvedType.java:1155)
at org.aspectj.weaver.ResolvedType.getInterTypeMungersIncludingSupers(ResolvedType.java:1134)
at org.aspectj.weaver.ResolvedType.checkInterTypeMungers(ResolvedType.java:1201)
at org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.weaveInterTypeDeclarations(AjLookupEnvironment.java:643)
at org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.weaveInterTypeDeclarations(AjLookupEnvironment.java:519)
at org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.createBinaryTypeFrom(AjLookupEnvironment.java:1058)
at org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.createBinaryTypeFrom(LookupEnvironment.java:480)
at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.accept(Compiler.java:190)
at org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:111)
at org.aspectj.org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding.resolve(UnresolvedReferenceBinding.java:43)
at org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveType(BinaryTypeBinding.java:53)
at org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.getMemberType(BinaryTypeBinding.java:618)
at org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope.findMemberType(Scope.java:928)
at org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope.getBinding(BlockScope.java:449)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference.resolveType(QualifiedNameReference.java:903)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.MessageSend.resolveType(MessageSend.java:326)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression.resolve(Expression.java:829)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolveStatements(AbstractMethodDeclaration.java:422)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.resolveStatements(MethodDeclaration.java:178)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolve(AbstractMethodDeclaration.java:400)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1088)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1137)
at org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.resolve(CompilationUnitDeclaration.java:305)
at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:519)
at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:329)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:887)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:271)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.incrementalBuild(AjBuildManager.java:170)
at org.aspectj.ajde.internal.CompilerAdapter.compile(CompilerAdapter.java:117)
at org.aspectj.ajde.internal.AspectJBuildManager$CompilerThread.run(AspectJBuildManager.java:191)

IllegalStateException thrown: How come we're in AsmObjectType resolving an inner type of something that is NOT a AsmObjectType??

==== My TestCode ====

import org.contract4j5.Contract;
import org.contract4j5.Post;
import org.contract4j5.Pre;

import org.contract4j5.aspects.Contract4J;

// this is a dummy code!!

@Contract
public class Foo {

  private String fooField = null;
  
  @Pre("nr != null")
  public void setFooField(String f) {
    fooField = f; 
  }
  
  @Post("$return != null")
  public String getFooField() {
    return fooField;
  }
  
  public static void main(String[] args) {
    
    Contract4J.setEnabled(Contract4J.TestType.Pre,   true); //1
    Contract4J.setEnabled(Contract4J.TestType.Post,  true); //2 
    Contract4J.setEnabled(Contract4J.TestType.Invar, true); //3
    
    Foo foo = new Foo();
    foo.setFooField(null);
    System.out.println(foo.getFooField());
    
  }
  
}
Comment 1 Dean Wampler CLA 2006-08-10 17:50:05 EDT
Created attachment 47732 [details]
Bug reporter's example reworked as a unit test.
Comment 2 Dean Wampler CLA 2006-08-10 17:53:53 EDT
I've attached a slightly-reworked version of your example as a unit test. No real difference.
I tried with the same AspectJ, Eclipse, and AJDT versions and had no problems (except that one test expression "nr != null" will always fail since "nr" is undefined..). However, there are a few possible differences:
(i) I am using a slightly newer development version of C4J that will released as V0.6 hopefully this weekend. It mostly adds structural improvements that shouldn't be involved in this problem (famous last words...).
(ii) I have occasionally seen similar, but not repeatable compiler errors. Usually a clean rebuild of everything makes it go away.
So, I suspect AspectJ ;) I will try to reproduce it on the actual V0.5 Contract4J release.
Comment 3 Thomas Zuberbuehler CLA 2006-08-10 18:13:00 EDT
Hello

Perhaps, I've found some solution in Bug 140375 (Comment 5, from Heiko Seeberger). With -Xset:activateLightweightDelegates=false no exception will be thrown anymore.

My program don't run without some output, but this is definitely no bug.. Only my greenness with Contract4J I think.. ;)

Thank you.
Comment 4 Thomas Zuberbuehler CLA 2006-08-10 18:16:43 EDT
sorry. of course ' ... don't run with ... ' ;)

what is the work of -Xset:activateLightweightDelegates=false? could it be that I receive therefore no output in my program? 
Comment 5 Adrian Colyer CLA 2006-08-11 03:53:44 EDT
AspectJ keeps a 'world' in which it retains information about the types used in your program (so that it can answer questions about pointcut matching for example). We have several different ways that information about types can be obtained - these are captured by different "delegate" classes that we use like a strategy pattern. We used to only use BCEL for delegates backed by .class files, but for types that we are not going to weave into we now have the option (used by default) of using ASM for 'types not exposed to the weaver'. The flag you are setting turns off this use of ASM for "lighter weight" delegates and falls back on the BCEL strategy. It should make no difference to the output of your program, only the amount of memory used (slightly more with BCEL). This bug is clearly to do with mixing up ASM and BCEL delegates in a way we weren't anticipating - hence why disabling the ASM support makes it go away...
Comment 6 Thomas Zuberbuehler CLA 2006-08-14 08:43:25 EDT
Thank you!
Comment 7 Helen Beeken CLA 2006-08-29 10:53:25 EDT
I've managed to recreate this bug with the AJ version in HEAD and the following simple testcase:

---------------------------------------------------
public aspect A {
	public enum TestType {Pre};
}

public class Foo {

	public static void main(String[] args) {
		A.TestType pre = A.TestType.Pre;
    }

}
----------------------------------------------------

The requirement for recreating this bug is that the aspect is compiled into a jar file which is then placed on the classpath when compiling Foo.
Comment 8 Helen Beeken CLA 2006-08-29 10:56:51 EDT
Created attachment 48965 [details]
failing testcase

Apply to the tests project.

This patch is the test program in the above comment written to fit in with the aj test harness.
Comment 9 Helen Beeken CLA 2006-08-29 11:41:38 EDT
In answer to the exception message "How come we're in AsmObjectType resolving an inner type of something that is NOT a AsmObjectType??", the reason is that the enum is an inner type of an aspect and due to the fix for bug 135001 we "fallbackToLoadingBcelDelegatesForAspects" in BcelWorld line 302 and so create a BcelObjecType for A instead. When we come to resolve the Enum we're not an aspect and so return the AsmDelegate. Consequently the AsmDelegate is an inner type of the BcelObjectType.
Comment 10 Helen Beeken CLA 2006-08-30 08:11:44 EDT
Two possible solutions are:

1. because the aspect is a BcelObjectType then all inner types should consequently be BcelObjectTypes

2. cope with the case when the inner type is an AsmDelegate whose enclosing type is an aspect which is a BcelObjectType
Comment 11 Helen Beeken CLA 2006-08-31 04:12:32 EDT
Created attachment 49142 [details]
zip containing improved tests

This zip contains the following:

* pr153490-tests.txt: apply to the tests project
* jarForFoo.jar, jarForGoo.jar, jarForBar.jar: place in the tests\bugs153\pr153490 directory

These tests replace the previously attached ones as they include more cases:

1. enum is an inner type of an aspect
2. enum is an inner type of a class which is an inner type of an aspect
3. enum is an inner type of an aspect which is an inner type of a class
Comment 12 Andrew Clement CLA 2006-09-13 03:43:19 EDT
I don't think there is a need to force the delegates of inner types to be Bcel ones - the second option in comment #10 is the way to go.  As with other illegal state exceptions, it was in the code to police something we were concerned about - something that might happen in the wild and yet we hadn't been able to cover with tests.  When it arises in the wild, we look at what is happening and decide whether the behaviour is reasonable - if it is then we remove the restriction (effectively considering the 'illegalstate' to be a 'legal state').  So - I've fixed this by allowing the mixing of delegates - the code was a mess to deal with this stuff so I've moved quite a bit of it around, I hope it hasn't introduced new problems but you never know.  if it has then they are likely to be in the use of generic/parmeterized types.

testcases and fixes all in.
Comment 13 Andrew Clement CLA 2006-09-25 09:50:41 EDT
fixes available in dev build.