Does Java's ProxySelector not work with automatic proxy configuration scripts?
Asked Answered
P

5

27

I want my Java program to use the system's proxy configuration. Accordingly, I used the code found in many places, such as this answer, to set java.net.useSystemProxies to true and call ProxySelector.getDefault().select(...) to discover the proxy for the particular host I want to reach. This works fine when I've configured a single explicit proxy server in Internet Properties. But if I have set "Use automatic configuration script", it always returns the DIRECT "proxy".

I know that the script works, as my browser can access the hosts for which it returns a proxy server, and without the script set, it can't. I even tried simplifying the script to its barest essentials:

function FindProxyForURL(url, host)
{
    return "PROXY my.proxy.mydomain:3128";
}

and it works in my browser, but ProxySelector.getDefault().select(...) still returns only DIRECT.

Am I missing something? (This is on Java 1.6 & Windows 7, should it matter.)

Paediatrician answered 25/4, 2012 at 23:1 Comment(0)
G
34

No, the Java ProxySelector does not read Proxy Auto-Config (PAC) files.

However, as suggested by Brian de Alwis as an answer to my similar question, the Proxy Vole library appears to provide that support/capability.

To provide network connectivity out of the box for you Java application you can use the Proxy - Vole library. It provides some strategies for autodetecting the current proxy settings. There are many configureable strategies to choose from. At the moment Proxy - Vole supports the following proxy detection strategies.

  • Read platform settings (Supports: Windows, KDE, Gnome, OSX)
  • Read browser setting (Supports: Firefox 3.x, Internet Explorer; Chrome and Webkit use the platform settings)
  • Read environment variables (often used variables on Linux / Unix server systems)
  • Autodetection script by using WPAD/PAC (Not all variations supported)
Gascony answered 26/4, 2012 at 1:3 Comment(4)
Thanks for the tip. Googling for "java proxy selector" doesn't find this library, unless you're sharp enough to realize that some of the code fragments going by are part of a useful library. It's a shame Java doesn't already do it by itself, since it has the ProxySelector structure, and knows how to find an ordinary fixed proxy.Paediatrician
By the way, the instructions are a little misleading, in that the "default" configuration is kind of useless -- it uses the "read the java system properties" strategy, which is what you'd get without this library in the first place. What worked for me was ProxySearch proxySearch = new ProxySearch(); proxySearch.addStrategy(Strategy.OS_DEFAULT); myProxySelector = proxySearch.getProxySelector();Paediatrician
Anyone knows about a lightweight alternative to proxy-vole? 6 MB feels a bit heavy for just some missing Java functionality.Egghead
The simplest solution happens to be to let JVM pick up the system proxies on program startup via -Djava.net.useSystemProxies=true as described in docs.oracle.com/javase/7/docs/api/java/net/doc-files/…Meld
H
15

As already suggested by Mads Hansen, Proxy-Vole does the trick!

You just need to add the jar from the download site to your classpath (dlls are included) and this code helped me to configure the proxy stettings:

ProxySearch proxySearch = new ProxySearch();
proxySearch.addStrategy(Strategy.OS_DEFAULT); 
proxySearch.addStrategy(Strategy.JAVA); 
proxySearch.addStrategy(Strategy.BROWSER); 
ProxySelector proxySelector = proxySearch.getProxySelector(); 

ProxySelector.setDefault(proxySelector); 
URI home = URI.create("http://www.google.com"); 
System.out.println("ProxySelector: " + proxySelector); 
System.out.println("URI: " + home); 
List<Proxy> proxyList = proxySelector.select(home); 
if (proxyList != null && !proxyList.isEmpty()) { 
 for (Proxy proxy : proxyList) { 
   System.out.println(proxy); 
   SocketAddress address = proxy.address(); 
   if (address instanceof InetSocketAddress) { 
     String host = ((InetSocketAddress) address).getHostName(); 
     String port = Integer.toString(((InetSocketAddress) address).getPort()); 
     System.setProperty("http.proxyHost", host); 
     System.setProperty("http.proxyPort", port); 
   } 
 } 
}
Herc answered 26/9, 2012 at 15:1 Comment(8)
The code isn't working for me :( I get NullPointerException in line List<Proxy> proxyList = proxySelector.select(home); proxySelector is null and if you look at getProxySelector() body, you'll see that it always returns null.Caceres
same for me, getProxySelector() returns NULL (but only on my Windows, on my Linux the same code works!).Standee
The Proxy-Vole project has been dormant since 2013, but there is some activity in a fork at GitHub: github.com/MarkusBernhardt/proxy-voleThink
@Standee do you found solution for this problem, because i add this lib and get same problem getProxySelector() returns NULL, please help because i`m stuck.Brisance
@Caceres do you found solution for this problem, because i add this lib and get same problem getProxySelector() returns NULL, please help because i`m stuck.Brisance
@Herc Why do we set env System.setProperty("http.proxyHost", host); because ProxySelector.setDefault(proxySelector); with this it work.Grapnel
@Grapnel good question, I do not remember to be hones as this is almost 9 years ago that I have written it. But you are right, ProxySelector.setDefault(proxySelector); should be enough. The remaining lines however give you an idea how to access the results from the proxy selection process.Herc
The simplest solution happens to be to let JVM pick up the system proxies on program startup via -Djava.net.useSystemProxies=true as described in docs.oracle.com/javase/7/docs/api/java/net/doc-files/…Meld
C
9

Yes, from version 9 automatic proxy configurations (PAC/WPAD) will be read from the operating system.

Conjoint answered 11/9, 2019 at 14:53 Comment(0)
T
5

You can use Proxy Vole to solve this issue:

If you know exactly which PAC-file you want to use, you can do:

UrlPacScriptSource source = new UrlPacScriptSource("http://www.example.org/proxy.pac");
PacProxySelector selector = new PacProxySelector(source);

ProxySelector.setDefault(selector);

The advantage of this is that it is not user-related. For example if running this as a Windows service, you may end up running it on the SYSTEM-user which may not have the same OS_DEFAULT proxy settings (if any) as the Administrator-user.

The approach using system/software values is:

ProxySearch proxySearch = new ProxySearch();
proxySearch.addStrategy(Strategy.OS_DEFAULT);
proxySearch.addStrategy(Strategy.BROWSER);
proxySearch.addStrategy(Strategy.JAVA);
ProxySelector proxySelector = proxySearch.getProxySelector();

ProxySelector.setDefault(proxySelector); 

This starts with OS_DEFAULT, then JAVA and lastly BROWSER as strategies for the proxy selector.

This code is based on the GitHub code, release version 1.0.3.

Think answered 11/12, 2017 at 13:14 Comment(0)
P
4

I could load Proxy Auto-Config (PAC) file on Java. Please see below codes and package. I hope this would what you were looking for:

import com.sun.deploy.net.proxy.*;
.
.
BrowserProxyInfo b = new BrowserProxyInfo();        
b.setType(ProxyType.AUTO);
b.setAutoConfigURL("http://yourhost/proxy.file.pac");       
DummyAutoProxyHandler handler = new DummyAutoProxyHandler();
handler.init(b);

URL url = new URL("http://host_to_query");
ProxyInfo[] ps = handler.getProxyInfo(url);     
for(ProxyInfo p : ps){
    System.out.println(p.toString());
}

You already have a [com.sun.deploy.net.proxy] package on your machine! Find [deploy.jar] ;D

Presidio answered 8/6, 2012 at 15:22 Comment(1)
What is DummyAutoProxyHandler?Nalor

© 2022 - 2024 — McMap. All rights reserved.