Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't proxyHost/proxyPort work when running my Java application?

Tags:

java

fiddler

I have a java app that talks to some REST services, and I want to look at the HTTP traffic using Fiddler.

Fiddler acts as a proxy on localhost:8888, so the following Java VM options are supposed to configure java to use this proxy:

-Dhttp.proxyHost=localhost -Dhttp.proxyPort=8888

However, if I pass these parameters when running the java app that I want to debug, I see no traffic in Fiddler.

I wrote a test Java app that simply performs an HTTP GET using HttpURLConnection.

I can view the HTTP traffic from this app in fiddler, if I specify the above-mentioned command-line parameters when debugging it from Eclipse.

What are the reasons that http.proxyHost/Port might not work for all java HTTP operations?

like image 429
mackenir Avatar asked Jul 21 '11 17:07

mackenir


2 Answers

You can tell HttpClient to honor the JDK system arguments using the below code (HttpClient 4.x).

public static final DefaultHttpClient HTTP = new DefaultHttpClient();
ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(HTTP.getConnectionManager().getSchemeRegistry(),
ProxySelector.getDefault());
HTTP.setRoutePlanner(routePlanner);
like image 76
Aravind Yarram Avatar answered Sep 28 '22 06:09

Aravind Yarram


As mentioned above you need to do something like this:

 CloseableHttpClient httpClient = HttpClients.custom()
   .setRoutePlanner(new SystemDefaultRoutePlanner(ProxySelector.getDefault())

But that will not be enough.

In TL;DR fashion - you also need all three of these system properties:

-Dhttp.proxyHost=localhost -Dhttp.proxyPort=8888 -Dhttp.nonProxyHosts=

The long answer can be found here:

As mentioned by Gerard Davison at the link above:

It can be very convenient when developing to server based application to run them using "localhost" in order to maintain consistency between developer machines. This is normally a good idea but there is a small case where this can cause problems.

Consider if you are running a local http proxy on your machine in order to capture your HTTP traffic. (Cough perhaps even the one in JDeveloper I work on). Then you might run into Java bug 6737819. Basically by default JDK 1.6 was hard coded not to send any request to localhost via a proxy which of course was a bit of a pain. Luckily a workaround was put in where you could put the string "~localhost" in your nonProxyHosts entry to turn of this feature:

java -client -classpath classes 
-Dhttp.proxyHost=localhost 
-Dhttp.proxyPort=8099 -Dhttp.nonProxyHosts=~localhost 
-Dhttps.proxyHost=localhost 
-Dhttps.proxyPort=8099 client.Example 

Now moving forward to JDK 1.7 this workaround no longer works; but you need to take care to define nonProxyHosts as an empty string:

java -client -classpath classes 
-Dhttp.proxyHost=localhost 
-Dhttp.proxyPort=8099 
-Dhttp.nonProxyHosts= 
-Dhttps.proxyHost=localhost 
-Dhttps.proxyPort=8099 client.Example  

If you define this any anything other than an empty string the DefaultProxySelector though beware because internally it will append / or use the http.nonProxyHosts value from ../jre/lib/net.properties".

Just a minor complication that is not obvious from the published API.

like image 39
Ted Gulesserian Avatar answered Sep 28 '22 08:09

Ted Gulesserian