Como faço para definir o proxy a ser usado pela JVM

Muitas vezes, um aplicativo Java precisa se conectar à Internet. O exemplo mais comum ocorre quando ele está lendo um arquivo XML e precisa baixar seu esquema.

Estou por trás de um servidor proxy. Como faço para definir minha JVM para usar o proxy?

   

Da documentação do Java ( não da API do javadoc):

http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html

Configure os sinalizadores de JVM http.proxyHost e http.proxyPort ao iniciar sua JVM na linha de comandos. Isso geralmente é feito em um script de shell (no Unix) ou em um arquivo bat (no Windows). Aqui está o exemplo com o script de shell Unix:

 JAVA_FLAGS=-Dhttp.proxyHost=10.0.0.100 -Dhttp.proxyPort=8800 java ${JAVA_FLAGS} ... 

Ao usar contêineres como o JBoss ou o WebLogic, minha solução é editar os scripts de boot fornecidos pelo fornecedor.

Muitos desenvolvedores estão familiarizados com a API Java (javadocs), mas muitas vezes o restante da documentação é ignorado. Ele contém muitas informações interessantes: http://download.oracle.com/javase/6/docs/technotes/guides/


Atualização: Se você não quiser usar o proxy para resolver alguns hosts locais / de intranet, confira o comentário de @Tomalak:

Também não esqueça da propriedade http.nonProxyHosts!

 -Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com‌​|etc" 

Para usar a configuração de proxy do sistema:

 java -Djava.net.useSystemProxies=true ... 

Ou programaticamente:

 System.setProperty("java.net.useSystemProxies", "true"); 

Fonte: http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html

Para definir um proxy HTTP / HTTPS e / ou SOCKS programaticamente:

 ... public void setProxy() { if (isUseHTTPProxy()) { // HTTP/HTTPS Proxy System.setProperty("http.proxyHost", getHTTPHost()); System.setProperty("http.proxyPort", getHTTPPort()); System.setProperty("https.proxyHost", getHTTPHost()); System.setProperty("https.proxyPort", getHTTPPort()); if (isUseHTTPAuth()) { String encoded = new String(Base64.encodeBase64((getHTTPUsername() + ":" + getHTTPPassword()).getBytes())); con.setRequestProperty("Proxy-Authorization", "Basic " + encoded); Authenticator.setDefault(new ProxyAuth(getHTTPUsername(), getHTTPPassword())); } } if (isUseSOCKSProxy()) { // SOCKS Proxy System.setProperty("socksProxyHost", getSOCKSHost()); System.setProperty("socksProxyPort", getSOCKSPort()); if (isUseSOCKSAuth()) { System.setProperty("java.net.socks.username", getSOCKSUsername()); System.setProperty("java.net.socks.password", getSOCKSPassword()); Authenticator.setDefault(new ProxyAuth(getSOCKSUsername(), getSOCKSPassword())); } } } ... public class ProxyAuth extends Authenticator { private PasswordAuthentication auth; private ProxyAuth(String user, String password) { auth = new PasswordAuthentication(user, password == null ? new char[]{} : password.toCharArray()); } protected PasswordAuthentication getPasswordAuthentication() { return auth; } } ... 

Lembre-se de que os proxies HTTP e os proxies SOCKS operam em diferentes níveis na pilha de rede, para que você possa usar um ou o outro ou ambos.

Você pode definir esses sinalizadores programaticamente dessa maneira:

 if (needsProxy()) { System.setProperty("http.proxyHost",getProxyHost()); System.setProperty("http.proxyPort",getProxyPort()); } else { System.setProperty("http.proxyHost",""); System.setProperty("http.proxyPort",""); } 

Apenas retorne os valores corretos dos methods needsProxy() , getProxyHost() e getProxyPort() e você poderá chamar este snippet de código sempre que desejar.

A JVM usa o proxy para fazer chamadas HTTP

 System.getProperties().put("http.proxyHost", "someProxyURL"); System.getProperties().put("http.proxyPort", "someProxyPort"); 

Isso pode usar o proxy de configuração do usuário

 System.setProperty("java.net.useSystemProxies", "true"); 

Você pode definir algumas propriedades sobre o servidor proxy como parâmetros jvm

-Dhttp.proxyPort = 8080, proxyHost, etc.

mas se você precisar passar por um proxy de autenticação, você precisa de um autenticador como este exemplo:

ProxyAuthenticator.java

 import java.net.*; import java.io.*; public class ProxyAuthenticator extends Authenticator { private String userName, password; protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName, password.toCharArray()); } public ProxyAuthenticator(String userName, String password) { this.userName = userName; this.password = password; } } 

Example.java

  import java.net.Authenticator; import ProxyAuthenticator; public class Example { public static void main(String[] args) { String username = System.getProperty("proxy.authentication.username"); String password = System.getProperty("proxy.authentication.password"); if (username != null && !username.equals("")) { Authenticator.setDefault(new ProxyAuthenticator(username, password)); } // here your JVM will be authenticated } } 

Com base nesta resposta: http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E

lendo um arquivo XML e precisa baixar seu esquema

Se você estiver contando com a recuperação de esquemas ou DTDs pela Internet, estará criando um aplicativo lento, tagarela e frágil. O que acontece quando esse servidor remoto que hospeda o arquivo recebe tempo de inatividade planejado ou não planejado? Seu aplicativo quebra. Tudo bem?

Veja http://xml.apache.org/commons/components/resolver/resolver-article.html#s.catalog.files

As URLs de esquemas e semelhantes são melhor consideradas como identificadores exclusivos. Não como solicitações para acessar o arquivo remotamente. Faça alguma pesquisa no Google sobre “catálogo XML”. Um catálogo XML permite que você hospede tais resources localmente, resolvendo a lentidão, a chatice e a fragilidade.

É basicamente uma cópia permanentemente em cache do conteúdo remoto. E tudo bem, já que o conteúdo remoto nunca mudará. Se houver uma atualização, ela estará em um URL diferente. Fazendo a recuperação real do recurso através da internet, especialmente bobo.

Defina a propriedade java.net.useSystemProxies como true . Você pode configurá-lo, por exemplo, através da variável ambiental JAVA_TOOL_OPTIONS . No Ubuntu, você pode, por exemplo, adicionar a seguinte linha ao .bashrc :

exportar JAVA_TOOL_OPTIONS + = “-Djava.net.useSystemProxies = true”

Eu também estou atrás do firewall, isso funcionou para mim !!

 System.setProperty("http.proxyHost", "proxy host addr"); System.setProperty("http.proxyPort", "808"); Authenticator.setDefault(new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("domain\\user","password".toCharArray()); } }); URL url = new URL("http://www.google.com/"); URLConnection con = url.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader( con.getInputStream())); // Read it ... String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close(); 

Combinando as respostas de Sorter e javabrett / Leonel:

 java -Dhttp.proxyHost=10.10.10.10 -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -jar myJar.jar 

Adicione isto antes de se conectar a um URL por trás de um proxy.

 System.getProperties().put("http.proxyHost", "someProxyURL"); System.getProperties().put("http.proxyPort", "someProxyPort"); System.getProperties().put("http.proxyUser", "someUserName"); System.getProperties().put("http.proxyPassword", "somePassword"); 

O seguinte mostra como definir em Java um proxy com o usuário proxy e a senha proxy da linha de comando, o que é um caso muito comum. Você não deve salvar senhas e hosts no código, como regra, em primeiro lugar.

Passar as propriedades do sistema na linha de comando com -D e defini-las no código com System.setProperty (“name”, “value”) é equivalente.

Mas note isso

Exemplo que funciona:

 C:\temp>java -Dhttps.proxyHost=host -Dhttps.proxyPort=port -Dhttps=proxyUser=user -Dhttps.proxyPassword="password" -Djavax.net.ssl.trustStore=c:/cacerts -Djavax.net.ssl.trustStorePassword=changeit com.andreas.JavaNetHttpConnection 

Mas o seguinte não funciona

 C:\temp>java com.andreas.JavaNetHttpConnection -Dhttps.proxyHost=host -Dhttps.proxyPort=port -Dhttps=proxyUser=user -Dhttps.proxyPassword="password" -Djavax.net.ssl.trustStore=c:/cacerts -Djavax.net.ssl.trustStorePassword=changeit 

A única diferença é a posição das propriedades do sistema! (antes e depois da aula)

Se você tem caracteres especiais em senha, você tem permissão para colocar entre aspas “@ MyPass123%”, como no exemplo acima.

Se você acessar um serviço HTTPS, precisará usar https.proxyHost, https.proxyPort etc.

Se você acessar um serviço HTTP, precisará usar http.proxyHost, http.proxyPort etc.

Esta é uma atualização secundária, mas, desde o Java 7, as conexões de proxy agora podem ser criadas de maneira programática, em vez de usar as propriedades do sistema. Isso pode ser útil se:

  1. Proxy precisa ser rotacionado dinamicamente durante o tempo de execução do programa
  2. Vários proxies paralelos precisam ser usados
  3. Ou apenas faça seu código mais limpo 🙂

Aqui está um exemplo artificial em groovy:

 // proxy configuration read from file resource under "proxyFileName" String proxyFileName = "proxy.txt" String proxyPort = "1234" String url = "http://www.promised.land" File testProxyFile = new File(proxyFileName) URLConnection connection if (!testProxyFile.exists()) { logger.debug "proxyFileName doesn't exist. Bypassing connection via proxy." connection = url.toURL().openConnection() } else { String proxyAddress = testProxyFile.text connection = url.toURL().openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, proxyPort))) } try { connection.connect() } catch (Exception e) { logger.error e.printStackTrace() } 

Referência completa: http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html

Recentemente, descobri a maneira de permitir que a JVM use as configurações de proxy do navegador. O que você precisa fazer é adicionar ${java.home}/lib/deploy.jar ao seu projeto e ${java.home}/lib/deploy.jar a biblioteca da seguinte forma:

 import com.sun.deploy.net.proxy.DeployProxySelector; import com.sun.deploy.services.PlatformType; import com.sun.deploy.services.ServiceManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public abstract class ExtendedProxyManager { private static final Log logger = LogFactory.getLog(ExtendedProxyManager.class); /** * After calling this method, proxy settings can be magically retrieved from default browser settings. */ public static boolean init() { logger.debug("Init started"); // Initialization code was taken from com.sun.deploy.ClientContainer: ServiceManager .setService(System.getProperty("os.name").toLowerCase().indexOf("windows") != -1 ? PlatformType.STANDALONE_TIGER_WIN32 : PlatformType.STANDALONE_TIGER_UNIX); try { // This will call ProxySelector.setDefault(): DeployProxySelector.reset(); } catch (Throwable throwable) { logger.error("Unable to initialize extended dynamic browser proxy settings support.", throwable); return false; } return true; } } 

Posteriormente, as configurações de proxy estarão disponíveis para a API Java via java.net.ProxySelector .

O único problema com essa abordagem é que você precisa iniciar a JVM com deploy.jar no bootclasspath, por exemplo, java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar . Se alguém souber como superar essa limitação, me avise.

Isso funciona para mim:

 public void setHttpProxy(boolean isNeedProxy) { if (isNeedProxy) { System.setProperty("http.proxyHost", getProxyHost()); System.setProperty("http.proxyPort", getProxyPort()); } else { System.clearProperty("http.proxyHost"); System.clearProperty("http.proxyPort"); } } 

P / S: baseio-me na resposta de GHad.

Como é apontado em outras respostas, se você precisar usar proxies autenticados, não há uma maneira confiável de fazer isso usando apenas variables ​​de linha de comando – o que é irritante se você estiver usando o aplicativo de outra pessoa e não quiser mexer com o Código fonte.

Iverson fará a sugestão útil sobre como usar o HttpProxy para se conectar a um host com autenticação preemtiva para usar uma ferramenta de gerenciamento de proxy, como o Proxifier ( http://www.proxifier.com/ para Mac OS X e Windows) para lidar com isso.

Por exemplo, com o Proxifier, você pode configurá-lo para interceptar apenas comandos Java para serem gerenciados e redirecionados através de seu proxy (autenticado). Você vai querer definir os valores proxyHost e proxyPort para em branco neste caso, por exemplo, passar em -Dhttp.proxyHost= -Dhttp.proxyPort= para seus comandos java.

Se você quiser “Socks Proxy”, informe os argumentos da VM “socksProxyHost” e “socksProxyPort”.

por exemplo

 java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main 

Além disso, se você estiver sempre procurando fazer o download do mesmo esquema, poderá adicionar o esquema ao seu classpath (sistema de arquivos ou JAR) e, em seguida, usar um EntityResolver personalizado.

Veja aqui uma discussão mais completa dessa abordagem.

Editar: Veja @ me.yahoo.com / a / 0QMxE da discussão do CatalogResolver, que usa a abordagem EntityResolver:

 CatalogResolver cr = new CatalogResolver(); ... yourParser.setEntityResolver(cr) 

É possível utilizar as variables ​​http.proxy * JVM se você estiver em uma JVM independente, mas NÃO DEVERÁ modificar seus scripts de boot e / ou fazer isso dentro de seu servidor de aplicativos (exceto talvez jboss ou tomcat). Em vez disso, você deve utilizar a API Proxy JAVA (não System.setProperty) ou utilizar as próprias opções de configuração do fornecedor. O WebSphere e o WebLogic têm maneiras muito definidas de configurar os proxies que são muito mais poderosos que o do J2SE. Além disso, para o WebSphere e o WebLogic, você provavelmente quebrará seu servidor de aplicativos de pequenas maneiras, sobrescrevendo os scripts de boot (particularmente os processos de interoperabilidade do servidor, como você pode estar dizendo a eles para usar seu proxy também …).

Acho que configurar o WINHTTP também funcionará.

Muitos programas, incluindo atualizações do Windows, estão tendo problemas por trás do proxy. A configuração do WINHTTP sempre corrigirá esse tipo de problema