I know there are lots of ways to `GET` the data from remotes. I have tried these different types:

1. using `curl` within a `Runtime.getRuntime().exec(...)` or `new ProcessBuilder(...).start()`;
2. using library as `URL` or `RestTemplate`;

Are there some **significant** differences among them that we should think over before using one of them?

### Update #0

Why I ask this seemingly **topic-too-broad** or **opinion-based** question?

I encountered an issue using `ProcessorBuilder` in a highly concurrent system, there will be some `TimeOut` while using `RestTemplate`, there is none?!

After digging and debugging, I found nothing quite related to the result and I asked this question to **understand what I might have overlooked**.

```
    List<CompletableFuture<GrafanaDashboard>> futureList = dbList.stream()
            .map(boardName -> CompletableFuture.supplyAsync(() -> GrafanaRetriever
                    .parseDashboard(apiUrl, tokenString, boardName), Executors.newCachedThreadPool()))
            .collect(Collectors.toList());
    for (CompletableFuture<GrafanaDashboard> completableFuture : futureList) {
        try {
            dashboards.add(completableFuture.get(30, TimeUnit.SECONDS)); 
           // using ProcessorBuilder, it will hang here and some might time out (not all just some)
           // using RestTemplate, it will not wait almost, just smooth and no time out at all;
        } catch (ExecutionException | InterruptedException | TimeoutException e) {
            log.warn("Retrieving data from grafana failed due to TimeOut most likely by {}", apiUrl);
            e.printStackTrace();
        }
    }

```

### Update #1

Here is a small demo to get data using http `GET` with `cookie` for all of them:

```
public class RunTimeExecTest {
    private static String urlString = "https://www.google.com.sg";
    private static String tokenString = "your_cookie";

    public static void main(String... args) {
        getWithRunTimeExec();
        getWithProcessorBuilder();
        getUsingUrl();
        getUsingRestTemplate();
    }

    private static void getWithRunTimeExec() {
        System.out.println("Using RunTime.exec: ");
        try {
            Process process = Runtime.getRuntime().exec("curl -v --cookie \"" + tokenString + "\" " + urlString);

            process.waitFor();
            System.out.println(IoHelper.output(process.getInputStream()));
            process = Runtime.getRuntime().exec(new String[]{"curl", "-v", "--cookie", tokenString, urlString});

            process.waitFor();
            System.out.println(IoHelper.output(process.getInputStream()));

        } catch (IOException | InterruptedException ignored) {
            ignored.printStackTrace();
        }
    }

    private static void getWithProcessorBuilder() {
        System.out.println("Using ProcessorBuilder: ");
        try {
            Process process = new ProcessBuilder("curl", "-v", "--cookie", tokenString, urlString).start();

            process.waitFor();
            System.out.println(IoHelper.output(process.getInputStream()));
        } catch (IOException | InterruptedException ignored) {
            ignored.printStackTrace();
        }

    }

    private static void getUsingUrl() {
        System.out.println("Using Url: ");
        try {
            URL myURL = new URL(urlString);
            HttpURLConnection myURLConnection = (HttpURLConnection) myURL.openConnection();
            myURLConnection.setRequestMethod("GET");
            myURLConnection.setRequestProperty("cookie", tokenString);
            myURLConnection.connect();
            System.out.println(IoHelper.output(myURLConnection.getInputStream()));
        } catch (IOException ignored) {
            ignored.printStackTrace();
        }
    }

    private static void getUsingRestTemplate() {
        System.out.println("Using RestTemplate: ");
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Cookie", tokenString);
        HttpEntity requestEntity = new HttpEntity(null, requestHeaders);
        ResponseEntity rssResponse = restTemplate.exchange(
                urlString,
                HttpMethod.GET,
                requestEntity,
                String.class);
        System.out.println(rssResponse.getBody());
    }
}

```

### Update #2

What I found out:

1. Using `URL` or `RestTemplate` provided `by spring.web` can be more robust since they provided the *contract* that what they can do and what they cannot clearly;
2. In different platforms, you do not reply on the specific commands which vary dramatically;
3. Hard to maintain since it's asking a java programmer to understand more than just java;
4. Using `URL` or `RestTemplate` can handle some complicated processes that using `curl` is hard (or even impossible) to achieve;
5. Using `URL` and `RestTemplate` can leave lots of issues to the library maintainers and even can just leave them there (`RestTemplate` requires no `try{...} catch(...){...}`;