39

I did see the question about setting the proxy for the JVM but what I want to ask is how one can utilize the proxy that is already configured (on Windows).

Here is a demonstration of my issue:

  1. Go to your Control Panel->Java and set a proxy address.
  2. Run the following simple applet code (I'm using the Eclipse IDE):
import java.awt.Graphics;
import javax.swing.JApplet;
import java.util.*;

public class Stacklet extends JApplet {
    private String message;
    public void init(){
        Properties props = System.getProperties();
        message = props.getProperty("http.proxyHost", "NONE");      
        message = (message.length() == 0)? "NONE": message;
    }

    public void paint(Graphics g)
    {
        g.drawString(message, 20, 20);
    }
}

The Applet displays "NONE" without regard to the settings you've placed in the Java Control Panel. What would be best would be if the Windows proxy settings (usually set in Internet Explorer) were what I could determine but doing an extra configuration step in the Java Control Panel would still be an acceptable solution.

Thanks!

t3rse
  • 10,024
  • 11
  • 57
  • 84

6 Answers6

39

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()));
        }
    }
}
xav
  • 5,452
  • 7
  • 48
  • 57
t3rse
  • 10,024
  • 11
  • 57
  • 84
  • 5
    I do have proxy in here. But this piece of code prints out "detecting proxies proxy hostname : DIRECT No Proxy" but actually connection to URI specified fails with timeout. – Nikolay Kuznetsov Nov 05 '12 at 08:27
  • proxy hostname : DIRECT No Proxy Does this mean I am not behind a proxy? – Koray Tugay Feb 22 '14 at 12:54
  • 2
    same situation, I'm behind a proxy but this I get DIRECT No Proxy using this code... – splinter123 Nov 03 '14 at 15:46
  • java.net.useSystemProxies does not always work. I don't know all situations where it does nothing, but it will definitely not do anything if the proxy is transparent, i.e. applications just do a direct connection and the proxy will intercept that connection without telling them. – toolforger Sep 16 '20 at 07:52
23

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.

Jaime Hablutzel
  • 6,117
  • 5
  • 40
  • 57
  • 3
    +1 for mentioning that this property is only checked once at startup, something not mentioned anywhere else in this question. – fragorl Mar 23 '16 at 23:19
  • Actually, if this property is specified the system proxy is used automatically! – MauganRa Oct 27 '16 at 07:06
  • 3
    This does not work with Proxy Auto-Config (PAC) files, see https://stackoverflow.com/questions/10324996/does-javas-proxyselector-not-work-with-automatic-proxy-configuration-scripts – Michael_S Apr 29 '19 at 10:57
  • This one helps bypass -javaagent side effects some times (such as Application run in Intellij IDEA) – loic Jun 03 '22 at 13:34
  • 1
    This does work with PAC files when **using java 9 and up** - see https://stackoverflow.com/a/57891805/3059685. – Joman68 Jul 09 '22 at 23:48
11

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;
  }
}
Flo
  • 133
  • 1
  • 5
3

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

Pops
  • 30,199
  • 37
  • 136
  • 151
Hrvoje
  • 119
  • 1
  • 1
  • 8
2

UPDATE: you need to have the System Property java.net.useSystemProxies set to true for my solution below to work.

If you use java.net.URL.openStream() to get an InputStream for the web resource content you automatically get the same proxy used as Internet Explorer would use for that URL.

No need to go to the Java Control Panel or to display the proxy used.

Alain O'Dea
  • 21,033
  • 1
  • 58
  • 84
  • 2
    Nope - that's not true. Or if it's supposed to work that way it does not work. – mmo May 28 '15 at 07:13
  • @mmo you are correct. Thank you for identifying that. I was using java.net.useSystemProxies and forgot to mention that. It is an essential point. – Alain O'Dea Jun 08 '15 at 17:10
  • @mmo have I addressed your concern sufficiently for you to remove the downvote? – Alain O'Dea Nov 17 '15 at 17:09
2
try{
    System.setProperty("java.net.useSystemProxies", "true");
    String prx = ProxySelector.getDefault().select(new URI("http://www.google.com")).get(0).address().toString();
    JOptionPane.showMessageDialog(null, prx);
} catch(Exception e){
    JOptionPane.showMessageDialog(null, "no proxy");
}
Mahdi
  • 57
  • 6
  • 2
    Hello, welcome to SO. Your answer contains only code. It would be better if you could also add some commentary to explain what it does and how. Can you please [edit] your answer and add it? Thank you! – Fabio says Reinstate Monica Nov 01 '18 at 21:58