Project

Profile

Help

Bug #2524

closed

AssertionError due to class loading order

Added by Gunther Rademacher over 8 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Internals
Sprint/Milestone:
Start date:
2015-12-03
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
9.6
Fix Committed on Branch:
9.6
Fixed in Maintenance Release:
Platforms:

Description

Running this Java program

import net.sf.saxon.s9api.ItemType;
import net.sf.saxon.s9api.XdmAtomicValue;

public class ValidateNCName {

  public static void main(String[] args) throws Exception {
//  Class.forName("net.sf.saxon.type.BuiltInAtomicType");
//  Class.forName("net.sf.saxon.type.StringConverter");
    new XdmAtomicValue("x", ItemType.NCNAME);
    System.out.println("success");
  }
}

with JVM argument -verbose shows that

  • net.sf.saxon.type.StringConverter

  • net.sf.saxon.type.BuiltInAtomicType

are loaded in this very order, which however causes their static initialization to behave in an unintended way, which subsequently causes an AssertionError:

This can be worked around by uncommenting the Class.forName invocations.

Originally observed in a more complex setup with Saxon-EE 9.6.0.5, but also occurs with 9.7.0.1.

Actions #1

Updated by Michael Kay over 8 years ago

  • Assignee set to Michael Kay
  • Priority changed from Low to Normal
  • Found in version changed from Saxon-EE 9.6.0.5 to 9.6

Very interesting - after all these years, Java still comes up with surprises.

As far as I can see, the root cause of the problem is that the two classes BuiltInAtomicType and StringConverter each have dependencies on each other in their static initializers, which means that one of the two is going to have its static initializers executed while the other is still uninitialized. Surprising that this hasn't come up before; and it's not immediately obvious what to do about it.

Actions #2

Updated by Michael Kay over 8 years ago

It seems to be possible to solve this by moving the static initializer of BuiltInAtomicType - the block that does

static {

    STRING.stringConverter = StringConverter.STRING_TO_STRING;

    etc

}

as static initializer of StringConverter instead. Very hard to know, though, whether this is a complete solution.

Perhaps a better solution would be to make the "constant" string converters into anonymous classes:

public final static BuiltInAtomicType HEX_BINARY =
            makeAtomicType(StandardNames.XS_HEX_BINARY, ANY_ATOMIC, true,
            new StringConverter() {
              public ConversionResult convertString(/*@NotNull*/ CharSequence input) {
                try {
                  return new HexBinaryValue(input);
                } catch (XPathException e) {
                  return new ValidationFailure(e);
                }
             };
           });
Actions #3

Updated by Michael Kay over 8 years ago

  • Category set to Internals
  • Status changed from New to Resolved

I have fixed this (this particular case, at least) for 9.6 and 9.7 by moving the static initializer block which sets the stringConverter of built-in types from the BuiltInAtomicType class to the StringConverter class.

Actions #4

Updated by O'Neil Delpratt over 8 years ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in version set to 9.6.0.8

Bug fix applied in the Saxon 9.6.0.8 maintenance release

Actions #5

Updated by O'Neil Delpratt over 8 years ago

  • Applies to branch 9.6 added
  • Fix Committed on Branch 9.6 added
  • Fixed in Maintenance Release 9.6.0.8 added
Actions #6

Updated by O'Neil Delpratt over 8 years ago

  • Sprint/Milestone set to 9.6.0.8

Please register to edit this issue

Also available in: Atom PDF