I encountered the same problem.
I tracked the problem to the jar glassfish/modules/dol.jar
(sources). The class com.sun.enterprise.deployment.annotation.introspection.ConstantPoolInfo
within this jar is responsible for testing classes on relevant annotations while deployment.
Problem:
The class does this by byte-wise reading and interpreting a special part of the .class
files: the constant pool (JVM spec). The pool contains "values such as numbers of all sorts, strings, identifier names, references to classes and methods, and type descriptors" (Wiki). This includes the class names of annotations.
The problem is, that the possible content of the constant pool increased with Java 7 and some additional entry types were added to support script languages with the JVM. Those entries (Method handle, Method type and InvokeDynamic (ids 15, 16 and 18)) are not supported by ConstantPoolInfo
yet. When reading and checking the type identifier byte of one of those constant pool entries, the class simply logs the warning "Unknow [sic] type constant pool x at position i" and proceeds processing with the next byte, missing to skip bytes belonging to the current type's data structure (they are not relevant anyway).
This leads to a complete mess up, as the next byte which should have been skipped is interpreted as type identifier.
In some situations, the wrongly interpreted byte leads to the execution of the code for the "UTF 8/ASCII"-entry case, with interprets the next two bytes as the length of a String in the constant pool and then wants to read that String. And this is where the BufferUnderflowException
comes from: The input source containing the constant pool's data may not hold as may bytes as requested.
Where and when:
There was no problem with this when using Java 7 code, as the usual developer/compiler did not produce byte code which needed the additional constant pool entry types.
With Java 8 this changed: Lambdas and methdod references make use of it.
For some reason I did not examine, the problem does not happen with lambdas in war-modules but only with ejb-modules. Probably, the introspection of the class files is not done there - at least not based on ConstantPoolInfo.
Solution:
I opened a bug report: https://java.net/jira/browse/GLASSFISH-21510.
I don't have a solution other than to refrain from using lambdas/method references (or anything that compiles to invokedynamic
bytecode) in ejb modules.
Refactoring the code until it only produces warnings and no exception may help but I don't consider it a clean solution. It may break again with any code change or jdk update. Apart from that, the inspection of the class is still broken and may cause other problems.
[TL;DR]
Remove lambdas/method references from ejb-projects.
[/TL;DR]
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…