Mark Miller created VALIDATOR-502:
-------------------------------------
Summary: circular dependency in static initialization causes NPE
in GenericValidator.isCreditCard()
Key: VALIDATOR-502
URL: https://issues.apache.org/jira/browse/VALIDATOR-502
Project: Commons Validator
Issue Type: Bug
Components: CreditCard
Affects Versions: 1.10.0, 1.9.0
Reporter: Mark Miller
Attachments: GenericValidator.patch
commons-validator 1.9.0 and 1.10.0 will throw a NullPointerException in
{{GenericValidator.isCreditCard()}} (and likely elsewhere) if
{{{}routines.CreditCardValidator{}}}'s class is initialized before
{{{}GenericValidator{}}}'s class is initialized.
h4. Dependency Chain
{{{}CreditCardValidator{}}}'s clinit calls
{{{}GenericValidator.isBlankOrNull(){}}}, which runs {{{}GenericValidator{}}}'s
clinit, which initializes:
{noformat}
private static final CreditCardValidator CREDIT_CARD_VALIDATOR = new
CreditCardValidator();{noformat}
which references (among others):
{noformat}
public static final CodeValidator AMEX_VALIDATOR = new
CodeValidator("^(3[47]\\d{13})$", LUHN_VALIDATOR);{noformat}
... but that field has not yet been initialized, so
{{{}GenericValidator.CREDIT_CARD_VALIDATOR{}}}'s AMEX_VALIDATOR is unexpectedly
null.
Bug is reproducible by this test code:
{noformat}
@Test
public void testGenericValidatorCircularDependency() {
CreditCardValidator ccv = new CreditCardValidator(); // commenting out
this line will avoid the NPE
GenericValidator.isCreditCard("1234567890"); // throws NPE!!!
}{noformat}
Suggested patch to GenericValidator.java is attached - it simply puts the
relevant fields into a LazyHolder inner class (which incidentally might provide
a small performance boost in cases where `GenericValidator.isCreditCard()` and
`GenericValidator.isUrl()` are not used).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)