Svetlin Zarev created TOMEE-2085:
------------------------------------

             Summary: AutoConfig::firstMatching sorting issue with java 8
                 Key: TOMEE-2085
                 URL: https://issues.apache.org/jira/browse/TOMEE-2085
             Project: TomEE
          Issue Type: Bug
            Reporter: Svetlin Zarev


Java 8 changed the implementation of Collections.sort(). In java < 8 it always 
allocated a new array which was used for the actual sorting, and then the list 
was recreated with it's content. Starting with Jav a8, the sort() method 
delegates to the concrete implementation of the concrete list. For arrya list 
it works directly on the backing array, which violates the assumption of the 
current comparator impl, that the backing array is not modified during the 
actual sorting.

Test case
{code}
public final class Main {
    public static void main(String[] args) {
        final Random random = new Random();
        final String prefix = "0";

        for (int k = 0; k < 1000; k++) {
            try {
                final List<String> resourceIds = generateRandomData(random);
                sort(prefix, resourceIds);
            } catch (Exception e) {
                System.out.println(e);
                break;
            }

            System.out.println(k);
        }
    }

    private static void sort(final String prefix, final List<String> 
resourceIds) {
        Collections.sort(resourceIds, new Comparator<String>() { // sort from 
webapp to global resources
            @Override
            public int compare(final String o1, final String o2) { // don't 
change global order, just put app scoped resource before others
                if (o1.startsWith(prefix) && o2.startsWith(prefix)) {
                    return resourceIds.indexOf(o1) - resourceIds.indexOf(o2);
                } else if (o1.startsWith(prefix)) {
                    return -1;
                } else if (o2.startsWith(prefix)) {
                    return 1;
                }
                // make it stable with prefixed comparison + keep existing 
ordering (bck compat)
                return resourceIds.indexOf(o1) - resourceIds.indexOf(o2);
            }
        });
    }

    private static List<String> generateRandomData(Random random) {
        final List<String> resourceIds = new ArrayList<>();
        for (int i = 0; i < 5000; i++) {
            resourceIds.add(Integer.toString(random.nextInt(3)) + 
random.nextInt(1000));
        }
        return resourceIds;
    }
}
{code}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to