Java HttpURLConnection uses SOCKS proxy instead of HTTP

I have a very simple code that uses HttpURLConnection to access some web site via proxy

    System.setProperty("java.net.useSystemProxies", "true");
    System.out.println("Proxy: " + ProxySelector.getDefault().select(new URI(urlS)));
    URL url = new URL(urlS);
    HttpURLConnection ic = (HttpURLConnection)url.openConnection();

    ic.connect();

For some reason, Java thinks that I need SOCKS proxy, not http, throwing the following exception:

ERROR: Can't connect to SOCKS proxy:Connection timed out: connect

Answers


If you are having this issues on Windows, you may run into a Java bug.

Java treats any system proxy setting as SOCKS. You have to either disable useSystemProxies or don't use proxy in Windows.

If proxy is needed, try to uncheck "Use the same proxy server for all protocols", making sure the field for the SOCKS proxy is blank. That fixed our problem.


The real problem is that Java assumes that the "Use the same proxy server for all protocols" check affects SOCKS proxy too (I don't know the logic behind this dialog in Windows, but it is, at least, confusing) If the check is set, you get proxies enabled for both HTTP and SOCKS, wich is very unlikely to be the desired configuration. One way to solve it is unchecking the check and leaving blank the SOCKS field.

I finally solved it creating a ProxySelector wich first calls the default selector and if it finds the same configuration for HTTP and SOCKS connections, it omits the SOCKS proxy.

   public class SocksFixerProxySelector extends ProxySelector {

    ProxySelector base;

    public SocksFixerProxySelector() {
         base = ProxySelector.getDefault();
    }

    @Override
    public List<Proxy> select(URI uri) {

        List<Proxy> baseList = base.select(uri);

        try {
            if (uri.getScheme().equals("socket")) {

                Proxy socksProxy = findByType(baseList, Type.SOCKS);
                if (socksProxy != null) {

                    URI httpTestUri = new URI("http", uri.getHost(), uri.getPath(), uri.getFragment());
                    Proxy httpProxy = findByType(base.select(httpTestUri), Type.HTTP);

                    if (httpProxy != null && socksProxy.address().equals(httpProxy.address())) {
                        // Quitamos SOCKS
                        List<Proxy> filteredList = new ArrayList<>(baseList);
                        filteredList.remove(socksProxy);
                        return filteredList;
                    }
                }
            }
        } catch (Exception e) {

        }
        return baseList;

    }

    @Override
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
        base.connectFailed(uri, sa, ioe);

    }

    private Proxy findByType(List<Proxy> proxies, Proxy.Type type) {
        for (Proxy proxy : proxies) {
            if (proxy.type() == type)
                return proxy;
        }

        return null;
    }

Maybe a better solution would be to inspect the registry and detect the right settings, but I didn't want to mess with Windows specific code (and all those script settings looked bad, too )


You need to use the http.proxyHost system property instead. See http://java.sun.com/javase/6/docs/technotes/guides/net/proxies.html for details.

java -Dhttp.proxyHost=webcache.mydomain.com GetURL

Check that something has not set the "socksProxyHost" property in the Systems properties.

EDIT

The "useSystemProxies" property is described thus:

"On recent Windows systems and on Gnome 2.x platforms it is possible to tell the default ProxySelector to use the system proxy settings (both recent versions of Windows and Gnome 2.x let you set proxies globally through their user interface). If the system property java.net.useSystemProxies is set to true (by default it is set to false for compatibility sake), then the default ProxySelector will try to use these settings."

So, assuming that you have not supplied your own ProxySelector class, you should also check the system proxy settings to ensure that they don't say to use SOCKS.


Need Your Help

Using Entity Framework generated classes in Business Logic Layer

c# entity-framework business-objects business-logic-layer

I have a ASP.net (C#) project that is using a three layer architecture. I started to use Entity Framework in my DAL and the question is to what extent classes generated by Entity Framework can be ...

My workplace's proxy is preventing me from using Maven

java spring maven spring-mvc proxy

I work in the public sector so my workplace controls internet access pretty strictly. I've tried configuring the settings.xml file that M2Eclipse reads to no avail. It may be simple user error in m...