Skip to content

Instantly share code, notes, and snippets.

@odrotbohm
Created August 8, 2019 20:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odrotbohm/60cfb8fbb8025dc374ebce213e9893ab to your computer and use it in GitHub Desktop.
Save odrotbohm/60cfb8fbb8025dc374ebce213e9893ab to your computer and use it in GitHub Desktop.

Hibernate Enhancer problem on Java 11

Spring RESTBucks uses Hibernate’s bytecode enhancement to avoid runtime overhead in favor of a build time step. This works fine on JDK 8. However, if the project is built on JDK 11, starting it fails with:

Caused by: java.lang.IllegalAccessError: Update to non-static final field org.springsource.restbucks.payment.Payment.order attempted from a different method ($$_hibernate_write_order) than the initializer method <init>
	at org.springsource.restbucks.payment.Payment.$$_hibernate_write_order(Payment.java) ~[classes/:na]
	at org.springsource.restbucks.payment.Payment.<init>(Payment.java:53) ~[classes/:na]
	at org.springsource.restbucks.payment.CreditCardPayment.<init>(CreditCardPayment.java:37) ~[classes/:na]
	... 27 common frames omitted

Steps to reproduce:

  1. git clone https://github.com/odrotbohm/spring-restbucks

  2. cd spring-restbucks

  3. git checkout hibernate-enhance-problem

  4. mvn spring-boot:run

Preliminary analysis

Obviously Hibernate’s bytecode enhancement does something to the default constructor of Payment. Apparently some method ($$_hibernate_write_order) gets injected that in turn tries to manipulate a final field.

Questions

  • Why does the same setup work on JDK 8?

  • Why does the method manipulate a final field, which by definition is not allowed other than from a constructor?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment