Bug 488097 - Enum in interface: cannot cast the outer type to a reference type
Summary: Enum in interface: cannot cast the outer type to a reference type
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: LTWeaving (show other bugs)
Version: 1.8.5   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-02-19 06:29 EST by Frank Benoit CLA
Modified: 2016-03-07 12:52 EST (History)
2 users (show)

See Also:


Attachments
trace info (901.83 KB, text/plain)
2016-02-22 13:18 EST, Frank Benoit CLA
no flags Details
See line 6664 (872.18 KB, text/plain)
2016-02-26 13:48 EST, Frank Benoit CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Frank Benoit CLA 2016-02-19 06:29:01 EST
Feb 19, 2016 12:20:48 PM org.aspectj.weaver.tools.Jdk14Trace error
SCHWERWIEGEND: defineClass
org.aspectj.weaver.BCException: Whilst processing type 'Lprj/lib/sas/itf/ISasDiag$CodeDiscMeasurementResult;' - cannot cast the outer type to a reference type.  Signature=Lprj/lib/sas/itf/ISasDiag; toString()=prj.lib.sas.itf.ISasDiag
when processing type mungers 
when weaving 

	at org.aspectj.weaver.AbstractReferenceTypeDelegate.getFormalTypeParametersFromOuterClass(AbstractReferenceTypeDelegate.java:110)
	at org.aspectj.weaver.bcel.BcelObjectType.ensureGenericSignatureUnpacked(BcelObjectType.java:772)
	at org.aspectj.weaver.bcel.BcelObjectType.getSuperclass(BcelObjectType.java:231)
	at org.aspectj.weaver.ReferenceType.getSuperclass(ReferenceType.java:987)
	at org.aspectj.weaver.bcel.BcelWeaver.weaveParentsFor(BcelWeaver.java:1300)
	at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1119)
	at org.aspectj.weaver.tools.WeavingAdaptor.getWovenBytes(WeavingAdaptor.java:527)
	at org.aspectj.weaver.tools.WeavingAdaptor.weaveClass(WeavingAdaptor.java:363)
	at org.aspectj.weaver.loadtime.WeavingURLClassLoader.defineClass(WeavingURLClassLoader.java:136)
	at org.aspectj.weaver.bcel.ExtensibleURLClassLoader.defineClass(ExtensibleURLClassLoader.java:97)
	at org.aspectj.weaver.bcel.ExtensibleURLClassLoader.findClass(ExtensibleURLClassLoader.java:52)



This is the interface:


public interface ISasDiag {
		
	void checkInternalErrorCodes();
	void checkInternalErrorCodes(IErrh[] error_codes);
	void checkInternalErrorFilterBits();
	void checkInternalErrorFilterBits(IErrh[] error_codes);
	public enum CodeDiscMeasurementResult{
	    MEAS_E_OK(0),
	    MEAS_E_PENDING(1),
	    MEAS_E_BUSY(2),
	    MEAS_E_TIMEOUT_MC2_ACK(3),
	    MEAS_E_TIMEOUT_WHILE_WAITING(4),
	    MEAS_E_TIMEOUT_WHILE_POLLING(5),
	    MEAS_E_ILLEGAL_ENCODER_STATE(6),
	    MEAS_E_DIFFERENCE_OVERFLOW(7),
	    MEAS_E_UNEXPECTED_DIR_CHANGE(8);
	    public int value;

	    CodeDiscMeasurementResult(int value){
			this.value = value;
	    }
	}

	public enum CodeDiscMeasurementMode{
	    NORMAL(0),
	    DEGRADATION(1);
	    public int value;

	    CodeDiscMeasurementMode(int value){
		this.value = value;
	    }
	}

	void codeDiscMeasurementResult(CodeDiscMeasurementMode mode, SasDiagRangeCheck min, SasDiagRangeCheck max);

	void codeDiscMeasurementStart(double acceleration_angle, CodeDiscMeasurementResult result, SasDiagRangeCheck min, SasDiagRangeCheck max);
	
	void DutResetOccured();
	
	void eraseInternalErrorCodes();

	String getSwBuildDate();

	String getSwVersion();

	void readCodeDiscValueRaw();

	void readGearWheelAngle();

	void readGearWheelSensorValuesRaw();

	void readRawAdcValue();

	void securityAccess();

	void startDiagnosticSession();

}



This interface is not relevant for aspects, but loaded with the WeavingURLClassLoader.
Comment 1 Frank Benoit CLA 2016-02-19 06:31:57 EST
Moving the enum out of the interface into separated files, works around this exception.
Comment 2 Andrew Clement CLA 2016-02-19 12:56:49 EST
I've been playing around this morning trying to recreate this one too. No luck. I'm suspecting it is getting a MissingType representation for prj.lib.sas.itf.ISasDiag and that is why it says it cannot cast it to a reference type. But I can't work out why it would be missing. In all my samples that I've built it is working. I tried with compile time and loadtime weaving to see if there is a difference but the case of an inner enum just works fine. Are you loadtime weaving via the agent or managing the WeavingURLClassLoader yourself? I'm afraid it is probably another case where unless I can recreate it, it is very hard to understand why it is misbehaving. (Glad you have a workaround although I recognize it isn't ideal)
Comment 3 Frank Benoit CLA 2016-02-19 13:04:37 EST
I use the WeavingURLClassLoader, which I extend.

There are many places with enums nested in interfaces. Many of them are part of a generated API. The two failing cases (the other ticket today) are luckily in the manual code part.

If you would have an instrumented version of the weaver, logging out more data or doing more checks, i would be willing to try and report the results.
Comment 4 Andrew Clement CLA 2016-02-19 13:48:07 EST
Actually we could try turning on some debug infrastructure, see if that reveals any clues. Specify: -Dorg.aspectj.tracing.factory=default -Dorg.aspectj.tracing.debug=true -Dorg.aspectj.tracing.enabled=true

And we should get stuff out like this:


10:45:46.823 main - org.aspectj.weaver.bcel.BcelWorld.lookupJavaClass org.aspectj.weaver.ltw.LTWWorld@685f4c2e java.lang.Enum, org.aspectj.apache.bcel.classfile.JavaClass@2344fc66
10:45:46.825 main - org.aspectj.weaver.bcel.BcelWorld.lookupJavaClass org.aspectj.weaver.ltw.LTWWorld@685f4c2e java.lang.Comparable, org.aspectj.apache.bcel.classfile.JavaClass@66d2e7d9
10:45:46.826 main - org.aspectj.weaver.bcel.BcelWorld.lookupJavaClass org.aspectj.weaver.ltw.LTWWorld@685f4c2e java.io.Serializable, org.aspectj.apache.bcel.classfile.JavaClass@6a2bcfcb

I guess I'm interested to see an entry for prj.lib.sas.itf.ISasDiag
Comment 5 Frank Benoit CLA 2016-02-22 13:18:29 EST
Created attachment 259867 [details]
trace info

Please see line 5495, timestamp 19:15:43.603
Comment 6 Andrew Clement CLA 2016-02-26 01:45:22 EST
I was initially confused by the trace as I expected to see stuff coming out of BcelWorld but now I see there is the route through ClassPathManager when looking for classes. Wouldn't you know it that ClassPathManager has no useful trace in it... so I'm using this bug as a chance to enhance the trace messages. If you feel like trying it again with the most recent dev build ( http://www.eclipse.org/downloads/download.php?file=/tools/aspectj/dev/aspectj-DEVELOPMENT-20160225224200.jar ) , you should see some key changes to ClassPathManager trace:

- the constructor to ClassPathManager should print the class path it is using
- the find method in ClassPathManager will print out the names it is looking up and whether it finds them.

I'm hoping either the class path isn't quite right and we can work out why or the classname for these outer classes is wrong and we can work out why. If the type *is* being found successfully we can see where needs instrumenting next. 

Here is some sample output I just obtained showing class path in use and the type being looked up and that it was found:

22:39:33.475 main > o.a.w.b.ClassPathManager.<init> o.a.w.b.ClassPathManager@1c20c684 [/Users/aclement/gits/org.aspectj/loadtime/../weaver/testdata/ltw-classes.jar], null

22:39:33.500 main > o.a.w.b.ClassPathManager.find o.a.w.b.ClassPathManager@1c20c684 org.aspectj.weaver.UnresolvedType[LTWHelloWorld]
22:39:33.500 main < o.a.w.b.ClassPathManager.find o.a.w.b.ClassPathManager$ZipEntryClassFile@1fb3ebeb
Comment 7 Frank Benoit CLA 2016-02-26 05:27:25 EST
yes, i like to try again and support to track this problem down.

I am currently using
org.aspectj.runtime_1.8.5.20150128171000.jar
org.aspectj.weaver_1.8.5.20150128171000.jar
in my eclipse RCP target platform.

Can aspectj-DEVELOPMENT-20160225224200.jar replace them? How?
Comment 8 Andrew Clement CLA 2016-02-26 11:45:19 EST
So you are using the bundle versions from AJDT?

I need to run a quick AJDT rebuild that would produce new versions of those bundles based on the latest AspectJ.
Comment 9 Andrew Clement CLA 2016-02-26 13:22:45 EST
runtime should be the same. But here is a link to a rebuilt org.aspectj.weaver bundle I got from an AJDT build just now: http://www.eclipse.org/downloads/download.php?file=/tools/aspectj/dev/org.aspectj.weaver-1.8.9-20160226101950.jar
Comment 10 Frank Benoit CLA 2016-02-26 13:48:33 EST
Created attachment 259965 [details]
See line 6664

Trace attached with using the latest weaver
Comment 11 Andrew Clement CLA 2016-02-26 14:46:29 EST
That was quick!

So, the trace is working, that is a good start.

> o.a.w.b.ClassPathManager.find o.a.w.b.ClassPathManager@6f9abec4 org.aspectj.weaver.UnresolvedType[prj.lib.sas.itf.ISasDiag]
< o.a.w.b.ClassPathManager.find

E defineClass org.aspectj.weaver.BCException: Whilst processing type 'Lprj/lib/sas/itf/ISasDiag$CodeDiscMeasurementResult;' - cannot cast the outer type to a reference type.  Signature=Lprj/lib/sas/itf/ISasDiag; toString()=prj.lib.sas.itf.ISasDiag class=ISasDiag
when processing type mungers 
when weaving 

We can see the ClassPathManager find did not find the class and that led to the defineClass error. Line 6 of the trace shows the class path that was used to initialize that ClassPathManager - does that class path include the jar that should contain this class? 

The request to weave comes in just before the problem:

> o.a.w.l.WeavingURLClassLoader.defineClass c.p.PrjClassLoader@27e1fb55 prj.lib.sas.itf.ISasDiag$CodeDiscMeasurementResult, byte[1997], null
> o.a.w.t.WeavingAdaptor.weaveClass o.a.w.t.WeavingAdaptor@115ca0cc prj.lib.sas.itf.ISasDiag$CodeDiscMeasurementResult, byte[1997]

Still seem to be missing a few trace points to definitively tie together the WeavingURLClassLoader and the ClassPathManager instances.  But the trace points near the top imply that WeavingURLClassLoader being asked to weave the inner class is using the ClassPathManager that is having problems:

> o.a.w.l.WeavingURLClassLoader.defineClass c.p.PrjClassLoader@27e1fb55 config.Config, byte[490], null
> o.a.w.t.WeavingAdaptor.weaveClass o.a.w.t.WeavingAdaptor@115ca0cc config.Config, byte[490]
> o.a.w.b.BcelWeaver.weave o.a.w.b.BcelWeaver@23e45e8b o.a.w.t.WeavingAdaptor$WeavingClassFileProvider@6c6ef361
> o.a.w.b.BcelWeaver.weaveAndNotify o.a.w.b.BcelWeaver@23e45e8b o.a.w.b.UnwovenClassFile@567b2362, o.a.w.b.BcelObjectType@304a48d6, o.a.w.t.WeavingAdaptor$WeavingClassFileProvider$1@67e945e
> o.a.w.b.ClassPathManager.find o.a.w.b.ClassPathManager@6f9abec4 org.aspectj.weaver.UnresolvedType[java.lang.annotation.Retention]

So I guess I'm wondering how does it make sense that the weaving url class loader being asked to weave the inner class can't see the outer class.
Comment 12 Frank Benoit CLA 2016-02-26 15:01:37 EST
The listed paths in line 6 do not contain any of the weaved classes.

My class loader is like this:

public class PrjClassLoader extends WeavingURLClassLoader {

    public PrjClassLoader( ClassLoader parent, File prjDir ) {
        super( /* base.jar+aj-runtime */, /* base.jar */, parent );
        ...
    }

    public InputStream getResourceFromJar(String name) {
        // ...
    }

    @Override
    protected byte[] getBytes(String name) throws IOException {
        // ...
    }
    @Override
    public URL getResource(String name) {
        // ...
    }
}

The base.jar contains the aspect code.

I override the getBytes(name) to find my classes.
They come from two sources:
Generated code from a config.jar
Manual code from the 'bin' directory, which contains the compiled classes created with Ant iajc task.

However, this mechanism works loading hundreds of classes. 
Even nested enums in interfaces are found in several places, so this is not a problem in general.
Comment 13 Andrew Clement CLA 2016-03-07 12:52:07 EST
> The listed paths in line 6 do not contain any of the weaved classes.

I'm not clear on whether you include prj.lib.sas.itf.ISasDiag when you say that? Should ISasDiag be found when looking through that classpath? If it should then I need more diagnostics on why it wasn't found there. If it shouldn't then need to look elsewhere.