Bug 490675 - AJC creates class files that cause ClassFormatError exceptions when using around advice on default methods in an interface
Summary: AJC creates class files that cause ClassFormatError exceptions when using aro...
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.8.9   Edit
Hardware: PC Windows NT
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-03-30 07:39 EDT by selvaraj chennappan CLA
Modified: 2016-04-04 18:40 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description selvaraj chennappan CLA 2016-03-30 07:39:15 EDT
Caused by: java.lang.ClassFormatError: Method getAll_aroundBody0 in class ReadHandler has illegal modifiers: 0x1A
	
Bug 475200 says it has fixed .However I am getting the same error in 1.8.9 also.

I have added aspect-1.8.9.jar in classpath as well.

2. Pointcut expression to exclude interface default methods?
Comment 1 Andrew Clement CLA 2016-03-30 14:54:05 EDT
The testcode in that bug is working fine and I think there were another couple of variants of it that I have also fixed under other bugs (all those fixes are in 1.8.9). Are you able to share the kind of declarations you have that are causing the problem?

I probably don't need actualy code, I just need the declaration of the default method (modifiers, signature) and the declaration of the pointcut/around advice that is applying to it.

Adding aspectj-1.8.9.jar is probably not going to fix it since that is a jar of jars, you need to add aspectjtools-1.8.9.jar or aspectjweaver-1.8.9.jar from inside it to pickup the 1.8.9 modifications.

I'd rather fix it than get too far into excluding default methods, since it is a real problem but you could probably use a type category type pattern as described in the 1.6.9 readme (attach an !is(InterfaceType) to your pointcut clause perhaps):

Type category type patterns

This is the ability to narrow the types of interest so that interfaces can be ignored, or inner types, or classes or aspects. There is now a new is() construct that enables this:

execution(* (!is(InnerType)).m(..)) {}
!within(* && is(InnerType)) {}
Options for use in is() are: ClassType, AspectType, InterfaceType, InnerType, AnonymousType, EnumType, AnonymousType.

Note: It is important to understand that "!within(is(InnerType))" and "within(!is(InnerType))" are not the same. The latter one is unlikely to be what you want to use. For example here:

class Boo {
  void foo() {}
  class Bar {
    void foo() {}
  }
}
Bar.foo() will match within(!is(InnerType)) because within considers all surrounding types (so although Bar doesn't match the pattern, the surrounding Boo will match it). Bar.foo() will not match !within(is(InnerType)) because Bar will match the pattern and then the result of that match will be negated.
Comment 2 selvaraj chennappan CLA 2016-04-01 02:45:35 EDT
public interface ReadHandler<E, R> {

	public R get(final E request);
	
	public default R getAll(final E request){
		throw new UnsupportedOperationException();
	}

}


@Pointcut("execution(public !static* com.xyz.abc..*.*(..)) ")
	private void abc(){};

@Around("abc()")
Comment 3 Andrew Clement CLA 2016-04-04 18:40:41 EDT
Thanks for the code. I converted that snippet to two source files:

-- ReadHandler.java --
public interface ReadHandler<E, R> {

	public R get(final E request);

	public default R getAll(final E request){
		throw new UnsupportedOperationException();
	}

}
--

-- X.java --
import org.aspectj.lang.annotation.*;

class C implements ReadHandler {
  public Object get(Object r) {
    return null;
  }
}

@Aspect
public class X {
  public static void main(String []argv) {
    new C().get("foo");
  }

  @Pointcut("execution(public !static * ReadHandler.*(..)) ")
  private void abc(){};

  @Around("abc()")
  public Object around() {
    return null;
  }
}
--

I can compile that and run it just fine on 1.8.8/1.8.9:
ajc -1.8 X.java ReadHandler.java -showWeaveInfo
Join point 'method-execution(java.lang.Object C.get(java.lang.Object))' in Type 'C' (X.java:4) advised by around advice from 'X' (X.java:19)

Join point 'method-execution(java.lang.Object ReadHandler.getAll(java.lang.Object))' in Type 'ReadHandler' (ReadHandler.java:6) advised by around advice from 'X' (X.java:19)

java X

If I try that with 1.8.7 or earlier, it fails.  Are you sure you are running with the 1.8.8/1.8.9 compiler?