/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.fs;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class HadoopExtendedFileSystemCache
{
    private static PrestoExtendedFileSystemCache cache;

    private HadoopExtendedFileSystemCache() {}

    public static synchronized void initialize()
    {
        if (cache == null) {
            cache = setFinalStatic(FileSystem.class, "CACHE", new PrestoExtendedFileSystemCache());
        }
    }

    private static <T> T setFinalStatic(Class<?> clazz, String name, T value)
    {
        try {
            Field field = clazz.getDeclaredField(name);
            field.setAccessible(true);

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

            field.set(null, value);

            return value;
        }
        catch (ReflectiveOperationException e) {
            throw new AssertionError(e);
        }
    }
}

@@ -618,16 +618,49 @@
 .Field;%0A
+import java.lang.reflect.Method;%0A
 import j
@@ -686,16 +686,16 @@
 difier;%0A
-
 %0Apublic 
@@ -1271,47 +1271,20 @@
 d = 
-Field.class.getDeclaredField(%22m
+getM
 odifiers
 %22);%0A
@@ -1279,17 +1279,22 @@
 odifiers
-%22
+Field(
 );%0A     
@@ -1537,24 +1537,24 @@
 eption e) %7B%0A
-
             
@@ -1597,11 +1597,836 @@
  %7D%0A    %7D
+%0A%0A    private static Field getModifiersField() throws NoSuchFieldException%0A    %7B%0A        try %7B%0A            return Field.class.getDeclaredField(%22modifiers%22);%0A        %7D%0A        catch (NoSuchFieldException e) %7B%0A            try %7B%0A                Method getDeclaredFields0 = Class.class.getDeclaredMethod(%22getDeclaredFields0%22, boolean.class);%0A                getDeclaredFields0.setAccessible(true);%0A                Field%5B%5D fields = (Field%5B%5D) getDeclaredFields0.invoke(Field.class, false);%0A                for (Field field : fields) %7B%0A                    if (%22modifiers%22.equals(field.getName())) %7B%0A                        return field;%0A                    %7D%0A                %7D%0A            %7D%0A            catch (ReflectiveOperationException ex) %7B%0A                e.addSuppressed(ex);%0A            %7D%0A            throw e;%0A        %7D%0A    %7D
 %0A%7D%0A

Fix incompatible reflection for modifying static final fields since JDK 12