Bug 561599 - java.lang.IllegalAccessError: Update to static final field attempted from a different method (ajc$preClinit1) than the initializer method <clinit>
Summary: java.lang.IllegalAccessError: Update to static final field attempted from a d...
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Runtime (show other bugs)
Version: 1.9.5   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-03-31 02:04 EDT by Mikael Petterson CLA
Modified: 2020-04-22 14:12 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mikael Petterson CLA 2020-03-31 02:04:45 EDT
When we run the testcases in Eclipse or with maven we get the following error:

java.lang.IllegalAccessError: Update to static final field
 com.company.common.rm.Cell.serialVersionUID attempted from a different method (ajc$preClinit1) than the initializer method <clinit>
          at com.company.common.rm.Cell.ajc$preClinit1(Cell.java:1)
          at com.company.common.rm.Cell.ajc$preClinit(Cell.java:1)
          at com.company.common.rm.Cell.<clinit>(Cell.java:1)
          at jdk.internal.reflect.GeneratedSerializationConstructorAccessor8.newInstance(Unknown Source)
          at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
          at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
          at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
          at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:19)
          at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:184)
          at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
          at org.mockito.internal.MockitoCore.mock(MockitoCore.java:63)
          at org.mockito.Mockito.mock(Mockito.java:1908)
          at org.mockito.Mockito.mock(Mockito.java:1817)
          at com.company.common.rm.RmPropsimTest.setUp(RmPropsimTest.java:85)

It is strange since the Cell class does not see below.


public abstract class Cell extends CellAdaptor implements WCell, LCell {

    

    protected Cell(String ldn, Provider provider,
            CellResource cellResource) {
        super(provider, ldn);
       
    }

}

I don't understand why it is complaining about serialVersionUID since class is not serialized or contains one.

//mike
Comment 1 Ning Zhang CLA 2020-04-01 01:29:40 EDT
The component should be compile.

I tried to reproduce it locally, reproduce it from one Enum.
Orginal Enum:
```
public enum ExampleEnum {
    ENUM1,
    EMUM2;

    public static String getAnotherName(ExampleEnum arg) {

        return arg.name() + "_" + AspectUtil.getDeprecatedResult();
    }
}
```
After AspectJ compile:
```
public enum ExampleEnum {
  ENUM1, EMUM2;
  
  static {
    ajc$preClinit();
  }
  
  private static final long serialVersionUID;
  
  public static String getAnotherName(ExampleEnum arg) {
    if (DeprecatedMethodsAspect.ajc$if$a6adfc1())
      DeprecatedMethodsAspect.aspectOf().ajc$before$com_ericsson_commonlibrary_statisticscollectorframework_aspectj_DeprecatedMethodsAspect$1$b9499fc0(Factory.makeJP(ajc$tjp_0, null, null)); 
    return String.valueOf(arg.name()) + "_" + AspectUtil.getDeprecatedResult();
  }
}
```

This strange serialVersionUID is generated.
It only happens on Java11, can not generate on Java8.
Comment 2 Andrew Clement CLA 2020-04-01 11:50:36 EDT
The control for AspectJ to generate serialVersionUID is -XaddSerialVersionUID - you aren't setting that somewhere are you?
Comment 3 Ning Zhang CLA 2020-04-01 21:50:36 EDT
Andrew, you are right.
serialVersionUID is generated -XaddSerialVersionUID.
So I think it is runtime issue now.

I did more comparisons, generated class with both compliance level 8 & 11,
after decompile, find both have below:

  static {
    ajc$preClinit();
  }
  
  private static final long serialVersionUID;

But find runtime errors with compliance level 11.
1. Compliance level 8, run successfully on both JRE8 and JRE11.
2. Compliance level 11, met issue same as Mikael mentioned: can not update serialVersionUID during class initialization.
Comment 4 Andrew Clement CLA 2020-04-22 14:07:15 EDT
So the workaround is (unfortunately) don't set -XaddSerialVersionUID. The only real way to fix this I think is inline the serial version code into the actual clinit, but at the same time mark it some way so that the code doesn't become a candidate for join point shadows that might match a pointcut.
Comment 5 Andrew Clement CLA 2020-04-22 14:12:00 EDT
Checking the docs I see it says "Causes the compiler to calculate and add the SerialVersionUID field to any type implementing Serializable that is affected by an aspect. " - is it perhaps adding it to too many types I wonder? Worth me checking...

Just looked and tested it and indeed it will only do it if they are Serializable, not any class.