Setting JVM/JRE to use Windows Proxy Automatically

Solution 1:

It is possible to detect the proxy using the ProxySelector class and assign the system proxy by assigning environment variables with the setProperty method of the System class:

System.setProperty("java.net.useSystemProxies", "true");
System.out.println("detecting proxies");
List l = null;
try {
    l = ProxySelector.getDefault().select(new URI("http://foo/bar"));
} 
catch (URISyntaxException e) {
    e.printStackTrace();
}
if (l != null) {
    for (Iterator iter = l.iterator(); iter.hasNext();) {
        java.net.Proxy proxy = (java.net.Proxy) iter.next();
        System.out.println("proxy type: " + proxy.type());

        InetSocketAddress addr = (InetSocketAddress) proxy.address();

        if (addr == null) {
            System.out.println("No Proxy");
        } else {
            System.out.println("proxy hostname: " + addr.getHostName());
            System.setProperty("http.proxyHost", addr.getHostName());
            System.out.println("proxy port: " + addr.getPort());
            System.setProperty("http.proxyPort", Integer.toString(addr.getPort()));
        }
    }
}

Solution 2:

This might be a little late, but I ran into the same problem. The way I fixed it is by adding the following system property:

-Djava.net.useSystemProxies=true

Now, note that this property is set only once at startup, so it can't change when you run your application. From https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html#Proxies:

java.net.useSystemProxies (default: false) ... Note that this property is checked only once at startup.

Solution 3:

I found an odd behavior experimenting with the suggested code here.

It appears that, after a default ProxySelector has been set, regular socket code (e.g. creating a new Socket) does not work anymore, because it tries to use a socks server (not sure why it would do this, but for me it does).

So if you, when calling

Socket socket = new Socket(host, port);

you receive such a SocketException:

java.net.SocketException: Malformed reply from SOCKS server
    at java.net.SocksSocketImpl.readSocksReply(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)

then try setting the default ProxySelector back to null:

ProxySelector.setDefault(null);

For me this resulted in the following small Java class which I now use to simply retrieve the systems proxy settings without having it affect the further usage of Sockets() of the application, yet configuring the system properly to use the proxy:

public class ProxyConfig {

  private static String host;
  private static int port;

  public static void init() {
    System.setProperty("java.net.useSystemProxies", "true");
    Proxy proxy = getProxy();
    if (proxy != null) {
      InetSocketAddress addr = (InetSocketAddress) proxy.address();
      host = addr.getHostName();
      port = addr.getPort();

      System.setProperty("java.net.useSystemProxies", "false");
      System.setProperty("http.proxyHost", host);
      System.setProperty("http.proxyPort", ""+port);

    }
    System.setProperty("java.net.useSystemProxies", "false");
  }

  public static String getHost() {
    return host;
  }

  public static int getPort() {
    return port;
  }

  private static Proxy getProxy() {
    List<Proxy> l = null;
    try {
      ProxySelector def = ProxySelector.getDefault();

      l = def.select(new URI("http://foo/bar"));
      ProxySelector.setDefault(null);
    } catch (Exception e) {
      e.printStackTrace();
    }
    if (l != null) {
      for (Iterator<Proxy> iter = l.iterator(); iter.hasNext();) {
        java.net.Proxy proxy = iter.next();
        return proxy;
      }
    }
    return null;
  }
}

Solution 4:

java.net.URL.openStream() is a shorthand for java.net.URL.openConnection().getInputStream().