Trying to make a PATCH call to a web service results in the error, java.net.ProtocolException: Invalid HTTP method: PATCH.
public class PatchTest {
    public static void main(String[] args) throws Exception {       
        HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL("https://api.url.com").openConnection();
        httpUrlConnection.setRequestMethod("PATCH");    
    }
}
I am aware that this is a known issue with Httpurlconnection.setrequestmethod as discussed in HttpURLConnection Invalid HTTP method: PATCH. First, I tried the X-HTTP-Method-Override workaround, but the service still thinks I am making a POST call.
public class PatchTest {    
    public static void main(String[] args) throws Exception {
        HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL("https://api.url.com").openConnection();
        httpUrlConnection.setRequestProperty("Content-Type", "application/json");   
        httpUrlConnection.setDoOutput(true);        
        httpUrlConnection.setRequestProperty("X-HTTP-Method-Override", "PATCH");        
        httpUrlConnection.setRequestMethod("POST");
        httpUrlConnection.getResponseCode();
        InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getErrorStream());
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        System.out.println(bufferedReader.readLine());                  
    }
}
Response: {"code":"405","message":"Request method 'POST' not supported"}
Next, I tried using the reflection method, and this worked fine before trying to send a request payload.
public class PatchTest {    
    public static void main(String[] args) throws Exception {       
        allowMethods("PATCH");
        HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL("https://api.url.com").openConnection();
        httpUrlConnection.setRequestProperty("Content-Type", "application/json");   
        httpUrlConnection.setDoOutput(true);
        System.out.println("Response code: " + httpUrlConnection.getResponseCode());
        InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getInputStream());
        System.out.println(new BufferedReader(inputStreamReader).readLine());
    }   
    private static void allowMethods(String... methods) {
        try {
            Field methodsField = HttpURLConnection.class.getDeclaredField("methods");
            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL);
            methodsField.setAccessible(true);
            String[] oldMethods = (String[]) methodsField.get(null);
            Set<String> methodsSet = new LinkedHashSet<>(Arrays.asList(oldMethods));
            methodsSet.addAll(Arrays.asList(methods));
            String[] newMethods = methodsSet.toArray(new String[0]);
            methodsField.set(null/*static field*/, newMethods);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new IllegalStateException(e);
        }
    }
}
Response code: 200
{"somekey":"somevalue"}
However, when I try to user Writer to set the request payload, I get a 405 error.
    public static void main(String[] args) throws Exception {       
        allowMethods("PATCH");
        HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL("https://api.url.com").openConnection();
        httpUrlConnection.setRequestProperty("Content-Type", "application/json");   
        httpUrlConnection.setDoOutput(true);    
        Writer writer = new BufferedWriter(new OutputStreamWriter(httpUrlConnection.getOutputStream()));
        writer.write("{}");
        writer.close();
        InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getInputStream());
        System.out.println(new BufferedReader(inputStreamReader).readLine());
    }   
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 405 for URL: https://api.url.com
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
    at PatchTest.main(PatchTest.java:32)
Is there some change I need to make to allowMethods to get past the 405 error, or is there something else I am missing?
