2

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
Demiurg
  • 1,597
  • 8
  • 26
  • 40

4 Answers4

5

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.

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272
ZZ Coder
  • 74,484
  • 29
  • 137
  • 169
  • This is what I thought. Some people suggested a workaround which involves overloading the DefaultProxySelector class which I'm going to try. – Demiurg Jul 04 '10 at 21:47
  • 1
    ZZ Coder, do you have a reference on this "Java bug" you were talking about so that I can find more information? Where did you get your information? Has this bug been filed with Oracle? – Garret Wilson Mar 12 '15 at 23:48
  • This is the correct answer (complementing the other answer on overriding the default proxy selector), but it could use more explanation. I edited the answer to clarify that one should _uncheck_ the "User the same proxy server for all protocols" option so that it is unselected. – Garret Wilson Mar 26 '15 at 22:17
2

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 )

Juan Calero
  • 4,124
  • 5
  • 31
  • 45
1

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • No, there is no SOCKS configuration in the system proxy settings. Moreover, I would expect that it would use HTTP proxy for HTTP protocol by default, or at least allow me to set this – Demiurg Jul 04 '10 at 12:24
  • I give up. Perhaps it is time to run your application using the Java debugger, set a breakpoint in the `DefaultProxySelector` and single step it. – Stephen C Jul 04 '10 at 12:36
  • Looks like a bug in JDK to me. Found some other [unresolved] reports of this problem – Demiurg Jul 04 '10 at 12:49
1

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
Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347