JDK-4254317 : [Verifier:Old] The result of verification pass 2 is undefined
  • Type: Bug
  • Component: specification
  • Sub-Component: vm
  • Affected Version: 1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 1999-07-15
  • Updated: 2014-02-26
  • Resolved: 2013-08-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8Fixed
Related Reports
Relates :  
Description
Name: akC45999			Date: 07/15/99

The Java Virtual Machine Specification, 5.4.1 Verification reads:

The representation of a class or interface is verified  to ensure that its
binary representation is structurally valid (passes 2 and 3 of 4.9.1).
... 

Verification must detect the following error:

     If the representation of the class or interface does not satisfy the static or
     structural constraints listed in Section 4.8, "Constraints on Java Virtual
     Machine Code," verification throws a VerifyError. 

(end of citation).

But Section 4.8 describes constraints on Code attribute, which are checked
on pass 3. What should be thrown if pass 2 failed, is not defined.

======================================================================

Comments
The text in JVMS2 4.9.1 "Pass 1" became JVMS7 4.8 "Format Checking". JVMS7 4.8 is called on by JVMS7 5.3.5 where ClassFormatError is mandated. The text in JVMS2 4.9.1 "Pass 2" was moved by JSR 202 into a section "Verification of class Files" which appeared as JVMS7 4.10. JVMS7 4.10 is called on by JVMS7 5.4 where VerifyError is mandated, so the result of Pass 2's failure is clearly a VerifyError as prefigured by Gilad's 1999 comment. However, it is worth examining "Pass 2" in more detail. It performs checks on i) final classes/methods and superclass existence, and ii) constant pool validity. Taking each in turn: - The type checking verifier in 4.10.1 performs (i) via the classIsTypeSafe and methodIsTypeSafe predicates, but the type inferencing verifier in 4.10.2 does not perform (i), since 4.10.2 specifies solely verification of the code array. - The type checking verifier in 4.10.1 arguably performs (ii) by virtue of the accessor predicates in 4.10.1.1 which rely on valid constant pool entries. But that would make invalid constant pool entries cause a VerifyError, whereas in fact they cause ClassFormatError (confirmed by H.Seigel and D.Heidinga 2013-04-11). So (ii) is looking misplaced in JVMS7 4.10 already. Then, the type inferencing verifier in 4.10.2 does not perform (ii) at all. It's clear that (ii) needs to be enforced before the main bytecode verification in 4.10.{1,2} gets going. Changes for JVMS8: - It must be clear the (i) checks introduced in 4.10 are a core part of verification, so that subclassing a final class, overriding a final method, or a class without a superclass is a VerifyError in both verifiers (type inferencing and type checking). - The (ii) checks should be identified as class format checks in 4.8, and removed from 4.10. (Although the checks may physically be performed by the "verifier" component of a JVM implementation.)
16-08-2013

EVALUATION This is true, and reflects larger problems in the specification of verification. Specifically: The division into passes is arbitrary, and need not be part of the spec at all. The exact nature of pass 2 is not specified. Most of the specified checks for pass 2 are really class format checks. The main exceptions are the check that final classes are not subclassed and that final methods are not overridden. These two checks do raise VerifyError, but this is not clear from the specs. gilad.bracha@eng 1999-07-23
23-07-1999