class HostUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(HostUtil.class);

    private HostUtil() {
        // private to enforce static
    }

    /**
     * @param urlStr URI
     * @return port number
     * @throws URISyntaxException on error
     */
    public static int urlToPort(String urlStr) throws URISyntaxException {
        URI uri = new URI(urlStr);
        return uri.getPort();
    }

    private static boolean isWebAppReachable(String webappURI, int timeOutSeconds, @Nullable String token) {
        ClientBuilder clientBuilder = ClientBuilder.newBuilder();
        clientBuilder.connectTimeout(timeOutSeconds, TimeUnit.SECONDS);
        clientBuilder.readTimeout(timeOutSeconds, TimeUnit.SECONDS);

        // Here, IndexerUtil#getWebAppHeaders() is not used because at the point this method is called,
        // the RuntimeEnvironment configuration used by getWebAppHeaders() is not set yet.
        MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
        if (token != null) {
            headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
        }

        LOGGER.log(Level.FINE, "checking reachability of {0} with connect/read timeout of {1} seconds",
                new Object[]{webappURI, timeOutSeconds});
        try (Client client = clientBuilder.build()) {
            Response response = client
                .target(webappURI)
                    .path("api")
                    .path("v1")
                    .path("system")
                    .path("ping")
                    .request()
                    .headers(headers)
                    .get();

            if (response.getStatusInfo().getFamily() != Response.Status.Family.SUCCESSFUL) {
                LOGGER.log(Level.SEVERE, "cannot reach OpenGrok web application on {0}: {1}",
                        new Object[]{webappURI, response.getStatusInfo()});
                return false;
            }
        } catch (ProcessingException e) {
            LOGGER.log(Level.SEVERE, String.format("could not connect to %s", webappURI), e);
            return false;
        }

        return true;
    }

    /**
     *
     * @param webappURI URI of the web app
     * @param timeOutSeconds connect/read timeout in seconds
     * @param token authentication token, can be {@code null}
     * @return whether web app is reachable within given timeout on given URI
     */
    public static boolean isReachable(String webappURI, int timeOutSeconds, @Nullable String token) {<FILL_FUNCTION_BODY>}
}

        boolean connectWorks = false;

        try {
            int port = HostUtil.urlToPort(webappURI);
            if (port <= 0) {
                LOGGER.log(Level.SEVERE, () -> "invalid port number for " + webappURI);
                return false;
            }

            return isWebAppReachable(webappURI, timeOutSeconds, token);
        } catch (URISyntaxException e) {
            LOGGER.log(Level.SEVERE, String.format("URI not valid: %s", webappURI), e);
        }

        return connectWorks;
    
<no_super_class>