Skip to content

NPE in NullPointerException in ExpressionOperator.printCollection since 2.7.11+, 3.0.0+ #2136

@igormukhin

Description

@igormukhin

Describe the bug

Since switching to EL 2.7.14 we are getting a mysterious NPE at ExpressionOperator.printCollection().
The exception happens only occasionally from time to time (like once a week) on different queries.

It also happend to other people #1867 and #1717

To Reproduce

I don't know how to reproduce it, but it is clearly a bug in the source code. Read further.

UPDATE 10.06.2024
I created a sample project that reproduces the issue: https://github.com/igormukhin/eclipselink-issue-1717-test
The problem is when a queries are running in parallel threads and use COALESCE(...) function or CASE WHEN statement.

Expected behavior

Same as before v2.7.11.

UPDATE 10.06.2024 The following problem description and the solution can be ignored as it is invalid.

The Problem

In the class ExpressionOperator there is a field argumentIndices

Up to 2.7.10 the field was used in the method printCollection like this:

    public void printCollection(List<Expression> items, ExpressionSQLPrinter printer) {
        // ... skipped some code ...

        if (this.argumentIndices == null) {
            this.argumentIndices = new int[items.size()];
            for (int i = 0; i < this.argumentIndices.length; i++){
                this.argumentIndices[i] = i;
            }
        }

        // ... skipped some code ...
        for (final int index : argumentIndices) {
            Expression item = items.get(index);
            // ... skipped some code ...
                item.printSQL(printer);
           // ... skipped some code ...
        }
    }

In 2.7.11 the line for (final int index : argumentIndices) was changed to for (int i = 0; i < this.argumentIndices.length; i++)
That is causing the exception.

The field argumentIndices can be changed while inside the loop because the loop calls item.printSQL(printer) which in turn can call ExpressionOperator.copyTo where the field argumetIndices on the already used operator instance will be set to null.

I can't explain why it does work most of the time and only occasionally fails but it is clearly the reason for the NPE.

Solution

While it is not the ultimate solution for the underlying problem (the field can be changed), we still can fix it with just by returning back to caching the value of argumentIndices while looping which is already done in 3.1.0-M1 and 4.0.0 but not in 2.7.x, 3.0.x

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions