After a successful build and enhancement step, i expected the JPA and the Datanucleus plugin to work smoothly. But then i get a java.lang.VerifyError when i run the App Engine local development server. Is there a fix for this?
Enhancment Result:
[datanucleusenhancer] INFO: DataNucleus Enhancer (version 3.0.1) : Enhancement of classes
[datanucleusenhancer] Dec 14, 2020 10:19:38 AM org.datanucleus.enhancer.AbstractClassEnhancer save
[datanucleusenhancer] INFO: Writing class file "/home/*****/Documents/AppEngineApps/java/*******/war/WEB-INF/classes/model/Category.class" with enhanced definition
[datanucleusenhancer] DataNucleus Enhancer completed with success for 1 classes. Timings : input=134 ms, enhance=43 ms, total=177 ms. Consult the log for full details
[datanucleusenhancer] Dec 14, 2020 10:19:38 AM org.datanucleus.enhancer.DataNucleusEnhancer addMessage
[datanucleusenhancer] INFO: DataNucleus Enhancer completed with success for 1 classes. Timings : input=134 ms, enhance=43 ms, total=177 ms. Consult the log for full details
System Info
# java -version
openjdk version "1.8.0_272"
OpenJDK Runtime Environment (build 1.8.0_272-b10)
OpenJDK 64-Bit Server VM (build 25.272-b10, mixed mode)
# gcloud --version
Google Cloud SDK 319.0.0
alpha 2020.11.13
app-engine-java 1.9.83
app-engine-python 1.9.91
app-engine-python-extras 1.9.91
beta 2020.11.13
bigtable
bq 2.0.62
cbt 0.9.0
cloud-build-local 0.5.2
cloud-datastore-emulator 2.1.0
core 2020.11.13
datalab 20190610
gsutil 4.55
kubectl 1.16.13
Enhancement snippet in Ant build file
<path location="${lib.dir}/datanucleus-enhancer-3.0.1.jar"
id="tools.class.path" />
<path id="enhancer.classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
<pathelement location="${class.dir}" />
</path>
<target name="datanucleusenhance" depends="compile"
description="DataNucleus enhancement">
<taskdef name="datanucleusenhancer" classpathref="enhancer.classpath"
classname="org.datanucleus.enhancer.tools.EnhancerTask" />
<datanucleusenhancer failonerror="true" api="JPA">
<classpath>
<path refid="enhancer.classpath" />
</classpath>
<fileset dir="${class.dir}">
<include name="model/*.class" />
</fileset>
</datanucleusenhancer>
</target>
Error
Caused by:
java.lang.VerifyError: Expecting a stackmap frame at branch target 16
Exception Details:
Location:
model/Category.jdoIsDetached()Z @4: ifnonnull
Reason:
Expected stackmap frame at this location.
Bytecode:
0x0000000: 2ab4 00a5 c700 0c2a b400 b1c6 0005 04ac
0x0000010: 03ac
Content of lib directory
war/WEB-INF/lib/appengine-api.jar
war/WEB-INF/lib/appengine-api-labs.jar
war/WEB-INF/lib/appengine-jsr107cache-0.0.0.jar
war/WEB-INF/lib/appengine-tools-api.jar
war/WEB-INF/lib/asm-3.3.1.jar
war/WEB-INF/lib/datanucleus-api-jpa-3.0.6.jar
war/WEB-INF/lib/datanucleus-appengine-2.0.0-final.jar
war/WEB-INF/lib/datanucleus-core-3.0.6.jar
war/WEB-INF/lib/datanucleus-enhancer-3.0.1.jar
war/WEB-INF/lib/geronimo-jpa_2.0_spec-1.0.jar
war/WEB-INF/lib/jdo-api-3.0.jar
war/WEB-INF/lib/jsr107cache-1.1.jar
war/WEB-INF/lib/org.apache.taglibs.taglibs-standard-impl-1.2.5.jar
war/WEB-INF/lib/org.apache.taglibs.taglibs-standard-spec-1.2.5.jar
war/WEB-INF/lib/servlet-api-3.1.jar
war/WEB-INF/lib/transaction-api-1.1.jar
I found that the jars provided by Google for the enhancement are outdated. That is the reason why the enhanced classes do not pass the bytecode verification of the newer JVMs. The solution is to download the latest version of
datanucleus-appengine.jarfrom the Maven repository plus the latest versions of all of it's dependencies: the dependencies are shown on the download page. This worked perfectly for me.